├── LICENSE ├── composer.json ├── config └── gitlab.php └── src ├── Auth ├── Authenticator │ ├── AbstractAuthenticator.php │ ├── AuthenticatorInterface.php │ ├── JobTokenAuthenticator.php │ ├── OauthAuthenticator.php │ └── TokenAuthenticator.php └── AuthenticatorFactory.php ├── Cache ├── ConnectionFactory.php └── Connector │ └── IlluminateConnector.php ├── Facades └── GitLab.php ├── GitLabFactory.php ├── GitLabManager.php ├── GitLabServiceProvider.php └── HttpClient └── BuilderFactory.php /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018-2025 Graham Campbell 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graham-campbell/gitlab", 3 | "description": "GitLab Is A GitLab Bridge For Laravel", 4 | "keywords": ["laravel", "framework", "gitlab", "php-gitlab-api", "PHP GitLab API", "gitlab bridge", "bridge", "GitLab", "Laravel GitLab", "Laravel-GitLab", "Graham Campbell", "GrahamCampbell"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Graham Campbell", 9 | "email": "hello@gjcampbell.co.uk", 10 | "homepage": "https://github.com/GrahamCampbell" 11 | } 12 | ], 13 | "require": { 14 | "php": "^8.1", 15 | "graham-campbell/bounded-cache": "^3.0", 16 | "graham-campbell/manager": "^5.2", 17 | "guzzlehttp/guzzle": "^7.9.2", 18 | "guzzlehttp/psr7": "^2.7.0", 19 | "illuminate/contracts": "^10.44 || ^11.0 || ^12.0", 20 | "illuminate/support": "^10.44 || ^11.0 || ^12.0", 21 | "m4tthumphrey/php-gitlab-api": "12.0.*", 22 | "symfony/cache": "^6.2 || ^7.0" 23 | }, 24 | "require-dev": { 25 | "graham-campbell/analyzer": "^5.0", 26 | "graham-campbell/testbench": "^6.2", 27 | "mockery/mockery": "^1.6.6", 28 | "phpunit/phpunit": "^10.5.45 || ^11.5.10" 29 | }, 30 | "autoload": { 31 | "psr-4": { 32 | "GrahamCampbell\\GitLab\\": "src/" 33 | } 34 | }, 35 | "autoload-dev": { 36 | "psr-4": { 37 | "GrahamCampbell\\Tests\\GitLab\\": "tests/" 38 | } 39 | }, 40 | "config": { 41 | "preferred-install": "dist", 42 | "allow-plugins": { 43 | "php-http/discovery": true 44 | } 45 | }, 46 | "extra": { 47 | "laravel": { 48 | "providers": [ 49 | "GrahamCampbell\\GitLab\\GitLabServiceProvider" 50 | ] 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /config/gitlab.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | return [ 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Default Connection Name 19 | |-------------------------------------------------------------------------- 20 | | 21 | | Here you may specify which of the connections below you wish to use as 22 | | your default connection for all work. Of course, you may use many 23 | | connections at once using the manager class. 24 | | 25 | */ 26 | 27 | 'default' => 'main', 28 | 29 | /* 30 | |-------------------------------------------------------------------------- 31 | | GitLab Connections 32 | |-------------------------------------------------------------------------- 33 | | 34 | | Here are each of the connections setup for your application. Example 35 | | configuration has been included, but you may add as many connections as 36 | | you would like. Note that the 4 supported authentication methods are: 37 | | "none", "oauth", "job_token", and "token". 38 | | 39 | */ 40 | 41 | 'connections' => [ 42 | 43 | 'main' => [ 44 | 'token' => 'your-token', 45 | 'method' => 'token', 46 | // 'backoff' => false, 47 | // 'cache' => false, 48 | // 'sudo' => null, 49 | // 'url' => null, 50 | ], 51 | 52 | 'alternative' => [ 53 | 'token' => 'your-token', 54 | 'method' => 'oauth', 55 | // 'backoff' => false, 56 | // 'cache' => false, 57 | // 'sudo' => null, 58 | // 'url' => null, 59 | ], 60 | 61 | ], 62 | 63 | /* 64 | |-------------------------------------------------------------------------- 65 | | HTTP Cache 66 | |-------------------------------------------------------------------------- 67 | | 68 | | Here are each of the cache configurations setup for your application. 69 | | Only the "illuminate" driver is provided out of the box. Example 70 | | configuration has been included. 71 | | 72 | */ 73 | 74 | 'cache' => [ 75 | 76 | 'main' => [ 77 | 'driver' => 'illuminate', 78 | 'connector' => null, // null means use default driver 79 | // 'min' => 43200, 80 | // 'max' => 172800 81 | ], 82 | 83 | 'bar' => [ 84 | 'driver' => 'illuminate', 85 | 'connector' => 'redis', // config/cache.php 86 | // 'min' => 43200, 87 | // 'max' => 172800 88 | ], 89 | 90 | ], 91 | 92 | ]; 93 | -------------------------------------------------------------------------------- /src/Auth/Authenticator/AbstractAuthenticator.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Auth\Authenticator; 15 | 16 | use Gitlab\Client; 17 | use InvalidArgumentException; 18 | 19 | /** 20 | * This is the abstract authenticator class. 21 | * 22 | * @author Graham Campbell 23 | */ 24 | abstract class AbstractAuthenticator implements AuthenticatorInterface 25 | { 26 | private ?Client $client = null; 27 | 28 | /** 29 | * Set the client to perform the authentication on. 30 | * 31 | * @param \Gitlab\Client $client 32 | * 33 | * @return \GrahamCampbell\GitLab\Auth\Authenticator\AuthenticatorInterface 34 | */ 35 | public function with(Client $client): AuthenticatorInterface 36 | { 37 | $this->client = $client; 38 | 39 | return $this; 40 | } 41 | 42 | /** 43 | * @throws \InvalidArgumentException 44 | * 45 | * @return \Gitlab\Client 46 | */ 47 | protected function getClient(): Client 48 | { 49 | if (!$this->client) { 50 | throw new InvalidArgumentException('The client instance was not given to the authenticator.'); 51 | } 52 | 53 | return $this->client; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Auth/Authenticator/AuthenticatorInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Auth\Authenticator; 15 | 16 | use Gitlab\Client; 17 | 18 | /** 19 | * This is the authenticator interface. 20 | * 21 | * @author Graham Campbell 22 | */ 23 | interface AuthenticatorInterface 24 | { 25 | /** 26 | * Set the client to perform the authentication on. 27 | * 28 | * @param \Gitlab\Client $client 29 | * 30 | * @return \GrahamCampbell\GitLab\Auth\Authenticator\AuthenticatorInterface 31 | */ 32 | public function with(Client $client): AuthenticatorInterface; 33 | 34 | /** 35 | * Authenticate the client, and return it. 36 | * 37 | * @param string[] $config 38 | * 39 | * @throws \InvalidArgumentException 40 | * 41 | * @return \Gitlab\Client 42 | */ 43 | public function authenticate(array $config): Client; 44 | } 45 | -------------------------------------------------------------------------------- /src/Auth/Authenticator/JobTokenAuthenticator.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Auth\Authenticator; 15 | 16 | use Gitlab\Client; 17 | use InvalidArgumentException; 18 | 19 | /** 20 | * This is the job token authenticator class. 21 | * 22 | * @author Graham Campbell 23 | */ 24 | final class JobTokenAuthenticator extends AbstractAuthenticator 25 | { 26 | /** 27 | * Authenticate the client, and return it. 28 | * 29 | * @param string[] $config 30 | * 31 | * @throws \InvalidArgumentException 32 | * 33 | * @return \Gitlab\Client 34 | */ 35 | public function authenticate(array $config): Client 36 | { 37 | $client = $this->getClient(); 38 | 39 | if (!array_key_exists('token', $config)) { 40 | throw new InvalidArgumentException('The job token authenticator requires a token.'); 41 | } 42 | 43 | $client->authenticate($config['token'], Client::AUTH_HTTP_JOB_TOKEN, $config['sudo'] ?? null); 44 | 45 | return $client; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Auth/Authenticator/OauthAuthenticator.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Auth\Authenticator; 15 | 16 | use Gitlab\Client; 17 | use InvalidArgumentException; 18 | 19 | /** 20 | * This is the oauth authenticator class. 21 | * 22 | * @author Graham Campbell 23 | */ 24 | final class OauthAuthenticator extends AbstractAuthenticator 25 | { 26 | /** 27 | * Authenticate the client, and return it. 28 | * 29 | * @param string[] $config 30 | * 31 | * @throws \InvalidArgumentException 32 | * 33 | * @return \Gitlab\Client 34 | */ 35 | public function authenticate(array $config): Client 36 | { 37 | $client = $this->getClient(); 38 | 39 | if (!array_key_exists('token', $config)) { 40 | throw new InvalidArgumentException('The oauth authenticator requires a token.'); 41 | } 42 | 43 | $client->authenticate($config['token'], Client::AUTH_OAUTH_TOKEN, $config['sudo'] ?? null); 44 | 45 | return $client; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Auth/Authenticator/TokenAuthenticator.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Auth\Authenticator; 15 | 16 | use Gitlab\Client; 17 | use InvalidArgumentException; 18 | 19 | /** 20 | * This is the token authenticator class. 21 | * 22 | * @author Graham Campbell 23 | */ 24 | final class TokenAuthenticator extends AbstractAuthenticator 25 | { 26 | /** 27 | * Authenticate the client, and return it. 28 | * 29 | * @param string[] $config 30 | * 31 | * @throws \InvalidArgumentException 32 | * 33 | * @return \Gitlab\Client 34 | */ 35 | public function authenticate(array $config): Client 36 | { 37 | $client = $this->getClient(); 38 | 39 | if (!array_key_exists('token', $config)) { 40 | throw new InvalidArgumentException('The token authenticator requires a token.'); 41 | } 42 | 43 | $client->authenticate($config['token'], Client::AUTH_HTTP_TOKEN, $config['sudo'] ?? null); 44 | 45 | return $client; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Auth/AuthenticatorFactory.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Auth; 15 | 16 | use GrahamCampbell\GitLab\Auth\Authenticator\AuthenticatorInterface; 17 | use InvalidArgumentException; 18 | 19 | /** 20 | * This is the authenticator factory class. 21 | * 22 | * @author Graham Campbell 23 | */ 24 | class AuthenticatorFactory 25 | { 26 | /** 27 | * Make a new authenticator instance. 28 | * 29 | * @param string $method 30 | * 31 | * @throws \InvalidArgumentException 32 | * 33 | * @return \GrahamCampbell\GitLab\Auth\Authenticator\AuthenticatorInterface 34 | */ 35 | public function make(string $method): AuthenticatorInterface 36 | { 37 | return match ($method) { 38 | 'job_token' => new Authenticator\JobTokenAuthenticator(), 39 | 'oauth' => new Authenticator\OauthAuthenticator(), 40 | 'token' => new Authenticator\TokenAuthenticator(), 41 | default => throw new InvalidArgumentException("Unsupported authentication method [$method]."), 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Cache/ConnectionFactory.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Cache; 15 | 16 | use GrahamCampbell\BoundedCache\BoundedCacheInterface; 17 | use GrahamCampbell\Manager\ConnectorInterface; 18 | use Illuminate\Contracts\Cache\Factory; 19 | use InvalidArgumentException; 20 | 21 | /** 22 | * This is the cache connection factory class. 23 | * 24 | * @author Graham Campbell 25 | */ 26 | class ConnectionFactory 27 | { 28 | /** 29 | * Create a new connection factory instance. 30 | * 31 | * @param \Illuminate\Contracts\Cache\Factory|null $cache 32 | * 33 | * @return void 34 | */ 35 | public function __construct( 36 | private readonly ?Factory $cache = null, 37 | ) { 38 | } 39 | 40 | /** 41 | * Establish a cache connection. 42 | * 43 | * @param array $config 44 | * 45 | * @throws \InvalidArgumentException 46 | * 47 | * @return \GrahamCampbell\BoundedCache\BoundedCacheInterface 48 | */ 49 | public function make(array $config): BoundedCacheInterface 50 | { 51 | return $this->createConnector($config)->connect($config); 52 | } 53 | 54 | /** 55 | * Create a connector instance based on the configuration. 56 | * 57 | * @param array $config 58 | * 59 | * @throws \InvalidArgumentException 60 | * 61 | * @return \GrahamCampbell\Manager\ConnectorInterface 62 | */ 63 | public function createConnector(array $config): ConnectorInterface 64 | { 65 | if (!isset($config['driver'])) { 66 | throw new InvalidArgumentException('A driver must be specified.'); 67 | } 68 | 69 | switch ($config['driver']) { 70 | case 'illuminate': 71 | return new Connector\IlluminateConnector($this->cache); 72 | } 73 | 74 | throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]."); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Cache/Connector/IlluminateConnector.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Cache\Connector; 15 | 16 | use GrahamCampbell\BoundedCache\BoundedCache; 17 | use GrahamCampbell\BoundedCache\BoundedCacheInterface; 18 | use GrahamCampbell\Manager\ConnectorInterface; 19 | use Illuminate\Contracts\Cache\Factory; 20 | use Illuminate\Contracts\Cache\Repository; 21 | use Illuminate\Support\Arr; 22 | use InvalidArgumentException; 23 | 24 | /** 25 | * This is the illuminate connector class. 26 | * 27 | * @author Graham Campbell 28 | */ 29 | final class IlluminateConnector implements ConnectorInterface 30 | { 31 | private const MIN_CACHE_LIFETIME = 43200; 32 | private const MAX_CACHE_LIFETIME = 172800; 33 | 34 | /** 35 | * Create a new illuminate connector instance. 36 | * 37 | * @param \Illuminate\Contracts\Cache\Factory|null $cache 38 | * 39 | * @return void 40 | */ 41 | public function __construct( 42 | private readonly ?Factory $cache = null, 43 | ) { 44 | } 45 | 46 | /** 47 | * Establish a cache connection. 48 | * 49 | * @param array $config 50 | * 51 | * @throws \InvalidArgumentException 52 | * 53 | * @return \GrahamCampbell\BoundedCache\BoundedCacheInterface 54 | */ 55 | public function connect(array $config): BoundedCacheInterface 56 | { 57 | $repository = $this->getRepository($config); 58 | 59 | return self::getBoundedCache($repository, $config); 60 | } 61 | 62 | /** 63 | * Get the cache repository. 64 | * 65 | * @param array $config 66 | * 67 | * @throws \InvalidArgumentException 68 | * 69 | * @return \Illuminate\Contracts\Cache\Repository 70 | */ 71 | private function getRepository(array $config): Repository 72 | { 73 | if (!$this->cache) { 74 | throw new InvalidArgumentException('Illuminate caching support not available.'); 75 | } 76 | 77 | $name = Arr::get($config, 'connector'); 78 | 79 | return $this->cache->store($name); 80 | } 81 | 82 | /** 83 | * Get the bounded cache instance. 84 | * 85 | * @param \Illuminate\Contracts\Cache\Repository $repository 86 | * @param array $config 87 | * 88 | * @return \GrahamCampbell\BoundedCache\BoundedCacheInterface 89 | */ 90 | private static function getBoundedCache(Repository $repository, array $config): BoundedCacheInterface 91 | { 92 | $min = Arr::get($config, 'min', self::MIN_CACHE_LIFETIME); 93 | $max = Arr::get($config, 'max', self::MAX_CACHE_LIFETIME); 94 | 95 | return new BoundedCache($repository, $min, $max); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Facades/GitLab.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\Facades; 15 | 16 | use Illuminate\Support\Facades\Facade; 17 | 18 | /** 19 | * This is the gitlab facade class. 20 | * 21 | * @author Graham Campbell 22 | */ 23 | class GitLab extends Facade 24 | { 25 | /** 26 | * Get the registered name of the component. 27 | * 28 | * @return string 29 | */ 30 | protected static function getFacadeAccessor(): string 31 | { 32 | return 'gitlab'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/GitLabFactory.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab; 15 | 16 | use Gitlab\Client; 17 | use Gitlab\HttpClient\Builder; 18 | use GrahamCampbell\GitLab\Auth\Authenticator\AuthenticatorInterface; 19 | use GrahamCampbell\GitLab\Auth\AuthenticatorFactory; 20 | use GrahamCampbell\GitLab\Cache\ConnectionFactory; 21 | use GrahamCampbell\GitLab\HttpClient\BuilderFactory; 22 | use Http\Client\Common\Plugin\RetryPlugin; 23 | use Illuminate\Support\Arr; 24 | use InvalidArgumentException; 25 | use Symfony\Component\Cache\Adapter\Psr16Adapter; 26 | 27 | /** 28 | * This is the gitlab factory class. 29 | * 30 | * @author Graham Campbell 31 | */ 32 | class GitLabFactory 33 | { 34 | /** 35 | * Create a new gitlab factory instance. 36 | * 37 | * @param \GrahamCampbell\GitLab\HttpClient\BuilderFactory $builder 38 | * @param \GrahamCampbell\GitLab\Auth\AuthenticatorFactory $auth 39 | * @param \GrahamCampbell\GitLab\Cache\ConnectionFactory $cache 40 | * 41 | * @return void 42 | */ 43 | public function __construct( 44 | private readonly BuilderFactory $builder, 45 | private readonly AuthenticatorFactory $auth, 46 | private readonly ConnectionFactory $cache, 47 | ) { 48 | } 49 | 50 | /** 51 | * Make a new gitlab client. 52 | * 53 | * @param string[] $config 54 | * 55 | * @throws \InvalidArgumentException 56 | * 57 | * @return \Gitlab\Client 58 | */ 59 | public function make(array $config): Client 60 | { 61 | $client = new Client($this->getBuilder($config)); 62 | 63 | if (!array_key_exists('method', $config)) { 64 | throw new InvalidArgumentException('The gitlab factory requires an auth method.'); 65 | } 66 | 67 | if ($url = Arr::get($config, 'url')) { 68 | $client->setUrl($url); 69 | } 70 | 71 | if ($config['method'] === 'none') { 72 | return $client; 73 | } 74 | 75 | return $this->getAuthenticator($config['method'])->with($client)->authenticate($config); 76 | } 77 | 78 | /** 79 | * Get the http client builder. 80 | * 81 | * @param string[] $config 82 | * 83 | * @return \Gitlab\HttpClient\Builder 84 | */ 85 | protected function getBuilder(array $config): Builder 86 | { 87 | $builder = $this->builder->make(); 88 | 89 | if ($backoff = Arr::get($config, 'backoff')) { 90 | $builder->addPlugin(new RetryPlugin(['retries' => $backoff === true ? 2 : $backoff])); 91 | } 92 | 93 | if (is_array($cache = Arr::get($config, 'cache', false))) { 94 | $boundedCache = $this->cache->make($cache); 95 | 96 | $builder->addCache( 97 | new Psr16Adapter($boundedCache), 98 | ['cache_lifetime' => $boundedCache->getMaximumLifetime()] 99 | ); 100 | } 101 | 102 | return $builder; 103 | } 104 | 105 | /** 106 | * Get the authenticator. 107 | * 108 | * @throws \InvalidArgumentException 109 | * 110 | * @return \GrahamCampbell\GitLab\Auth\Authenticator\AuthenticatorInterface 111 | */ 112 | protected function getAuthenticator(string $method): AuthenticatorInterface 113 | { 114 | return $this->auth->make($method); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/GitLabManager.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab; 15 | 16 | use Gitlab\Client; 17 | use GrahamCampbell\Manager\AbstractManager; 18 | use Illuminate\Contracts\Config\Repository; 19 | use Illuminate\Support\Arr; 20 | 21 | /** 22 | * This is the gitlab manager class. 23 | * 24 | * @method \Gitlab\Client connection(string|null $name = null) 25 | * @method \Gitlab\Client reconnect(string|null $name = null) 26 | * @method void disconnect(string|null $name = null) 27 | * @method array getConnections() 28 | * @method \Gitlab\Api\DeployKeys deployKeys() 29 | * @method \Gitlab\Api\Deployments deployments() 30 | * @method \Gitlab\Api\Environments environments() 31 | * @method \Gitlab\Api\Events events() 32 | * @method \Gitlab\Api\Groups groups() 33 | * @method \Gitlab\Api\GroupsBoards groupsBoards() 34 | * @method \Gitlab\Api\GroupsEpics groupsEpics() 35 | * @method \Gitlab\Api\GroupsMilestones groupsMilestones() 36 | * @method \Gitlab\Api\IssueBoards issueBoards() 37 | * @method \Gitlab\Api\IssueLinks issueLinks() 38 | * @method \Gitlab\Api\Issues issues() 39 | * @method \Gitlab\Api\IssuesStatistics issuesStatistics() 40 | * @method \Gitlab\Api\Jobs jobs() 41 | * @method \Gitlab\Api\Keys keys() 42 | * @method \Gitlab\Api\MergeRequests mergeRequests() 43 | * @method \Gitlab\Api\Milestones milestones() 44 | * @method \Gitlab\Api\ProjectNamespaces namespaces() 45 | * @method \Gitlab\Api\Projects projects() 46 | * @method \Gitlab\Api\Repositories repositories() 47 | * @method \Gitlab\Api\RepositoryFiles repositoryFiles() 48 | * @method \Gitlab\Api\Schedules schedules() 49 | * @method \Gitlab\Api\Search search() 50 | * @method \Gitlab\Api\Snippets snippets() 51 | * @method \Gitlab\Api\SystemHooks systemHooks() 52 | * @method \Gitlab\Api\Users users() 53 | * @method \Gitlab\Api\Tags tags() 54 | * @method \Gitlab\Api\Version version() 55 | * @method \Gitlab\Api\Wiki wiki() 56 | * @method \Gitlab\Api\ApiInterface api(string $name) 57 | * @method void authenticate(string $token, string $authMethod, string|null $sudo = null) 58 | * @method void setUrl(string $url) 59 | * @method \Psr\Http\Message\ResponseInterface|null getLastResponse() 60 | * @method \Gitlab\HttpClient\Plugin\History getResponseHistory() 61 | * @method \Http\Client\Common\HttpMethodsClientInterface getHttpClient() 62 | * @method \Http\Message\StreamFactory getStreamFactory() 63 | * 64 | * @author Graham Campbell 65 | */ 66 | class GitLabManager extends AbstractManager 67 | { 68 | protected readonly GitLabFactory $factory; 69 | 70 | /** 71 | * Create a new gitlab manager instance. 72 | * 73 | * @param \Illuminate\Contracts\Config\Repository $config 74 | * @param \GrahamCampbell\GitLab\GitLabFactory $factory 75 | * 76 | * @return void 77 | */ 78 | public function __construct(Repository $config, GitLabFactory $factory) 79 | { 80 | parent::__construct($config); 81 | $this->factory = $factory; 82 | } 83 | 84 | /** 85 | * Create the connection instance. 86 | * 87 | * @param array $config 88 | * 89 | * @return \Gitlab\Client 90 | */ 91 | protected function createConnection(array $config): Client 92 | { 93 | return $this->factory->make($config); 94 | } 95 | 96 | /** 97 | * Get the configuration name. 98 | * 99 | * @return string 100 | */ 101 | protected function getConfigName(): string 102 | { 103 | return 'gitlab'; 104 | } 105 | 106 | /** 107 | * Get the configuration for a connection. 108 | * 109 | * @param string|null $name 110 | * 111 | * @throws \InvalidArgumentException 112 | * 113 | * @return array 114 | */ 115 | public function getConnectionConfig(?string $name = null): array 116 | { 117 | $config = parent::getConnectionConfig($name); 118 | 119 | if (is_string($cache = Arr::get($config, 'cache'))) { 120 | $config['cache'] = $this->getNamedConfig('cache', 'Cache', $cache); 121 | } 122 | 123 | return $config; 124 | } 125 | 126 | /** 127 | * Get the factory instance. 128 | * 129 | * @return \GrahamCampbell\GitLab\GitLabFactory 130 | */ 131 | public function getFactory(): GitLabFactory 132 | { 133 | return $this->factory; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/GitLabServiceProvider.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab; 15 | 16 | use Gitlab\Client; 17 | use GrahamCampbell\GitLab\Auth\AuthenticatorFactory; 18 | use GrahamCampbell\GitLab\Cache\ConnectionFactory; 19 | use GrahamCampbell\GitLab\HttpClient\BuilderFactory; 20 | use GuzzleHttp\Client as GuzzleClient; 21 | use GuzzleHttp\Psr7\HttpFactory as GuzzlePsrFactory; 22 | use Illuminate\Contracts\Container\Container; 23 | use Illuminate\Foundation\Application as LaravelApplication; 24 | use Illuminate\Support\ServiceProvider; 25 | use Laravel\Lumen\Application as LumenApplication; 26 | 27 | /** 28 | * This is the gitlab service provider class. 29 | * 30 | * @author Graham Campbell 31 | */ 32 | class GitLabServiceProvider extends ServiceProvider 33 | { 34 | /** 35 | * Boot the service provider. 36 | * 37 | * @return void 38 | */ 39 | public function boot(): void 40 | { 41 | $this->setupConfig(); 42 | } 43 | 44 | /** 45 | * Setup the config. 46 | * 47 | * @return void 48 | */ 49 | private function setupConfig(): void 50 | { 51 | $source = realpath($raw = __DIR__.'/../config/gitlab.php') ?: $raw; 52 | 53 | if ($this->app instanceof LaravelApplication && $this->app->runningInConsole()) { 54 | $this->publishes([$source => config_path('gitlab.php')]); 55 | } elseif ($this->app instanceof LumenApplication) { 56 | $this->app->configure('gitlab'); 57 | } 58 | 59 | $this->mergeConfigFrom($source, 'gitlab'); 60 | } 61 | 62 | /** 63 | * Register the service provider. 64 | * 65 | * @return void 66 | */ 67 | public function register(): void 68 | { 69 | $this->registerHttpClientFactory(); 70 | $this->registerAuthFactory(); 71 | $this->registerCacheFactory(); 72 | $this->registerGitLabFactory(); 73 | $this->registerManager(); 74 | $this->registerBindings(); 75 | } 76 | 77 | /** 78 | * Register the http client factory class. 79 | * 80 | * @return void 81 | */ 82 | private function registerHttpClientFactory(): void 83 | { 84 | $this->app->singleton('gitlab.httpclientfactory', function (): BuilderFactory { 85 | $psrFactory = new GuzzlePsrFactory(); 86 | 87 | return new BuilderFactory( 88 | new GuzzleClient(['connect_timeout' => 10, 'timeout' => 30]), 89 | $psrFactory, 90 | $psrFactory, 91 | $psrFactory, 92 | ); 93 | }); 94 | 95 | $this->app->alias('gitlab.httpclientfactory', BuilderFactory::class); 96 | } 97 | 98 | /** 99 | * Register the auth factory class. 100 | * 101 | * @return void 102 | */ 103 | private function registerAuthFactory(): void 104 | { 105 | $this->app->singleton('gitlab.authfactory', function (): AuthenticatorFactory { 106 | return new AuthenticatorFactory(); 107 | }); 108 | 109 | $this->app->alias('gitlab.authfactory', AuthenticatorFactory::class); 110 | } 111 | 112 | /** 113 | * Register the cache factory class. 114 | * 115 | * @return void 116 | */ 117 | private function registerCacheFactory(): void 118 | { 119 | $this->app->singleton('gitlab.cachefactory', function (Container $app): ConnectionFactory { 120 | $cache = $app->bound('cache') ? $app->make('cache') : null; 121 | 122 | return new ConnectionFactory($cache); 123 | }); 124 | 125 | $this->app->alias('gitlab.cachefactory', ConnectionFactory::class); 126 | } 127 | 128 | /** 129 | * Register the gitlab factory class. 130 | * 131 | * @return void 132 | */ 133 | private function registerGitLabFactory(): void 134 | { 135 | $this->app->singleton('gitlab.factory', function (Container $app): GitLabFactory { 136 | $builder = $app['gitlab.httpclientfactory']; 137 | $auth = $app['gitlab.authfactory']; 138 | $cache = $app['gitlab.cachefactory']; 139 | 140 | return new GitLabFactory($builder, $auth, $cache); 141 | }); 142 | 143 | $this->app->alias('gitlab.factory', GitLabFactory::class); 144 | } 145 | 146 | /** 147 | * Register the manager class. 148 | * 149 | * @return void 150 | */ 151 | private function registerManager(): void 152 | { 153 | $this->app->singleton('gitlab', function (Container $app): GitLabManager { 154 | $config = $app['config']; 155 | $factory = $app['gitlab.factory']; 156 | 157 | return new GitLabManager($config, $factory); 158 | }); 159 | 160 | $this->app->alias('gitlab', GitLabManager::class); 161 | } 162 | 163 | /** 164 | * Register the bindings. 165 | * 166 | * @return void 167 | */ 168 | private function registerBindings(): void 169 | { 170 | $this->app->bind('gitlab.connection', function (Container $app): Client { 171 | $manager = $app['gitlab']; 172 | 173 | return $manager->connection(); 174 | }); 175 | 176 | $this->app->alias('gitlab.connection', Client::class); 177 | } 178 | 179 | /** 180 | * Get the services provided by the provider. 181 | * 182 | * @return string[] 183 | */ 184 | public function provides(): array 185 | { 186 | return [ 187 | 'gitlab.httpclientfactory', 188 | 'gitlab.authfactory', 189 | 'gitlab.cachefactory', 190 | 'gitlab.factory', 191 | 'gitlab', 192 | 'gitlab.connection', 193 | ]; 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/HttpClient/BuilderFactory.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace GrahamCampbell\GitLab\HttpClient; 15 | 16 | use Gitlab\HttpClient\Builder; 17 | use Psr\Http\Client\ClientInterface; 18 | use Psr\Http\Message\RequestFactoryInterface; 19 | use Psr\Http\Message\StreamFactoryInterface; 20 | use Psr\Http\Message\UriFactoryInterface; 21 | 22 | /** 23 | * This is the http client builder factory class. 24 | * 25 | * @author Graham Campbell 26 | */ 27 | class BuilderFactory 28 | { 29 | /** 30 | * Create a new connection factory instance. 31 | * 32 | * @param \Psr\Http\Client\ClientInterface $httpClient 33 | * @param \Psr\Http\Message\RequestFactoryInterface $requestFactory 34 | * @param \Psr\Http\Message\StreamFactoryInterface $streamFactory 35 | * @param \Psr\Http\Message\UriFactoryInterface $uriFactory 36 | * 37 | * @return void 38 | */ 39 | public function __construct( 40 | private readonly ClientInterface $httpClient, 41 | private readonly RequestFactoryInterface $requestFactory, 42 | private readonly StreamFactoryInterface $streamFactory, 43 | private readonly UriFactoryInterface $uriFactory, 44 | ) { 45 | } 46 | 47 | /** 48 | * Return a new http client builder. 49 | * 50 | * @return \Gitlab\HttpClient\Builder 51 | */ 52 | public function make(): Builder 53 | { 54 | return new Builder($this->httpClient, $this->requestFactory, $this->streamFactory, $this->uriFactory); 55 | } 56 | } 57 | --------------------------------------------------------------------------------