Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
AgentsCommand
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
3 / 3
6
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 configure
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
39 / 39
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Fast Forward Development Tools for PHP projects.
7 *
8 * This file is part of fast-forward/dev-tools project.
9 *
10 * @author   Felipe SayĆ£o Lobato Abreu <github@mentordosnerds.com>
11 * @license  https://opensource.org/licenses/MIT MIT License
12 *
13 * @see      https://github.com/php-fast-forward/
14 * @see      https://github.com/php-fast-forward/dev-tools
15 * @see      https://github.com/php-fast-forward/dev-tools/issues
16 * @see      https://php-fast-forward.github.io/dev-tools/
17 * @see      https://datatracker.ietf.org/doc/html/rfc2119
18 */
19
20namespace FastForward\DevTools\Console\Command;
21
22use FastForward\DevTools\Console\Command\Traits\LogsCommandResults;
23use Composer\Command\BaseCommand;
24use FastForward\DevTools\Console\Input\HasJsonOption;
25use FastForward\DevTools\Filesystem\FilesystemInterface;
26use FastForward\DevTools\Path\DevToolsPathResolver;
27use FastForward\DevTools\Sync\PackagedDirectorySynchronizer;
28use Psr\Log\LoggerInterface;
29use Symfony\Component\Console\Attribute\AsCommand;
30use Symfony\Component\Console\Input\InputInterface;
31use Symfony\Component\Console\Output\OutputInterface;
32
33/**
34 * Synchronizes packaged Fast Forward project agents into the consumer repository.
35 */
36#[AsCommand(
37    name: 'agents',
38    description: 'Synchronizes Fast Forward project agents into .agents/agents directory.',
39    help: 'This command ensures the consumer repository contains linked Fast Forward project agents by creating symlinks to the packaged prompts and removing broken links.'
40)]
41 class AgentsCommand extends BaseCommand implements LoggerAwareCommandInterface
42{
43    use HasJsonOption;
44    use LogsCommandResults;
45
46    private const string AGENTS_DIRECTORY = '.agents/agents';
47
48    /**
49     * @param PackagedDirectorySynchronizer $synchronizer
50     * @param FilesystemInterface $filesystem
51     * @param LoggerInterface $logger
52     */
53    public function __construct(
54        private  PackagedDirectorySynchronizer $synchronizer,
55        private  FilesystemInterface $filesystem,
56        private  LoggerInterface $logger,
57    ) {
58        parent::__construct();
59    }
60
61    /**
62     * Configures JSON output options for the synchronization command.
63     */
64    protected function configure(): void
65    {
66        $this->addJsonOption();
67    }
68
69    /**
70     * @param InputInterface $input
71     * @param OutputInterface $output
72     *
73     * @return int
74     */
75    protected function execute(InputInterface $input, OutputInterface $output): int
76    {
77        $packageAgentsPath = DevToolsPathResolver::getPackagePath(self::AGENTS_DIRECTORY);
78        $agentsDir = $this->filesystem->getAbsolutePath(self::AGENTS_DIRECTORY);
79        $this->logger->info('Starting agents synchronization...');
80
81        if (! $this->filesystem->exists($packageAgentsPath)) {
82            return $this->failure(
83                'No packaged .agents/agents found at: {packaged_agents_path}',
84                $input,
85                [
86                    'packaged_agents_path' => $packageAgentsPath,
87                    'agents_dir' => $agentsDir,
88                    'directory_created' => false,
89                ],
90            );
91        }
92
93        $directoryCreated = false;
94
95        if (! $this->filesystem->exists($agentsDir)) {
96            $this->filesystem->mkdir($agentsDir);
97            $directoryCreated = true;
98            $this->logger->info('Created .agents/agents directory.');
99        }
100
101        $this->synchronizer->setLogger($this->getIO());
102
103        $result = $this->synchronizer->synchronize($agentsDir, $packageAgentsPath, self::AGENTS_DIRECTORY);
104
105        if ($result->failed()) {
106            return $this->failure(
107                'Agents synchronization failed.',
108                $input,
109                [
110                    'packaged_agents_path' => $packageAgentsPath,
111                    'agents_dir' => $agentsDir,
112                    'directory_created' => $directoryCreated,
113                ],
114            );
115        }
116
117        return $this->success(
118            'Agents synchronization completed successfully.',
119            $input,
120            [
121                'packaged_agents_path' => $packageAgentsPath,
122                'agents_dir' => $agentsDir,
123                'directory_created' => $directoryCreated,
124            ],
125        );
126    }
127}