From 404df850f5e8b1db84981b97d888b4285082dd46 Mon Sep 17 00:00:00 2001 From: Pavel Shevaev Date: Mon, 29 Aug 2022 16:06:59 +0300 Subject: [PATCH] A bit polishing code --- chirp.inc.php | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++ chirp.php | 269 +-------------------------------------- 2 files changed, 346 insertions(+), 263 deletions(-) create mode 100644 chirp.inc.php diff --git a/chirp.inc.php b/chirp.inc.php new file mode 100644 index 0000000..77c56b2 --- /dev/null +++ b/chirp.inc.php @@ -0,0 +1,340 @@ + $token_field))); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $pass); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + $json = curl_exec($ch); + curl_close($ch); + + $res = json_decode($json, true); + if(!isset($res['sha1'])) + throw new Exception("Could not login to gitea"); + + return $res['sha1']; +} + +function gitea_api_call($auth_token, $gitea_url, $api_path) +{ + $api_url = "$gitea_url/api/v1/$api_path"; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $api_url); + curl_setopt($ch, CURLOPT_HEADER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, + array( + 'Accept: application/json', + "Authorization: token $auth_token" + ) + ); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + $response = curl_exec($ch); + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $header = substr($response, 0, $header_size); + $json = substr($response, $header_size); + + $info = curl_getinfo($ch); + + curl_close($ch); + + if($info['http_code'] != 200) + return $info['http_code']; + + return json_decode($json, true); +} + +function gitea_get_tags($auth_token, $gitea_url, $repo) +{ + $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/tags"); + if($res === 404) + return array(); + else if(is_numeric($res)) + throw new Exception("Bad response: $res"); + return $res; +} + +function gitea_get_source($auth_token, $gitea_url, $repo, $path) +{ + $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/contents/$path"); + + if(is_numeric($res)) + throw new Exception("Bad response: $res"); + + if(!isset($res['content'])) + throw new Exception("Could not get file at path '$path'"); + + return base64_decode($res['content']); +} + +function gitea_get_forks($auth_token, $gitea_url, $repo) +{ + $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/forks"); + if(is_numeric($res)) + throw new Exception("Bad response: $res"); + return $res; +} + +function gitea_get_commits($auth_token, $gitea_url, $repo) +{ + $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/commits"); + if(is_numeric($res)) + throw new Exception("Bad response: $res"); + return $res; +} + +function gitea_get_commit($auth_token, $gitea_url, $repo, $sha) +{ + $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/git/commits/$sha"); + if($res === 404) + return null; + else if(is_numeric($res)) + throw new Exception("Bad response: $res"); + else + return $res; +} + +function github_get_tags($github_repo) +{ + $api_url = "https://api.github.com/repos/$github_repo/tags"; + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $api_url); + curl_setopt($ch, CURLOPT_HEADER, true); + curl_setopt($ch, CURLOPT_USERAGENT, "test"); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + $response = curl_exec($ch); + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $header = substr($response, 0, $header_size); + $json = substr($response, $header_size); + + $info = curl_getinfo($ch); + + curl_close($ch); + + if($info['http_code'] != 200) + return $info['http_code']; + + return json_decode($json, true); +} + +function _is_composer_git_repo(array $repos, $repo) +{ + foreach($repos as $item) + { + if($item['type'] == 'git' && $item['url'] == $repo) + return true; + } + return false; +} + +function _is_composer_github_package(array $repos, $repo, &$github_repo) +{ + foreach($repos as $item) + { + if($item['type'] == 'package' && + $item['package']['name'] == $repo && + preg_match('~https?://github.com/([^/]+)/([^/]+)~', $item['package']['dist']['url'], $matches)) + { + $github_repo = $matches[1].'/'.$matches[2]; + return true; + } + } + return false; +} + + +interface IReporter +{ + public function write($msg); + public function flush(); +} + +class CliReporter implements IReporter +{ + public function write($msg) + { + echo $msg; + } + + public function flush() + { + } +} + +class SlackReporter implements IReporter +{ + private $buffer = ''; + + public function write($msg) + { + $this->buffer .= $msg; + } + + public function flush() + { + slack_post($this->buffer); + } +} + +class Reporters implements IReporter +{ + private $all = array(); + + public function add(IReporter $r) + { + $this->all[] = $r; + } + + public function write($msg) + { + foreach($this->all as $r) + $r->write($msg); + } + + public function flush() + { + foreach($this->all as $r) + $r->flush(); + } +} + +function gitea_check_repo( + $auth_token, + $gitea_url, + $base_repo, + array $opts + ) +{ + $r = new Reporters(); + $r->add(new SlackReporter()); + $r->add(new CliReporter()); + + $r->write("************************* Chirping about repo '$base_repo' *************************\n"); + + $commits = gitea_get_commits($auth_token, $gitea_url, $base_repo); + + if($opts['check_forks']) + { + $forks = gitea_get_forks($auth_token, $gitea_url, $base_repo); + $behind_forks = array(); + $r->write("== Checking forks ==\n"); + foreach($forks as $fork) + { + $repo_fork = $fork['full_name']; + foreach($commits as $commit) + { + $status = gitea_get_commit($auth_token, $gitea_url, $repo_fork, $commit['sha']); + if($status === null) + { + $behind_forks[] = $repo_fork; + break; + } + //early exit if commit exists + else if(isset($status['sha'])) + { + break; + } + } + } + $r->write("Behind forks: " . implode(", ", $behind_forks) . "\n"); + } + + if($opts['check_composer']) + { + $r->write("== Checking Composer manifest ==\n"); + $composer_json = gitea_get_source($auth_token, $gitea_url, $base_repo, "composer/composer.json"); + $composer_arr = json_decode($composer_json, true); + + foreach($composer_arr['require'] as $repo => $version) + { + if(strpos($repo, "bit/") !== 0) + continue; + + if(_is_composer_git_repo($composer_arr['repositories'], "$gitea_url/$repo")) + { + $tags = gitea_get_tags($auth_token, $gitea_url, $repo); + if(isset($tags[0])) + { + $last_tag_info = $tags[0]; + if(ltrim($last_tag_info["name"], 'v') != ltrim($version, 'v')) + $r->write("Package '$repo': current $version, latest {$last_tag_info["name"]}\n"); + } + else + $r->write("Could not fetch tags for $repo\n"); + } + else if(_is_composer_github_package($composer_arr['repositories'], $repo, $github_repo)) + { + $tags = github_get_tags($github_repo); + if(isset($tags[0])) + { + $last_tag_info = $tags[0]; + if(ltrim($last_tag_info["name"], 'v') != ltrim($version, 'v')) + $r->write("Package '$repo': current $version, latest {$last_tag_info["name"]}\n"); + } + } + } + } + + if($opts['check_upm']) + { + $r->write("== Checking UPM manifest ==\n"); + $upm_json = gitea_get_source($auth_token, $gitea_url, $base_repo, "unity/Packages/manifest.json"); + $upm_arr = json_decode($upm_json, true); + + foreach($upm_arr['dependencies'] as $name => $version) + { + if(strpos($name, "com.bitgames.") !== 0) + continue; + + $name = str_replace("com.bitgames.ecs", "com.bitgames.leoecs", $name); + $name = str_replace("com.bitgames.", "", $name); + $name = str_replace(".", "-", $name); + $repo = 'bit-upm/' . $name; + + $tags = gitea_get_tags($auth_token, $gitea_url, $repo); + if(isset($tags[0])) + { + $last_tag_info = $tags[0]; + if(ltrim($last_tag_info["name"], 'v') != ltrim($version, 'v')) + $r->write("Package '$repo': current $version, latest {$last_tag_info["name"]}\n"); + } + else + $r->write("Could not fetch tags for $repo\n"); + } + } + $r->flush(); +} + +function slack_post($message, $fields = array()) +{ + $ch = curl_init("https://slack.com/api/chat.postMessage"); + $fields["token"] = 'xoxb-141599046048-4017237103457-fsUiANhvIcuScMRkrTB7obEU'; + $fields["channel"] = "#tech"; + $fields["text"] = $message; + + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + + $result = curl_exec($ch); + curl_close($ch); + + return json_decode($result, true); +} + diff --git a/chirp.php b/chirp.php index 18df6ca..0773ae6 100644 --- a/chirp.php +++ b/chirp.php @@ -1,298 +1,41 @@ true, 'check_composer' => true, 'check_upm' => false ) ); -gitea_check_repo($auth_token, $gitea_url, 'bit/skeletor', +hoopoe\gitea_check_repo($auth_token, $gitea_url, 'bit/skeletor', array( 'check_forks' => true, 'check_composer' => true, 'check_upm' => true ) ); -gitea_check_repo($auth_token, $gitea_url, 'bit/skeletor-rnd', +hoopoe\gitea_check_repo($auth_token, $gitea_url, 'bit/skeletor-rnd', array( 'check_forks' => true, 'check_composer' => true, 'check_upm' => true ) ); -gitea_check_repo($auth_token, $gitea_url, 'game/gymmania', +hoopoe\gitea_check_repo($auth_token, $gitea_url, 'game/gymmania', array( 'check_forks' => false, 'check_composer' => true, 'check_upm' => false ) ); -////////////////////////////////// -function gitea_login($gitea_url, $user, $pass) -{ - $token_field = "test_".time(); - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, "https://git.bit5.ru/api/v1/users/$user/tokens"); - curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(array("name" => $token_field))); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); - curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $pass); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - $json = curl_exec($ch); - curl_close($ch); - - $res = json_decode($json, true); - if(!isset($res['sha1'])) - throw new Exception("Could not login to gitea"); - - return $res['sha1']; -} - -function gitea_api_call($auth_token, $gitea_url, $api_path) -{ - $api_url = "$gitea_url/api/v1/$api_path"; - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $api_url); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_HTTPHEADER, - array( - 'Accept: application/json', - "Authorization: token $auth_token" - ) - ); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - $response = curl_exec($ch); - - $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $header = substr($response, 0, $header_size); - $json = substr($response, $header_size); - - $info = curl_getinfo($ch); - - curl_close($ch); - - if($info['http_code'] != 200) - return $info['http_code']; - - return json_decode($json, true); -} - -function gitea_get_tags($auth_token, $gitea_url, $repo) -{ - $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/tags"); - if($res === 404) - return array(); - else if(is_numeric($res)) - throw new Exception("Bad response: $res"); - return $res; -} - -function gitea_get_source($auth_token, $gitea_url, $repo, $path) -{ - $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/contents/$path"); - - if(is_numeric($res)) - throw new Exception("Bad response: $res"); - - if(!isset($res['content'])) - throw new Exception("Could not get file at path '$path'"); - - return base64_decode($res['content']); -} - -function gitea_get_forks($auth_token, $gitea_url, $repo) -{ - $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/forks"); - if(is_numeric($res)) - throw new Exception("Bad response: $res"); - return $res; -} - -function gitea_get_commits($auth_token, $gitea_url, $repo) -{ - $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/commits"); - if(is_numeric($res)) - throw new Exception("Bad response: $res"); - return $res; -} - -function gitea_get_commit($auth_token, $gitea_url, $repo, $sha) -{ - $res = gitea_api_call($auth_token, $gitea_url, "repos/$repo/git/commits/$sha"); - if($res === 404) - return null; - else if(is_numeric($res)) - throw new Exception("Bad response: $res"); - else - return $res; -} - -function github_get_tags($github_repo) -{ - $api_url = "https://api.github.com/repos/$github_repo/tags"; - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $api_url); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_USERAGENT, "test"); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - $response = curl_exec($ch); - - $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); - $header = substr($response, 0, $header_size); - $json = substr($response, $header_size); - - $info = curl_getinfo($ch); - - curl_close($ch); - - if($info['http_code'] != 200) - return $info['http_code']; - - return json_decode($json, true); -} - -function _is_composer_git_repo(array $repos, $repo) -{ - foreach($repos as $item) - { - if($item['type'] == 'git' && $item['url'] == $repo) - return true; - } - return false; -} - -function _is_composer_github_package(array $repos, $repo, &$github_repo) -{ - foreach($repos as $item) - { - if($item['type'] == 'package' && - $item['package']['name'] == $repo && - preg_match('~https?://github.com/([^/]+)/([^/]+)~', $item['package']['dist']['url'], $matches)) - { - $github_repo = $matches[1].'/'.$matches[2]; - return true; - } - } - return false; -} - - -function gitea_check_repo( - $auth_token, - $gitea_url, - $base_repo, - array $opts - ) -{ - echo "************************* Checking repo '$base_repo' *************************\n"; - - $commits = gitea_get_commits($auth_token, $gitea_url, $base_repo); - - if($opts['check_forks']) - { - $forks = gitea_get_forks($auth_token, $gitea_url, $base_repo); - $behind_forks = array(); - echo "== Checking forks ==\n"; - foreach($forks as $fork) - { - $repo_fork = $fork['full_name']; - foreach($commits as $commit) - { - $status = gitea_get_commit($auth_token, $gitea_url, $repo_fork, $commit['sha']); - if($status === null) - { - $behind_forks[] = $repo_fork; - break; - } - //early exit if commit exists - else if(isset($status['sha'])) - { - break; - } - } - } - echo "Behind forks: " . implode(", ", $behind_forks) . "\n"; - } - - if($opts['check_composer']) - { - echo "== Checking Composer manifest ==\n"; - $composer_json = gitea_get_source($auth_token, $gitea_url, $base_repo, "composer/composer.json"); - $composer_arr = json_decode($composer_json, true); - - foreach($composer_arr['require'] as $repo => $version) - { - if(strpos($repo, "bit/") !== 0) - continue; - - if(_is_composer_git_repo($composer_arr['repositories'], "$gitea_url/$repo")) - { - $tags = gitea_get_tags($auth_token, $gitea_url, $repo); - if(isset($tags[0])) - { - $last_tag_info = $tags[0]; - if(ltrim($last_tag_info["name"], 'v') != ltrim($version, 'v')) - echo "Package '$repo': current $version, latest {$last_tag_info["name"]}\n"; - } - else - echo "Could not fetch tags for $repo\n"; - } - else if(_is_composer_github_package($composer_arr['repositories'], $repo, $github_repo)) - { - $tags = github_get_tags($github_repo); - if(isset($tags[0])) - { - $last_tag_info = $tags[0]; - if(ltrim($last_tag_info["name"], 'v') != ltrim($version, 'v')) - echo "Package '$repo': current $version, latest {$last_tag_info["name"]}\n"; - } - } - } - } - - if($opts['check_upm']) - { - echo "== Checking UPM manifest ==\n"; - $upm_json = gitea_get_source($auth_token, $gitea_url, $base_repo, "unity/Packages/manifest.json"); - $upm_arr = json_decode($upm_json, true); - - foreach($upm_arr['dependencies'] as $name => $version) - { - if(strpos($name, "com.bitgames.") !== 0) - continue; - - $name = str_replace("com.bitgames.ecs", "com.bitgames.leoecs", $name); - $name = str_replace("com.bitgames.", "", $name); - $name = str_replace(".", "-", $name); - $repo = 'bit-upm/' . $name; - - $tags = gitea_get_tags($auth_token, $gitea_url, $repo); - if(isset($tags[0])) - { - $last_tag_info = $tags[0]; - if(ltrim($last_tag_info["name"], 'v') != ltrim($version, 'v')) - echo "Package '$repo': current $version, latest {$last_tag_info["name"]}\n"; - } - else - echo "Could not fetch tags for $repo\n"; - } - } -}