SchemaCommand.php•3.8 kB
<?php
declare(strict_types=1);
namespace Butschster\ContextGenerator\Console;
use Butschster\ContextGenerator\DirectoriesInterface;
use Butschster\ContextGenerator\Lib\HttpClient\Exception\HttpException;
use Butschster\ContextGenerator\Lib\HttpClient\HttpClientInterface;
use Spiral\Console\Attribute\Option;
use Spiral\Files\FilesInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
#[AsCommand(
    name: 'schema',
    description: 'Get information about or download the JSON schema for IDE integration',
    aliases: ['json-schema'],
)]
final class SchemaCommand extends BaseCommand
{
    private const string SCHEMA_URL = 'https://raw.githubusercontent.com/context-hub/generator/refs/heads/main/json-schema.json';
    #[Option(
        name: 'download',
        shortcut: 'd',
        description: 'Download the schema to the current directory',
    )]
    protected bool $download = false;
    #[Option(
        name: 'output',
        shortcut: 'o',
        description: 'The file path where the schema should be saved',
    )]
    protected string $outputPath = 'json-schema.json';
    /**
     * Execute the command
     */
    public function __invoke(
        HttpClientInterface $httpClient,
        FilesInterface $files,
        DirectoriesInterface $dirs,
    ): int {
        $outputPath = (string) $dirs->getRootPath()->join($this->outputPath);
        // Always show the URL where the schema is hosted
        $this->output->info('JSON schema URL: ' . self::SCHEMA_URL);
        // If no download requested, exit early
        if (!$this->download) {
            $this->output->note('Use --download option to download the schema to your current directory');
            return Command::SUCCESS;
        }
        // Download and save the schema
        try {
            $response = $httpClient->get(self::SCHEMA_URL, [
                'User-Agent' => 'Context-Generator-Schema-Download',
                'Accept' => 'application/json',
            ]);
            if (!$response->isSuccess()) {
                $this->output->error(
                    \sprintf(
                        'Failed to download schema. Server returned status code %d',
                        $response->getStatusCode(),
                    ),
                );
                return Command::FAILURE;
            }
            $schemaContent = $response->getBody();
            // Validate that the schema is proper JSON
            try {
                // This will throw an exception if the content is not valid JSON
                $response->getJson();
            } catch (HttpException $e) {
                $this->output->error('Downloaded schema is not valid JSON: ' . $e->getMessage());
                return Command::FAILURE;
            }
            // Save schema to file
            if (!$files->write($this->outputPath, $schemaContent)) {
                $this->output->error(\sprintf('Failed to write schema to %s', $outputPath));
                return Command::FAILURE;
            }
            $this->output->success(\sprintf('Schema successfully downloaded to %s', $outputPath));
            // Provide a hint about how to use the schema
            $this->output->note([
                'To use this schema in your IDE:',
                '- For PhpStorm/IntelliJ IDEA: Add the json-schema.json file to your project and associate it with your context.json file',
                '- For VS Code: Add the schema to your settings.json in the "json.schemas" section',
            ]);
            return Command::SUCCESS;
        } catch (\Throwable $e) {
            $this->output->error(\sprintf('Error downloading schema: %s', $e->getMessage()));
            return Command::FAILURE;
        }
    }
}