From 36cfa28cf2dcee3422f0231f91c6692eb28e7824 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 13 May 2015 10:18:12 +0200 Subject: [PATCH] yet another github api refactoring --- app/Controller/Github.php | 18 +---- app/Controller/Github/Callback.php | 2 - app/Controller/Github/Hook/Receive.php | 21 +++--- app/Controller/Github/Index.php | 16 +---- app/Controller/Github/Repo.php | 69 ++----------------- app/Controller/Github/RepoHook.php | 4 +- app/Github/API.php | 16 +++++ app/Github/API/Call.php | 12 +++- app/Github/API/Callback.php | 16 +++++ app/Github/API/Hooks/CreateHook.php | 1 + app/Github/API/Hooks/HooksCallback.php | 20 ++++++ app/Github/API/Hooks/ListHooks.php | 3 +- app/Github/API/Hooks/UpdateHook.php | 1 + app/Github/API/Releases/CreateRelease.php | 1 + .../API/Releases/CreateReleaseAsset.php | 1 + app/Github/API/Releases/ListReleaseAssets.php | 3 +- app/Github/API/Releases/ListReleases.php | 3 +- app/Github/API/Repos/ContentsCallback.php | 31 +++++++++ app/Github/API/Repos/ListRepos.php | 3 +- app/Github/API/Repos/ReadContents.php | 3 +- app/Github/API/Repos/ReadRepo.php | 3 +- app/Github/API/Repos/ReleasesCallback.php | 28 ++++++++ app/Github/API/Repos/RepoCallback.php | 17 +++++ app/Github/API/Repos/ReposCallback.php | 15 ++++ app/Github/API/Tags/ListTags.php | 3 +- app/Github/API/Tags/TagsCallback.php | 25 +++++++ app/Github/API/Users/ReadAuthToken.php | 1 + app/Github/API/Users/ReadAuthUser.php | 3 +- app/views/github/repo.phtml | 2 +- 29 files changed, 224 insertions(+), 117 deletions(-) create mode 100644 app/Github/API/Callback.php create mode 100644 app/Github/API/Hooks/HooksCallback.php create mode 100644 app/Github/API/Repos/ContentsCallback.php create mode 100644 app/Github/API/Repos/ReleasesCallback.php create mode 100644 app/Github/API/Repos/RepoCallback.php create mode 100644 app/Github/API/Repos/ReposCallback.php create mode 100644 app/Github/API/Tags/TagsCallback.php diff --git a/app/Controller/Github.php b/app/Controller/Github.php index 364f0e5..164f320 100644 --- a/app/Controller/Github.php +++ b/app/Controller/Github.php @@ -35,7 +35,7 @@ abstract class Github implements Controller "location" => "github", "title" => "Github" ]); - $this->app->getView()->registerFunction("check", [$this, "checkRepoHook"]); + $this->app->getView()->registerFunction("check", [$github, "checkRepoHook"]); if (($header = $this->app->getRequest()->getHeader("Cache-Control", Header::class))) { $params = $header->getParams(); @@ -57,20 +57,4 @@ abstract class Github implements Controller ])); return false; } - - /** - * Check if the pharext webhook is set for the repo and return it - * @param object $repo - * @return int hook id - */ - function checkRepoHook($repo) { - if ($repo->hooks) { - foreach ($repo->hooks as $hook) { - if ($hook->name === "web" && $hook->config->url === $this->github->getConfig()->hook->url) { - return $hook; - } - } - } - return null; - } } diff --git a/app/Controller/Github/Callback.php b/app/Controller/Github/Callback.php index 1b7f34f..646d782 100644 --- a/app/Controller/Github/Callback.php +++ b/app/Controller/Github/Callback.php @@ -4,14 +4,12 @@ namespace app\Controller\Github; use app\Controller\Github; use app\Github\API; -use app\Github\Exception; use app\Model\Accounts; use app\Session; use app\Web; class Callback extends Github { - /** * @var Accounts */ diff --git a/app/Controller/Github/Hook/Receive.php b/app/Controller/Github/Hook/Receive.php index 62722ed..c53878c 100644 --- a/app/Controller/Github/Hook/Receive.php +++ b/app/Controller/Github/Hook/Receive.php @@ -8,7 +8,7 @@ use app\Model\Accounts; use app\Web; use http\Params; use pharext\Task; -use pharext\SourceDir\Git; +use pharext\SourceDir; require_once __DIR__."/../../../../vendor/m6w6/pharext/src/pharext/Version.php"; @@ -79,19 +79,22 @@ class Receive implements Controller private function uploadAssetForRelease($release, $repo) { $this->setTokenForUser($repo->owner->login); - $asset = $this->createReleaseAsset($release, $repo); - $name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name); - $url = uri_template($release->upload_url, compact("name")); - $this->github->createReleaseAsset($url, $asset, "application/phar", function($json) { - $response = $this->app->getResponse(); - $response->setResponseCode(201); - $response->setHeader("Location", $json->url); + $this->github->listHooks($repo->full_name, function($hooks) use($release, $repo) { + $repo->hooks = $hooks; + $asset = $this->createReleaseAsset($release, $repo); + $name = sprintf("%s-%s.ext.phar", $repo->name, $release->tag_name); + $url = uri_template($release->upload_url, compact("name")); + $this->github->createReleaseAsset($url, $asset, "application/phar", function($json) { + $response = $this->app->getResponse(); + $response->setResponseCode(201); + $response->setHeader("Location", $json->url); + }); })->send(); } private function createReleaseAsset($release, $repo) { $source = (new Task\GitClone($repo->clone_url, $release->tag_name))->run(); - $iterator = new Git($source); + $iterator = new SourceDir\Git($source); $meta = [ "header" => sprintf("pharext v%s (c) Michael Wallner ", \pharext\VERSION), "version" => \pharext\VERSION, diff --git a/app/Controller/Github/Index.php b/app/Controller/Github/Index.php index c0838b7..2b16c7b 100644 --- a/app/Controller/Github/Index.php +++ b/app/Controller/Github/Index.php @@ -8,21 +8,11 @@ class Index extends Github { function __invoke(array $args = null) { if ($this->checkToken()) { - $this->github->listRepos( + list($repos, $links) = $this->github->listRepos( $this->app->getRequest()->getQuery("page"), - [$this, "reposCallback"] + new \app\Github\API\Repos\ReposCallback($this->github) )->send(); - $this->app->display("github/index"); - } - } - - function reposCallback($repos, $links) { - $this->app->getView()->addData(compact("repos", "links")); - - foreach ($repos as $repo) { - $this->github->listHooks($repo->full_name, function($hooks) use($repo) { - $repo->hooks = $hooks; - }); + $this->app->display("github/index", compact("repos", "links")); } } } diff --git a/app/Controller/Github/Repo.php b/app/Controller/Github/Repo.php index ac2ce37..813b942 100644 --- a/app/Controller/Github/Repo.php +++ b/app/Controller/Github/Repo.php @@ -3,79 +3,24 @@ namespace app\Controller\Github; use app\Controller\Github; +use app\Github\API\Repos\RepoCallback; class Repo extends Github { function __invoke(array $args = null) { extract($args); - $this->app->getView()->addData(compact("owner", "name")); if ($this->checkToken()) { - $this->github->readRepo( - "$owner/$name", - [$this, "repoCallback"] - )->send(); + list($repo) = $this->github->readRepo("$owner/$name", new RepoCallback($this->github))->send(); + $hook = $this->github->checkRepoHook($repo); + + $this->app->getView()->addData(compact("owner", "name", "repo", "hook")); if (($modal = $this->app->getRequest()->getQuery("modal"))) { - $this->app->getView()->addData(compact("modal") + [ - "action" => $this->app->getRequest()->getQuery($modal) - ]); + $action = $this->app->getRequest()->getQuery($modal); + $this->app->getView()->addData(compact("modal", "action")); } $this->app->display("github/repo"); } } - - function repoCallback($repo) { - $this->app->getView()->addData(compact("repo") + [ - "title" => "Github: {$repo->name}" - ]); - settype($repo->tags, "object"); - $this->github->listHooks($repo->full_name, function($hooks) use($repo) { - $repo->hooks = $hooks; - $this->app->getView()->addData(["hook" => $this->checkRepoHook($repo)]); - }); - $this->github->listTags($repo->full_name, 1, $this->createTagsCallback($repo)); - $this->github->listReleases($repo->full_name, 1, $this->createReleasesCallback($repo)); - $this->github->readContents($repo->full_name, null, $this->createContentsCallback($repo)); - } - - function createReleasesCallback($repo) { - return function($releases, $links) use($repo) { - foreach ($releases as $release) { - $tag = $release->tag_name; - settype($repo->tags->$tag, "object"); - $repo->tags->$tag->release = $release; - $this->github->listReleaseAssets($repo->full_name, $release->id, function($assets) use($release) { - $release->assets = $assets; - }); - } - }; - } - - function createTagsCallback($repo) { - return function($tags, $links) use ($repo) { - foreach ($tags as $tag) { - $name = $tag->name; - settype($repo->tags->$name, "object"); - $repo->tags->$name->tag = $tag; - } - }; - } - - function createContentsCallback($repo) { - return function($tree) use($repo) { - foreach ($tree as $entry) { - if ($entry->type !== "file" || $entry->size <= 0) { - continue; - } - if ($entry->name === "config.m4" || fnmatch("config?.m4", $entry->name)) { - $repo->config_m4 = $entry->name; - } elseif ($entry->name === "package.xml" || $entry->name === "package2.xml") { - $repo->package_xml = $entry->name; - } elseif ($entry->name === "pharext_package.php") { - $repo->pharext_package_php = $entry->name; - } - } - }; - } } diff --git a/app/Controller/Github/RepoHook.php b/app/Controller/Github/RepoHook.php index 023763a..39f6f1b 100644 --- a/app/Controller/Github/RepoHook.php +++ b/app/Controller/Github/RepoHook.php @@ -48,7 +48,7 @@ class RepoHook extends Github $this->github->readRepo("$owner/$repo", function($repo) { $call = $this->github->listHooks($repo->full_name, function($hooks, $links) use($repo, &$call) { $repo->hooks = $hooks; - if (($hook = $this->checkRepoHook($repo))) { + if (($hook = $this->github->checkRepoHook($repo))) { $hook_conf = $this->app->getRequest()->getForm(); $this->github->updateRepoHook($repo->full_name, $hook->id, $hook_conf, function($changed_hook) use($repo, $hook, $hooks, $links, &$call) { foreach ($changed_hook as $key => $val) { @@ -66,7 +66,7 @@ class RepoHook extends Github $this->github->readRepo("$owner/$repo", function($repo) { $call = $this->github->listHooks($repo->full_name, function($hooks) use($repo, &$call) { $repo->hooks = $hooks; - if (($hook = $this->checkRepoHook($repo))) { + if (($hook = $this->github->checkRepoHook($repo))) { $this->github->deleteRepoHook($repo->full_name, $hook->id, function() use($repo, &$call) { $call->dropFromCache(); $this->redirectBack($repo->full_name); diff --git a/app/Github/API.php b/app/Github/API.php index d6990f2..1c9ff78 100644 --- a/app/Github/API.php +++ b/app/Github/API.php @@ -168,6 +168,22 @@ class API return $call($callback); } + /** + * Check if the pharext webhook is set for the repo and return it + * @param object $repo + * @return stdClass hook + */ + function checkRepoHook($repo) { + if ($repo->hooks) { + foreach ($repo->hooks as $hook) { + if ($hook->name === "web" && $hook->config->url === $this->config->hook->url) { + return $hook; + } + } + } + return null; + } + function listHooks($repo, callable $callback) { $call = new API\Hooks\ListHooks($this, compact("repo")); return $call($callback); diff --git a/app/Github/API/Call.php b/app/Github/API/Call.php index d4afd19..22a6951 100644 --- a/app/Github/API/Call.php +++ b/app/Github/API/Call.php @@ -35,6 +35,11 @@ abstract class Call */ protected $query; + /** + * @var array + */ + protected $result; + /** * Queue this call to the API client */ @@ -58,8 +63,8 @@ abstract class Call } function __invoke(callable $callback) { - if ($this->readFromCache($cached)) { - call_user_func_array($callback, $cached); + if ($this->readFromCache($this->result)) { + call_user_func_array($callback, $this->result); } else { $this->enqueue($callback); } @@ -79,7 +84,8 @@ abstract class Call * Call Client::send() */ function send() { - return $this->api->getClient()->send(); + $this->api->getClient()->send(); + return $this->result; } /** diff --git a/app/Github/API/Callback.php b/app/Github/API/Callback.php new file mode 100644 index 0000000..04b9ed6 --- /dev/null +++ b/app/Github/API/Callback.php @@ -0,0 +1,16 @@ +api = $api; + } +} diff --git a/app/Github/API/Hooks/CreateHook.php b/app/Github/API/Hooks/CreateHook.php index 866e939..8e7c050 100644 --- a/app/Github/API/Hooks/CreateHook.php +++ b/app/Github/API/Hooks/CreateHook.php @@ -39,6 +39,7 @@ class CreateHook extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } + $this->result = [$json]; $callback($json); return true; }); diff --git a/app/Github/API/Hooks/HooksCallback.php b/app/Github/API/Hooks/HooksCallback.php new file mode 100644 index 0000000..f520844 --- /dev/null +++ b/app/Github/API/Hooks/HooksCallback.php @@ -0,0 +1,20 @@ +repo = $repo; + } + + function __invoke($json, $links = null) { + $this->repo->hooks = $json; + } +} diff --git a/app/Github/API/Hooks/ListHooks.php b/app/Github/API/Hooks/ListHooks.php index 6cd784e..3d8237e 100644 --- a/app/Github/API/Hooks/ListHooks.php +++ b/app/Github/API/Hooks/ListHooks.php @@ -20,7 +20,8 @@ class ListHooks extends Call throw new RequestException($response); } $links = new Links($response->getHeader("Link")); - $this->saveToCache([$json, $links]); + $this->result = [$json, $links]; + $this->saveToCache($this->result); $callback($json, $links); return true; }); diff --git a/app/Github/API/Hooks/UpdateHook.php b/app/Github/API/Hooks/UpdateHook.php index cd249ba..1fb8231 100644 --- a/app/Github/API/Hooks/UpdateHook.php +++ b/app/Github/API/Hooks/UpdateHook.php @@ -25,6 +25,7 @@ class UpdateHook extends \app\Github\API\Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new \app\Github\Exception\RequestException($response); } + $this->result = [$json]; $callback($json); return true; }); diff --git a/app/Github/API/Releases/CreateRelease.php b/app/Github/API/Releases/CreateRelease.php index 21f849f..5942f0c 100644 --- a/app/Github/API/Releases/CreateRelease.php +++ b/app/Github/API/Releases/CreateRelease.php @@ -22,6 +22,7 @@ class CreateRelease extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } + $this->result = [$json]; $callback($json); return true; }); diff --git a/app/Github/API/Releases/CreateReleaseAsset.php b/app/Github/API/Releases/CreateReleaseAsset.php index c69d805..88b5a49 100644 --- a/app/Github/API/Releases/CreateReleaseAsset.php +++ b/app/Github/API/Releases/CreateReleaseAsset.php @@ -20,6 +20,7 @@ class CreateReleaseAsset extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } + $this->result = [$json]; $callback($json); return true; }); diff --git a/app/Github/API/Releases/ListReleaseAssets.php b/app/Github/API/Releases/ListReleaseAssets.php index bde9096..2aaaaad 100644 --- a/app/Github/API/Releases/ListReleaseAssets.php +++ b/app/Github/API/Releases/ListReleaseAssets.php @@ -20,7 +20,8 @@ class ListReleaseAssets extends Call throw new RequestException($response); } $links = new Links($response->getHeader("Link")); - $this->saveToCache([$json, $links]); + $this->result = [$json, $links]; + $this->saveToCache($this->result); $callback($json, $links); return true; }); diff --git a/app/Github/API/Releases/ListReleases.php b/app/Github/API/Releases/ListReleases.php index c1760b9..bb1e158 100644 --- a/app/Github/API/Releases/ListReleases.php +++ b/app/Github/API/Releases/ListReleases.php @@ -20,7 +20,8 @@ class ListReleases extends Call throw new RequestException($response); } $links = new Links($response->getHeader("Link")); - $this->saveToCache([$json, $links]); + $this->result = [$json, $links]; + $this->saveToCache($this->result); $callback($json, $links); return true; }); diff --git a/app/Github/API/Repos/ContentsCallback.php b/app/Github/API/Repos/ContentsCallback.php new file mode 100644 index 0000000..c08c3c2 --- /dev/null +++ b/app/Github/API/Repos/ContentsCallback.php @@ -0,0 +1,31 @@ +repo = $repo; + } + + function __invoke($json, $links = null) { + foreach ($json as $entry) { + if ($entry->type !== "file" || $entry->size <= 0) { + continue; + } + if ($entry->name === "config.m4" || fnmatch("config?.m4", $entry->name)) { + $this->repo->config_m4 = $entry->name; + } elseif ($entry->name === "package.xml" || $entry->name === "package2.xml") { + $this->repo->package_xml = $entry->name; + } elseif ($entry->name === "pharext_package.php") { + $this->repo->pharext_package_php = $entry->name; + } + } + } +} diff --git a/app/Github/API/Repos/ListRepos.php b/app/Github/API/Repos/ListRepos.php index c842196..60767c3 100644 --- a/app/Github/API/Repos/ListRepos.php +++ b/app/Github/API/Repos/ListRepos.php @@ -20,7 +20,8 @@ class ListRepos extends Call throw new RequestException($response); } $links = new Links($response->getHeader("Link")); - $this->saveToCache([$json, $links]); + $this->result = [$json, $links]; + $this->saveToCache($this->result); $callback($json, $links); return true; }); diff --git a/app/Github/API/Repos/ReadContents.php b/app/Github/API/Repos/ReadContents.php index fde19b8..844df19 100644 --- a/app/Github/API/Repos/ReadContents.php +++ b/app/Github/API/Repos/ReadContents.php @@ -18,7 +18,8 @@ class ReadContents extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } - $this->saveToCache([$json]); + $this->result = [$json]; + $this->saveToCache($this->result); $callback($json); return true; }); diff --git a/app/Github/API/Repos/ReadRepo.php b/app/Github/API/Repos/ReadRepo.php index 775a9ee..2a82b08 100644 --- a/app/Github/API/Repos/ReadRepo.php +++ b/app/Github/API/Repos/ReadRepo.php @@ -18,7 +18,8 @@ class ReadRepo extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } - $this->saveToCache([$json]); + $this->result = [$json]; + $this->saveToCache($this->result); $callback($json); return true; }); diff --git a/app/Github/API/Repos/ReleasesCallback.php b/app/Github/API/Repos/ReleasesCallback.php new file mode 100644 index 0000000..aca8575 --- /dev/null +++ b/app/Github/API/Repos/ReleasesCallback.php @@ -0,0 +1,28 @@ +repo = $repo; + } + + function __invoke($json, $links = null) { + settype($this->repo->tags, "object"); + foreach ($json as $release) { + $tag = $release->tag_name; + settype($this->repo->tags->$tag, "object"); + $this->repo->tags->$tag->release = $release; + $this->api->listReleaseAssets($this->repo->full_name, $release->id, function($assets) use($release) { + $release->assets = $assets; + }); + } + } +} diff --git a/app/Github/API/Repos/RepoCallback.php b/app/Github/API/Repos/RepoCallback.php new file mode 100644 index 0000000..a3621a5 --- /dev/null +++ b/app/Github/API/Repos/RepoCallback.php @@ -0,0 +1,17 @@ +api->listHooks($repo->full_name, new HooksCallback($this->api, $repo)); + $this->api->listTags($repo->full_name, 1, new TagsCallback($this->api, $repo)); + $this->api->listReleases($repo->full_name, 1, new ReleasesCallback($this->api, $repo)); + $this->api->readContents($repo->full_name, null, new ContentsCallback($this->api, $repo));; + } +} diff --git a/app/Github/API/Repos/ReposCallback.php b/app/Github/API/Repos/ReposCallback.php new file mode 100644 index 0000000..78d68c9 --- /dev/null +++ b/app/Github/API/Repos/ReposCallback.php @@ -0,0 +1,15 @@ +api->listHooks($repo->full_name, new HooksCallback($this->api, $repo)); + } + } +} diff --git a/app/Github/API/Tags/ListTags.php b/app/Github/API/Tags/ListTags.php index b7a1d4c..fd60a67 100644 --- a/app/Github/API/Tags/ListTags.php +++ b/app/Github/API/Tags/ListTags.php @@ -20,7 +20,8 @@ class ListTags extends Call throw new RequestException($response); } $links = new Links($response->getHeader("Link")); - $this->saveToCache([$json, $links]); + $this->result = [$json, $links]; + $this->saveToCache($this->result); $callback($json, $links); return true; }); diff --git a/app/Github/API/Tags/TagsCallback.php b/app/Github/API/Tags/TagsCallback.php new file mode 100644 index 0000000..99b623b --- /dev/null +++ b/app/Github/API/Tags/TagsCallback.php @@ -0,0 +1,25 @@ +repo = $repo; + } + + function __invoke($json, $links = null) { + settype($this->repo->tags, "object"); + foreach ($json as $tag) { + $name = $tag->name; + settype($this->repo->tags->$name, "object"); + $this->repo->tags->$name->tag = $tag; + } + } +} diff --git a/app/Github/API/Users/ReadAuthToken.php b/app/Github/API/Users/ReadAuthToken.php index bc1f03b..e167eef 100644 --- a/app/Github/API/Users/ReadAuthToken.php +++ b/app/Github/API/Users/ReadAuthToken.php @@ -18,6 +18,7 @@ class ReadAuthToken extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } + $this->result = [$json]; $callback($json); return true; }); diff --git a/app/Github/API/Users/ReadAuthUser.php b/app/Github/API/Users/ReadAuthUser.php index 6cb6de0..b5c4fa9 100644 --- a/app/Github/API/Users/ReadAuthUser.php +++ b/app/Github/API/Users/ReadAuthUser.php @@ -18,7 +18,8 @@ class ReadAuthUser extends Call if ($response->getResponseCode() >= 400 || null === ($json = json_decode($response->getBody()))) { throw new RequestException($response); } - $this->saveToCache([$json]); + $this->result = [$json]; + $this->saveToCache($this->result); $callback($json); return true; }); diff --git a/app/views/github/repo.phtml b/app/views/github/repo.phtml index ae72691..c1994a8 100644 --- a/app/views/github/repo.phtml +++ b/app/views/github/repo.phtml @@ -1,4 +1,4 @@ -layout("layout") ?> +layout("layout", ["title" => "Github: {$repo->name}"]) ?>