Skip to content

Commit 3c0490b

Browse files
authored
refactor: reorganize commands into Console namespace with dependency injection (#42)
* refactor: reorganize commands into Console namespace with dependency injection * Refactor tests and enhance coverage for various commands and components - Simplified command instantiation in CopyLicenseCommandTest and DocsCommandTest. - Improved test structure and readability in GitAttributesCommandTest and PhpDocCommandTest. - Updated ReportsCommandTest to remove unnecessary command mocks. - Enhanced TestsCommandTest and WikiCommandTest with ComposerJson mocking. - Introduced ComposerJsonTest to validate ComposerJson accessors and behavior. - Added DevToolsCommandLoaderTest to ensure only instantiable commands are registered. - Refactored DevToolsTest to utilize CommandLoaderInterface for command management. - Enhanced PlaceholderResolverTest and ReaderTest with ClockInterface for date handling. - Added JoliNotifExecutionFinishedSubscriberTest to validate notification behavior on test execution. - Introduced SystemClockTest to verify current date-time retrieval. - Added ContainerTest to validate static container behavior and configuration loading. Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: restructure command handling and implement service provider for dependency injection Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: improve container initialization check and enhance DevToolsServiceProvider documentation Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: enhance documentation for ComposerJson, DevToolsCommandLoader, SystemClock, and DevToolsServiceProvider classes Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: format AsCommand attributes for DependenciesCommand Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: improve documentation for ComposerJson parameter in GitAttributesCommand constructor Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: improve documentation for logger parameter in SkillsSynchronizer constructor Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: enhance constructor documentation for PhpDocCommand Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: format AsCommand attributes in RefactorCommand Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: improve constructor documentation for WikiCommand Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: improve documentation for DevToolsCommandLoader class Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: improve constructor documentation for PlaceholderResolver class Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> * refactor: melhorar a documentação do construtor da classe Reader Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com> --------- Signed-off-by: Felipe Sayão Lobato Abreu <github@mentordosnerds.com>
1 parent bb8eb14 commit 3c0490b

File tree

59 files changed

+1516
-841
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1516
-841
lines changed

bin/dev-tools.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818

1919
namespace FastForward\DevTools;
2020

21+
use FastForward\DevTools\Console\DevTools;
2122
use Symfony\Component\Console\Input\ArgvInput;
2223

2324
$projectVendorAutoload = \dirname(__DIR__, 4) . '/vendor/autoload.php';
2425
$pluginVendorAutoload = \dirname(__DIR__) . '/vendor/autoload.php';
2526

2627
require_once file_exists($projectVendorAutoload) ? $projectVendorAutoload : $pluginVendorAutoload;
2728

28-
$application = new DevTools();
29-
$application->run(new ArgvInput([...$argv, '--no-plugins']));
29+
DevTools::create()->run(new ArgvInput([...$argv, '--no-plugins']));

composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"php": "^8.3",
2828
"composer-plugin-api": "^2.0",
2929
"composer/composer": "^2.9",
30+
"container-interop/service-provider": "^0.4.1",
3031
"dg/bypass-finals": "^1.9",
3132
"ergebnis/composer-normalize": "^2.50",
3233
"ergebnis/rector-rules": "^1.14",
@@ -36,11 +37,13 @@
3637
"icanhazstring/composer-unused": "^0.9.6",
3738
"jolicode/jolinotif": "^3.3",
3839
"nikic/php-parser": "^5.7",
40+
"php-di/php-di": "^7.1",
3941
"phpdocumentor/shim": "^3.9",
4042
"phpro/grumphp": "^2.19",
4143
"phpspec/prophecy": "^1.26",
4244
"phpspec/prophecy-phpunit": "^2.5",
4345
"phpunit/phpunit": "^12.5",
46+
"psr/clock": "^1.0",
4447
"psr/log": "^3.0",
4548
"pyrech/composer-changelogs": "^2.2",
4649
"rector/rector": "^2.3",

docs/advanced/consumer-automation.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,5 @@ Producer Impact
5252

5353
Any change to ``resources/github-actions``, ``resources/dependabot.yml``,
5454
``.agents/skills``, ``.github/workflows``, or
55-
``FastForward\DevTools\Command\SyncCommand`` changes the default onboarding
55+
``FastForward\DevTools\Console\Command\SyncCommand`` changes the default onboarding
5656
story for every consumer library.

docs/api/commands.rst

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Command Classes
22
===============
33

44
All public CLI commands extend
5-
``FastForward\DevTools\Command\AbstractCommand``, which provides path
5+
``FastForward\DevTools\Console\Command\AbstractCommand``, which provides path
66
resolution, configuration fallback, PSR-4 lookup, and child-command dispatch.
77

88
.. list-table::
@@ -11,47 +11,47 @@ resolution, configuration fallback, PSR-4 lookup, and child-command dispatch.
1111
* - Class
1212
- CLI command
1313
- Responsibility
14-
* - ``FastForward\DevTools\Command\AbstractCommand``
14+
* - ``FastForward\DevTools\Console\Command\AbstractCommand``
1515
- n/a
1616
- Shared helpers for path resolution, packaged fallback files, PSR-4
1717
discovery, and subcommand execution.
18-
* - ``FastForward\DevTools\Command\StandardsCommand``
18+
* - ``FastForward\DevTools\Console\Command\StandardsCommand``
1919
- ``standards``
2020
- Runs the full quality pipeline.
21-
* - ``FastForward\DevTools\Command\RefactorCommand``
21+
* - ``FastForward\DevTools\Console\Command\RefactorCommand``
2222
- ``refactor``
2323
- Runs Rector with local or packaged configuration.
24-
* - ``FastForward\DevTools\Command\PhpDocCommand``
24+
* - ``FastForward\DevTools\Console\Command\PhpDocCommand``
2525
- ``phpdoc``
2626
- Runs PHP-CS-Fixer and a focused Rector PHPDoc pass.
27-
* - ``FastForward\DevTools\Command\CodeStyleCommand``
27+
* - ``FastForward\DevTools\Console\Command\CodeStyleCommand``
2828
- ``code-style``
2929
- Runs Composer Normalize and ECS.
30-
* - ``FastForward\DevTools\Command\TestsCommand``
30+
* - ``FastForward\DevTools\Console\Command\TestsCommand``
3131
- ``tests``
3232
- Runs PHPUnit with optional coverage output.
33-
* - ``FastForward\DevTools\Command\DependenciesCommand``
33+
* - ``FastForward\DevTools\Console\Command\DependenciesCommand``
3434
- ``dependencies``
3535
- Reports missing and unused Composer dependencies.
36-
* - ``FastForward\DevTools\Command\DocsCommand``
36+
* - ``FastForward\DevTools\Console\Command\DocsCommand``
3737
- ``docs``
3838
- Builds the HTML documentation site.
39-
* - ``FastForward\DevTools\Command\WikiCommand``
39+
* - ``FastForward\DevTools\Console\Command\WikiCommand``
4040
- ``wiki``
4141
- Builds Markdown API documentation.
42-
* - ``FastForward\DevTools\Command\ReportsCommand``
42+
* - ``FastForward\DevTools\Console\Command\ReportsCommand``
4343
- ``reports``
4444
- Combines the documentation build with coverage generation.
45-
* - ``FastForward\DevTools\Command\SkillsCommand``
45+
* - ``FastForward\DevTools\Console\Command\SkillsCommand``
4646
- ``skills``
4747
- Synchronizes packaged agent skills into ``.agents/skills``.
48-
* - ``FastForward\DevTools\Command\SyncCommand``
48+
* - ``FastForward\DevTools\Console\Command\SyncCommand``
4949
- ``dev-tools:sync``
5050
- Synchronizes consumer-facing scripts, automation assets, and packaged
5151
skills.
52-
* - ``FastForward\DevTools\Command\GitIgnoreCommand``
52+
* - ``FastForward\DevTools\Console\Command\GitIgnoreCommand``
5353
- ``gitignore``
5454
- Merges and synchronizes .gitignore files.
55-
* - ``FastForward\DevTools\Command\CopyLicenseCommand``
55+
* - ``FastForward\DevTools\Console\Command\CopyLicenseCommand``
5656
- ``license``
5757
- Generates a LICENSE file from composer.json license information.

docs/configuration/overriding-defaults.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ without forking the whole package.
77
Resolution Order
88
----------------
99

10-
``FastForward\DevTools\Command\AbstractCommand::getConfigFile()`` resolves
10+
``FastForward\DevTools\Console\Command\AbstractCommand::getConfigFile()`` resolves
1111
configuration in this order:
1212

1313
1. Check whether the file exists in the current working directory.

docs/faq.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ after deleting a packaged skill link locally.
3333
Why does ``code-style`` touch ``composer.lock``?
3434
------------------------------------------------
3535

36-
Because ``FastForward\DevTools\Command\CodeStyleCommand`` always runs
36+
Because ``FastForward\DevTools\Console\Command\CodeStyleCommand`` always runs
3737
``composer update --lock --quiet`` before Composer Normalize and ECS.
3838

3939
Where did ``.docheader`` come from?
4040
-----------------------------------
4141

42-
``FastForward\DevTools\Command\PhpDocCommand`` creates it automatically when it
42+
``FastForward\DevTools\Console\Command\PhpDocCommand`` creates it automatically when it
4343
is missing. The template comes from the packaged file and is rewritten with the
4444
current package name when possible.
4545

docs/internals/architecture.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Local Command Lifecycle
1616
is given.
1717
5. Individual commands resolve local configuration first and packaged
1818
fallbacks second through
19-
``FastForward\DevTools\Command\AbstractCommand::getConfigFile()``.
19+
``FastForward\DevTools\Console\Command\AbstractCommand::getConfigFile()``.
2020

2121
Consumer Synchronization Lifecycle
2222
----------------------------------
@@ -27,31 +27,31 @@ Consumer Synchronization Lifecycle
2727
``FastForward\DevTools\Composer\Capability\DevToolsCommandProvider``.
2828
4. After ``composer install`` or ``composer update``, the plugin runs
2929
``vendor/bin/dev-tools dev-tools:sync``.
30-
5. ``FastForward\DevTools\Command\SyncCommand`` updates scripts, GitHub
30+
5. ``FastForward\DevTools\Console\Command\SyncCommand`` updates scripts, GitHub
3131
workflow stubs, ``.editorconfig``, ``dependabot.yml``, ``.gitignore``, and
3232
the wiki submodule in the consumer repository.
33-
6. ``FastForward\DevTools\Command\SkillsCommand`` synchronizes packaged skill
33+
6. ``FastForward\DevTools\Console\Command\SkillsCommand`` synchronizes packaged skill
3434
links into the consumer ``.agents/skills`` directory.
3535
7. ``FastForward\DevTools\Agent\Skills\SkillsSynchronizer`` creates missing
3636
links, repairs broken ones, and preserves consumer-owned directories.
3737

3838
Documentation Pipeline
3939
----------------------
4040

41-
1. ``FastForward\DevTools\Command\DocsCommand`` reads PSR-4 paths from
41+
1. ``FastForward\DevTools\Console\Command\DocsCommand`` reads PSR-4 paths from
4242
``composer.json``.
4343
2. It generates a temporary ``phpdocumentor.xml`` file in
4444
``tmp/cache/phpdoc``.
4545
3. phpDocumentor builds API pages from those PSR-4 paths.
4646
4. phpDocumentor also builds the guide from the selected ``docs/`` source
4747
directory.
48-
5. ``FastForward\DevTools\Command\ReportsCommand`` combines that
48+
5. ``FastForward\DevTools\Console\Command\ReportsCommand`` combines that
4949
documentation build with PHPUnit coverage generation.
5050

5151
Key Abstraction
5252
---------------
5353

54-
``FastForward\DevTools\Command\AbstractCommand`` is the main shared layer. It
54+
``FastForward\DevTools\Console\Command\AbstractCommand`` is the main shared layer. It
5555
centralizes:
5656

5757
- current working directory detection;

src/Agent/Skills/SkillsSynchronizer.php

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@
1919
namespace FastForward\DevTools\Agent\Skills;
2020

2121
use Psr\Log\LoggerAwareInterface;
22-
use Psr\Log\LoggerAwareTrait;
23-
use Psr\Log\NullLogger;
22+
use Psr\Log\LoggerInterface;
2423
use Symfony\Component\Filesystem\Filesystem;
2524
use Symfony\Component\Finder\Finder;
2625
use Symfony\Component\Filesystem\Path;
@@ -34,21 +33,25 @@
3433
*/
3534
final class SkillsSynchronizer implements LoggerAwareInterface
3635
{
37-
use LoggerAwareTrait;
38-
3936
/**
40-
* Initializes the synchronizer with an optional filesystem instance.
41-
*
42-
* If no filesystem is provided, a default {@see Filesystem} instance is created.
37+
* Initializes the synchronizer with a filesystem and finder instance.
4338
*
44-
* @param Filesystem|null $filesystem Filesystem instance for file operations
39+
* @param Filesystem $filesystem Filesystem instance for file operations
4540
* @param Finder $finder Finder instance for locating skill directories in the package
41+
* @param LoggerInterface $logger Logger for recording synchronization actions and decisions
4642
*/
4743
public function __construct(
48-
private readonly Filesystem $filesystem = new Filesystem(),
49-
private readonly Finder $finder = new Finder(),
50-
) {
51-
$this->logger = new NullLogger();
44+
private readonly Filesystem $filesystem,
45+
private readonly Finder $finder,
46+
private LoggerInterface $logger,
47+
) {}
48+
49+
/**
50+
* {@inheritDoc}
51+
*/
52+
public function setLogger(LoggerInterface $logger): void
53+
{
54+
$this->logger = $logger;
5255
}
5356

5457
/**

src/Composer/Capability/DevToolsCommandProvider.php

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,54 +18,24 @@
1818

1919
namespace FastForward\DevTools\Composer\Capability;
2020

21-
use FastForward\DevTools\Command\AbstractCommand;
22-
use Composer\Plugin\Capability\CommandProvider as CommandProviderCapability;
23-
use FastForward\DevTools\Command\CodeStyleCommand;
24-
use FastForward\DevTools\Command\CopyLicenseCommand;
25-
use FastForward\DevTools\Command\DependenciesCommand;
26-
use FastForward\DevTools\Command\DocsCommand;
27-
use FastForward\DevTools\Command\GitAttributesCommand;
28-
use FastForward\DevTools\Command\GitIgnoreCommand;
29-
use FastForward\DevTools\Command\PhpDocCommand;
30-
use FastForward\DevTools\Command\RefactorCommand;
31-
use FastForward\DevTools\Command\ReportsCommand;
32-
use FastForward\DevTools\Command\StandardsCommand;
33-
use FastForward\DevTools\Command\TestsCommand;
34-
use FastForward\DevTools\Command\WikiCommand;
35-
use FastForward\DevTools\Command\SyncCommand;
36-
use FastForward\DevTools\Command\SkillsCommand;
21+
use Composer\Command\BaseCommand;
22+
use Composer\Plugin\Capability\CommandProvider;
23+
use FastForward\DevTools\Console\DevTools;
3724

3825
/**
3926
* Provides a registry of custom dev-tools commands mapped for Composer integration.
40-
* This capability struct MUST implement the defined `CommandProviderCapability`.
27+
* This capability struct MUST implement the defined `CommandProvider`.
4128
*/
42-
final class DevToolsCommandProvider implements CommandProviderCapability
29+
final class DevToolsCommandProvider implements CommandProvider
4330
{
4431
/**
45-
* Dispatches the comprehensive collection of CLI commands.
46-
*
47-
* The method MUST yield an array of instantiated command classes representing the tools.
48-
* It SHALL be queried by the Composer plugin dynamically during runtime execution.
49-
*
50-
* @return array<int, AbstractCommand> the commands defined within the toolset
32+
* {@inheritDoc}
5133
*/
5234
public function getCommands()
5335
{
54-
return [
55-
new CodeStyleCommand(),
56-
new RefactorCommand(),
57-
new TestsCommand(),
58-
new DependenciesCommand(),
59-
new PhpDocCommand(),
60-
new DocsCommand(),
61-
new StandardsCommand(),
62-
new ReportsCommand(),
63-
new WikiCommand(),
64-
new SyncCommand(),
65-
new GitIgnoreCommand(),
66-
new GitAttributesCommand(),
67-
new SkillsCommand(),
68-
new CopyLicenseCommand(),
69-
];
36+
return array_values(array_filter(
37+
DevTools::create()->all(),
38+
static fn(object $command): bool => $command instanceof BaseCommand,
39+
));
7040
}
7141
}

0 commit comments

Comments
 (0)