From 1da046dbb1ad4cd9afb19d1c6a87098072c9a119 Mon Sep 17 00:00:00 2001 From: MBorne Date: Sat, 24 Nov 2018 18:06:11 +0100 Subject: [PATCH] GithubClient and GitlabClient : avoid some code duplication (refs #24) --- src/MBO/RemoteGit/GithubClient.php | 59 ++++++++++---------- src/MBO/RemoteGit/GitlabClient.php | 90 +++++++++++++----------------- 2 files changed, 70 insertions(+), 79 deletions(-) diff --git a/src/MBO/RemoteGit/GithubClient.php b/src/MBO/RemoteGit/GithubClient.php index f6163cd..164bac3 100644 --- a/src/MBO/RemoteGit/GithubClient.php +++ b/src/MBO/RemoteGit/GithubClient.php @@ -2,12 +2,20 @@ namespace MBO\RemoteGit; -use \GuzzleHttp\Client as GuzzleHttpClient; use Psr\Log\LoggerInterface; +use \GuzzleHttp\Client as GuzzleHttpClient; + use MBO\RemoteGit\Filter\ProjectFilterInterface; /** * Client implementation for github + * + * See following github docs : + * + * https://developer.github.com/v3/repos/#list-organization-repositories + * https://developer.github.com/v3/repos/#list-user-repositories + * https://developer.github.com/v3/#pagination + * */ class GithubClient implements ClientInterface { @@ -69,29 +77,10 @@ protected function findByUser( $user, ProjectFilterInterface $projectFilter ){ - $result = array(); - for ($page = 1; $page <= self::MAX_PAGES; $page++) { - /* - * https://developer.github.com/v3/repos/#list-user-repositories - * https://developer.github.com/v3/#pagination - */ - $uri = '/users/'.$user.'/repos?page='.$page.'&per_page='.self::DEFAULT_PER_PAGE; - - $this->logger->debug('GET '.$uri); - $response = $this->httpClient->get($uri); - $rawProjects = json_decode( (string)$response->getBody(), true ) ; - if ( empty($rawProjects) ){ - break; - } - foreach ( $rawProjects as $rawProject ){ - $project = new GithubProject($rawProject); - if ( ! $projectFilter->isAccepted($project) ){ - continue; - } - $result[] = $project; - } - } - return $result; + return $this->fetchAllPages( + '/users/'.$user.'/repos', + $projectFilter + ); } /** @@ -102,14 +91,26 @@ protected function findByUser( protected function findByOrg( $org, ProjectFilterInterface $projectFilter + ){ + return $this->fetchAllPages( + '/orgs/'.$org.'/repos', + $projectFilter + ); + } + + /** + * Fetch all pages for a given URI + * + * @param string $path such as '/orgs/IGNF/repos' or '/users/mborne/repos' + * @return ProjectInterface[] + */ + private function fetchAllPages( + $path, + ProjectFilterInterface $projectFilter ){ $result = array(); for ($page = 1; $page <= self::MAX_PAGES; $page++) { - /* - * https://developer.github.com/v3/repos/#list-organization-repositories - * https://developer.github.com/v3/#pagination - */ - $uri = '/orgs/'.$org.'/repos?page='.$page.'&per_page='.self::DEFAULT_PER_PAGE; + $uri = $path.'?page='.$page.'&per_page='.self::DEFAULT_PER_PAGE; $this->logger->debug('GET '.$uri); $response = $this->httpClient->get($uri); diff --git a/src/MBO/RemoteGit/GitlabClient.php b/src/MBO/RemoteGit/GitlabClient.php index f249830..f5a82e4 100644 --- a/src/MBO/RemoteGit/GitlabClient.php +++ b/src/MBO/RemoteGit/GitlabClient.php @@ -10,8 +10,11 @@ /** * Find gitlab projects * - * TODO add ClientInterface and RepositoryInterface to allow github, gogs and local repositories & co? + * See following gitlab docs : * + * https://docs.gitlab.com/ee/api/projects.html#list-all-projects + * https://docs.gitlab.com/ee/api/projects.html#search-for-projects-by-name + * */ class GitlabClient implements ClientInterface { @@ -45,6 +48,7 @@ public function __construct( * @{inheritDoc} */ public function find(FindOptions $options){ + /* find all projects applying optional search */ if ( empty($options->getUsers()) && empty($options->getOrganizations()) ){ return $this->findBySearch($options); } @@ -74,25 +78,10 @@ protected function findByUser( $user, ProjectFilterInterface $projectFilter ){ - $result = array(); - for ($page = 1; $page <= self::MAX_PAGES; $page++) { - $uri = '/api/v4/users/'.$user.'/projects?page='.$page.'&per_page='.self::DEFAULT_PER_PAGE; - - $this->logger->debug('GET '.$uri); - $response = $this->httpClient->get($uri); - $rawProjects = json_decode( (string)$response->getBody(), true ) ; - if ( empty($rawProjects) ){ - break; - } - foreach ( $rawProjects as $rawProject ){ - $project = new GitlabProject($rawProject); - if ( ! $projectFilter->isAccepted($project) ){ - continue; - } - $result[] = $project; - } - } - return $result; + return $this->fetchAllPages( + '/api/v4/users/'.urlencode($user).'/projects', + $projectFilter + ); } /** @@ -104,43 +93,44 @@ protected function findByGroup( $group, ProjectFilterInterface $projectFilter ){ - $result = array(); - for ($page = 1; $page <= self::MAX_PAGES; $page++) { - $uri = '/api/v4/groups/'.urlencode($group).'/projects?page='.$page.'&per_page='.self::DEFAULT_PER_PAGE; - - $this->logger->debug('GET '.$uri); - $response = $this->httpClient->get($uri); - $rawProjects = json_decode( (string)$response->getBody(), true ) ; - if ( empty($rawProjects) ){ - break; - } - foreach ( $rawProjects as $rawProject ){ - $project = new GitlabProject($rawProject); - if ( ! $projectFilter->isAccepted($project) ){ - continue; - } - $result[] = $project; - } - } - return $result; + return $this->fetchAllPages( + '/api/v4/groups/'.urlencode($group).'/projects', + $projectFilter + ); } /** * Find all projects using option search */ protected function findBySearch(FindOptions $options){ - /* - * refs : - * https://docs.gitlab.com/ee/api/projects.html#list-all-projects - * https://docs.gitlab.com/ee/api/projects.html#search-for-projects-by-name - */ + $path = '/api/v4/projects'; + if ( $options->hasSearch() ){ + $path .= '?search='.$options->getSearch(); + } + return $this->fetchAllPages( + $path, + $options->getFilterCollection() + ); + } + + + /** + * Fetch all pages for a given path + * + * @param string $path "/api/v4/projects?search=something", "/api/v4/projects" + * @param ProjectFilterInterface $projectFilter + * @return void + */ + private function fetchAllPages( + $path, + ProjectFilterInterface $projectFilter + ){ $result = array(); - + if ( strpos($path,'?') === false ){ + $path .= '?'; + } for ($page = 1; $page <= self::MAX_PAGES; $page++) { - $uri = '/api/v4/projects?page='.$page.'&per_page='.self::DEFAULT_PER_PAGE; - if ( $options->hasSearch() ){ - $uri .= '&search='.$options->getSearch(); - } + $uri = $path.'page='.$page.'&per_page='.self::DEFAULT_PER_PAGE; $this->logger->debug('GET '.$uri); $response = $this->httpClient->get($uri); $rawProjects = json_decode( (string)$response->getBody(), true ) ; @@ -149,7 +139,7 @@ protected function findBySearch(FindOptions $options){ } foreach ( $rawProjects as $rawProject ){ $project = new GitlabProject($rawProject); - if ( ! $options->getFilterCollection()->isAccepted($project) ){ + if ( ! $projectFilter->isAccepted($project) ){ continue; } $result[] = $project;