From eeaf1c1dbf515237fd9371972a4f76b63bc1d9a4 Mon Sep 17 00:00:00 2001 From: mappu Date: Mon, 4 May 2020 18:05:36 +1200 Subject: [PATCH] codesite2git: add gitea create+push support --- codesite2git | 126 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 6 deletions(-) diff --git a/codesite2git b/codesite2git index dca7851..ba4ec49 100755 --- a/codesite2git +++ b/codesite2git @@ -137,12 +137,106 @@ mtime=".$this->lastupdate." } -function codesite2git(string $projdirname, string $projname, string $dest) { +class Gitea { + protected $url; + protected $org; + protected $token; + + public function __construct(string $url, string $org, string $token) { + $this->url = $url; + $this->org = $org; + $this->token = $token; + } + + public function repoExists(string $repo): bool { + + $resp = @file_get_contents($this->url.'api/v1/repos/'.$this->org.'/'.$repo); + if ($resp === false) { + return false; // not conclusive but it will suffice + } + if (strpos($resp, 'does not exist')) { + return false; + } + + $inf = json_decode($resp, true); + if (is_array($inf) && $inf['name'] == $repo) { + return true; // definitely yes + } + + throw new \Exception("Couldn't decide whether repo {$repo} exists\n\n".var_export($resp, true)); + } + + public function createRepo(string $repo) { + $command = ('curl -sS -X POST ' . + escapeshellarg($this->url.'api/v1/admin/users/'.$this->org.'/repos?access_token='.urlencode($this->token)) . ' '. + '-H "accept: application/json" -H "Content-Type: application/json" -d ' . escapeshellarg(json_encode(['name' => $repo])) + ); + + $code = 0; + $output = []; + exec($command, $output, $code); + if ($code == 0) { + return; // success + } + + throw new \Exception("failed to create repository {$repo} (exit code {$code})\n\n".var_export($output, true)); + } + + public function updateRepoProperties(string $repo, string $description) { + $json_update = [ + 'archived' => true, + 'description' => $description, + + // SPECIAL https://code.ivysaur.me/ - don't leave in commit {{{ + 'has_wiki' => false, + 'website' => 'https://code.ivysaur.me/'.$repo, + // }}} + ]; + + $command = ('curl -sS -X PATCH ' . + escapeshellarg($this->url.'api/v1/repos/'.$this->org.'/'.$repo.'?access_token='.urlencode($this->token)) . ' '. + '-H "accept: application/json" -H "Content-Type: application/json" -d ' . escapeshellarg(json_encode($json_update)) + ); + + $code = 0; + $output = []; + exec($command, $output, $code); + if ($code == 0) { + return; // success + } + + throw new \Exception("failed to update repository {$repo} properties: (exit code {$code})\n\n".var_export($output, true)); + } + + public function setRepoTopics(string $repo, array $topics) { + $command = ('curl -sS -X PUT ' . + escapeshellarg($this->url.'api/v1/repos/'.$this->org.'/'.$repo.'/topics?access_token='.urlencode($this->token)) . ' '. + '-H "accept: application/json" -H "Content-Type: application/json" -d ' . escapeshellarg(json_encode(['topics' => $topics])) + ); + + $code = 0; + $output = []; + exec($command, $output, $code); + if ($code == 0) { + return; // success + } + + throw new \Exception("failed to update repository {$repo} topics: (exit code {$code})\n\n".var_export($output, true)); + } + + public function gitRemoteUrlFor(string $repo): string { + return $this->url.$this->org.'/'.$repo.'.git'; + } +} + +function codesite2git(string $projdirname, string $projname, string $dest): CProjectGitExporter { // Parse existing project $c = new CProjectGitExporter($projdirname, $projname); // var_dump($c); $c->ExportAsGit($dest); + + return $c; } function usage() { @@ -178,22 +272,42 @@ function main(array $argv) { $repos = glob(BASEDIR.'data/*'); $temp_dir = $argv[3]; + $gitea = new Gitea($argv[4], $argv[5], $argv[6]); + + foreach($repos as $i => $path) { - foreach($repos as $path) { $projdir = basename($path); $reponame = explode('-', $projdir, 2)[1]; + echo sprintf("[%3d/%3d] Processing '%s'... ", $i+1, count($repos), $reponame); + // Convert to git - codesite2git($projdir, $reponame, $temp_dir.'/'.$projdir.'-archive.git'); + $git_repo_dir = $temp_dir.'/'.$projdir.'-archive.git'; + $c = codesite2git($projdir, $reponame, $git_repo_dir); + + // Check if Gitea repo already exists + if ($gitea->repoExists($reponame)) { + throw new \Exception("Abandoning process since repo {$reponame} already exists in Gitea - move it out of the source directory first"); + } // Create new Gitea repo - // TODO + $gitea->createRepo($reponame); + if (! $gitea->repoExists($reponame)) { + throw new \Exception("Created repo {$reponame} successfully but it doesn't seem to exist?"); + } // Add git remote and push - // TODO + shell_exec( + 'cd '.escapeshellarg($git_repo_dir) .' && '. + 'git remote add origin '.escapeshellarg($gitea->gitRemoteUrlFor($reponame)).' && '. + 'git push origin master' + ); // Set Gitea topics + description - // TODO + $gitea->updateRepoProperties($reponame, $c->shortdesc); + $gitea->setRepoTopics($reponame, $c->tags); + + echo " Done\n"; } } else {