Skip to main content
Glama

CTX: Context as Code (CaC) tool

by context-hub
MIT License
235
  • Apple
  • Linux
GitlabClient.php6.48 kB
<?php declare(strict_types=1); namespace Butschster\ContextGenerator\Lib\GitlabClient; use Butschster\ContextGenerator\Application\Logger\LoggerPrefix; use Butschster\ContextGenerator\Lib\GitlabClient\Model\GitlabRepository; use Butschster\ContextGenerator\Lib\HttpClient\Exception\HttpException; use Butschster\ContextGenerator\Lib\HttpClient\HttpClientInterface; use Psr\Log\LoggerInterface; /** * GitLab API client implementation */ final class GitlabClient implements GitlabClientInterface { private string $serverUrl = 'https://gitlab.com'; private ?string $token = null; /** * Custom HTTP headers * * @var array<string, string> */ private array $headers = []; /** * Create a new GitLab client */ public function __construct( private readonly HttpClientInterface $httpClient, #[LoggerPrefix(prefix: 'gitlab-client')] private readonly ?LoggerInterface $logger = null, ) {} public function getContents(GitlabRepository $repository, string $path = ''): array { $this->logger?->debug('Getting repository contents', [ 'repository' => $repository->repository, 'branch' => $repository->branch, 'path' => $path, ]); // Format URL for GitLab API v4 $url = $this->buildApiUrl("/projects/{$repository->projectId}/repository/tree", [ 'ref' => $repository->branch, 'path' => $path, 'recursive' => 'false', ]); $this->logger?->debug('Making GitLab API request', [ 'url' => $url, ]); $response = $this->makeApiRequest($url); $items = \json_decode($response, true); if (!\is_array($items)) { $errorMessage = "Failed to parse GitLab API response for path: $path"; $this->logger?->error($errorMessage, [ 'response' => $response, ]); throw new \RuntimeException($errorMessage); } $this->logger?->debug('Got repository contents', [ 'itemCount' => \count($items), ]); return $items; } public function getFileContent(GitlabRepository $repository, string $path): string { $this->logger?->debug('Getting file content', [ 'repository' => $repository->repository, 'branch' => $repository->branch, 'path' => $path, ]); // Format URL for GitLab API v4 $url = $this->buildApiUrl("/projects/{$repository->projectId}/repository/files/" . \rawurlencode($path), [ 'ref' => $repository->branch, ]); $this->logger?->debug('Making GitLab API request', [ 'url' => $url, ]); $response = $this->makeApiRequest($url); $data = \json_decode($response, true); if (!\is_array($data) || !isset($data['content'])) { $errorMessage = "Failed to get file content for path: $path"; $this->logger?->error($errorMessage, [ 'response' => $response, ]); throw new \RuntimeException($errorMessage); } // GitLab returns file content as base64 encoded $content = \base64_decode((string) $data['content']); if ($content === false) { $errorMessage = "Failed to decode base64 content for path: $path"; $this->logger?->error($errorMessage); throw new \RuntimeException($errorMessage); } $this->logger?->debug('Got file content', [ 'contentLength' => \strlen($content), ]); return $content; } public function setToken(?string $token): void { $this->logger?->debug('Setting GitLab API token', [ 'hasToken' => $token !== null, ]); $this->token = $token; } public function setServerUrl(string $serverUrl): void { $this->logger?->debug('Setting GitLab server URL', [ 'serverUrl' => $serverUrl, ]); $this->serverUrl = \rtrim($serverUrl, '/'); } public function setHeaders(array $headers): void { $this->logger?->debug('Setting custom HTTP headers', [ 'headerCount' => \count($headers), 'headers' => \array_keys($headers), ]); $this->headers = $headers; } /** * Build a GitLab API URL * * @param string $path API endpoint path * @param array<string, string> $queryParams Query parameters * @return string Full API URL */ private function buildApiUrl(string $path, array $queryParams = []): string { $url = "{$this->serverUrl}/api/v4{$path}"; if (!empty($queryParams)) { $url .= '?' . \http_build_query($queryParams); } return $url; } /** * Make a GET request to the GitLab API * * @param string $url API URL * @return string API response * @throws \RuntimeException If the request fails */ private function makeApiRequest(string $url): string { // Prepare headers $headers = $this->prepareHeaders(); try { $response = $this->httpClient->get($url, $headers); if (!$response->isSuccess()) { $errorMessage = "GitLab API request failed with HTTP code {$response->getStatusCode()}"; $this->logger?->error($errorMessage, [ 'url' => $url, 'statusCode' => $response->getStatusCode(), 'response' => $response->getBody(), ]); throw new \RuntimeException($errorMessage); } return $response->getBody(); } catch (HttpException $e) { $errorMessage = "GitLab API request failed: {$e->getMessage()}"; $this->logger?->error($errorMessage, [ 'url' => $url, 'exception' => $e, ]); throw new \RuntimeException($errorMessage, 0, $e); } } /** * Prepare request headers for GitLab API * * @return array<string, string> Headers to send with the request */ private function prepareHeaders(): array { $headers = $this->headers; // Add authorization header if token is set if ($this->token !== null) { $headers['PRIVATE-TOKEN'] = $this->token; } return $headers; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/context-hub/generator'

If you have feedback or need assistance with the MCP directory API, please join our Discord server