Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
AgentsCommand
100.00% covered (success)
100.00%
44 / 44
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%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 execute
100.00% covered (success)
100.00%
38 / 38
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 FastForward\DevTools\Console\Input\HasJsonOption;
24use FastForward\DevTools\Filesystem\FilesystemInterface;
25use FastForward\DevTools\Path\DevToolsPathResolver;
26use FastForward\DevTools\Sync\PackagedDirectorySynchronizer;
27use Symfony\Component\Console\Attribute\AsCommand;
28use Symfony\Component\Console\Command\Command;
29use Symfony\Component\Console\Input\InputInterface;
30use Symfony\Component\Console\Output\OutputInterface;
31
32/**
33 * Synchronizes packaged Fast Forward project agents into the consumer repository.
34 */
35#[AsCommand(
36    name: 'agents:agents',
37    description: 'Synchronizes Fast Forward project agents into .agents/agents directory.',
38    aliases: ['agents'],
39)]
40 class AgentsCommand extends Command
41{
42    use HasJsonOption;
43    use LogsCommandResults;
44
45    private const string AGENTS_DIRECTORY = '.agents/agents';
46
47    /**
48     * @param PackagedDirectorySynchronizer $synchronizer
49     * @param FilesystemInterface $filesystem
50     */
51    public function __construct(
52        private  PackagedDirectorySynchronizer $synchronizer,
53        private  FilesystemInterface $filesystem,
54    ) {
55        parent::__construct();
56    }
57
58    /**
59     * Configures JSON output options for the synchronization command.
60     */
61    protected function configure(): void
62    {
63        $this->setHelp(
64            'This command ensures the consumer repository contains linked Fast Forward project agents by creating'
65            . ' symlinks to the packaged prompts and removing broken links.'
66        );
67        $this->addJsonOption();
68    }
69
70    /**
71     * @param InputInterface $input
72     * @param OutputInterface $output
73     *
74     * @return int
75     */
76    protected function execute(InputInterface $input, OutputInterface $output): int
77    {
78        $packageAgentsPath = DevToolsPathResolver::getPackagePath(self::AGENTS_DIRECTORY);
79        $agentsDir = $this->filesystem->getAbsolutePath(self::AGENTS_DIRECTORY);
80        $this->log('Starting agents synchronization...', $input);
81
82        if (! $this->filesystem->exists($packageAgentsPath)) {
83            return $this->failure(
84                'No packaged .agents/agents found at: {packaged_agents_path}',
85                $input,
86                [
87                    'packaged_agents_path' => $packageAgentsPath,
88                    'agents_dir' => $agentsDir,
89                    'directory_created' => false,
90                ],
91            );
92        }
93
94        $directoryCreated = false;
95
96        if (! $this->filesystem->exists($agentsDir)) {
97            $this->filesystem->mkdir($agentsDir);
98            $directoryCreated = true;
99            $this->log('Created .agents/agents directory.', $input);
100        }
101
102        $result = $this->synchronizer->synchronize($agentsDir, $packageAgentsPath, self::AGENTS_DIRECTORY);
103
104        if ($result->failed()) {
105            return $this->failure(
106                'Agents synchronization failed.',
107                $input,
108                [
109                    'packaged_agents_path' => $packageAgentsPath,
110                    'agents_dir' => $agentsDir,
111                    'directory_created' => $directoryCreated,
112                ],
113            );
114        }
115
116        return $this->success(
117            'Agents synchronization completed successfully.',
118            $input,
119            [
120                'packaged_agents_path' => $packageAgentsPath,
121                'agents_dir' => $agentsDir,
122                'directory_created' => $directoryCreated,
123            ],
124        );
125    }
126}