Skip to main content
Glama

CTX: Context as Code (CaC) tool

by context-hub
MIT License
235
  • Apple
  • Linux
FileSystemComposerClient.php3.84 kB
<?php declare(strict_types=1); namespace Butschster\ContextGenerator\Lib\ComposerClient; use Butschster\ContextGenerator\Application\Logger\LoggerPrefix; use Butschster\ContextGenerator\Source\Composer\Exception\ComposerNotFoundException; use Psr\Log\LoggerInterface; use Spiral\Files\Exception\FilesException; use Spiral\Files\FilesInterface; /** * Client that interacts with Composer package data through the filesystem */ final readonly class FileSystemComposerClient implements ComposerClientInterface { public function __construct( private FilesInterface $files, #[LoggerPrefix(prefix: 'composer-client')] private ?LoggerInterface $logger = null, ) {} public function loadComposerData(string $path): array { // If path is a directory, append composer.json if (\is_dir($path)) { $path = \rtrim($path, '/') . '/composer.json'; } // Check if composer.json exists if (!$this->files->exists($path)) { $this->logger?->error('composer.json not found', ['path' => $path]); throw ComposerNotFoundException::fileNotFound($path); } // Read composer.json $composerJson = $this->files->read($path); // Parse composer.json $composerData = \json_decode($composerJson, true); if (!\is_array($composerData) || \json_last_error() !== JSON_ERROR_NONE) { $this->logger?->error('Failed to parse composer.json', [ 'path' => $path, 'error' => \json_last_error_msg(), ]); throw ComposerNotFoundException::cannotParse($path, \json_last_error_msg()); } return $composerData; } public function tryLoadComposerLock(string $path): ?array { $lockPath = \rtrim($path, '/') . '/composer.lock'; if (!$this->files->exists($lockPath)) { $this->logger?->info('composer.lock not found', ['path' => $lockPath]); return null; } // Read composer.lock try { $lockJson = $this->files->read($lockPath); } catch (FilesException $e) { $this->logger?->error('Failed to read composer.lock', [ 'path' => $lockPath, 'error' => $e->getMessage(), ]); return null; } // Parse composer.lock $lockData = \json_decode($lockJson, true); if (!\is_array($lockData) || \json_last_error() !== JSON_ERROR_NONE) { $this->logger?->warning('Failed to parse composer.lock', [ 'path' => $lockPath, 'error' => \json_last_error_msg(), ]); return null; } return $lockData; } public function getVendorDir(array $composerData, string $basePath): string { // Check if composer.json has a custom vendor-dir configuration if (isset($composerData['config']['vendor-dir']) && \is_string($composerData['config']['vendor-dir'])) { return $composerData['config']['vendor-dir']; } // Check if vendor directory exists in the base path $defaultVendorDir = 'vendor'; $vendorPath = $basePath . '/' . $defaultVendorDir; if (\is_dir($vendorPath)) { return $defaultVendorDir; } // If vendor directory doesn't exist, try to find it $possibleVendorDirs = ['vendor', 'vendors', 'lib', 'libs', 'packages', 'deps']; foreach ($possibleVendorDirs as $dir) { if (\is_dir($basePath . '/' . $dir)) { $this->logger?->info('Found alternative vendor directory', ['directory' => $dir]); return $dir; } } // Default to 'vendor' if nothing else is found return $defaultVendorDir; } }

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