Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bin/dev-tools.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

namespace FastForward\DevTools;

use FastForward\DevTools\Console\DevTools;
use Symfony\Component\Console\Input\ArgvInput;

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

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

$application = new DevTools();
$application->run(new ArgvInput([...$argv, '--no-plugins']));
DevTools::create()->run(new ArgvInput([...$argv, '--no-plugins']));
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"php": "^8.3",
"composer-plugin-api": "^2.0",
"composer/composer": "^2.9",
"container-interop/service-provider": "^0.4.1",
"dg/bypass-finals": "^1.9",
"ergebnis/composer-normalize": "^2.50",
"ergebnis/rector-rules": "^1.14",
Expand All @@ -36,11 +37,13 @@
"icanhazstring/composer-unused": "^0.9.6",
"jolicode/jolinotif": "^3.3",
"nikic/php-parser": "^5.7",
"php-di/php-di": "^7.1",
"phpdocumentor/shim": "^3.9",
"phpro/grumphp": "^2.19",
"phpspec/prophecy": "^1.26",
"phpspec/prophecy-phpunit": "^2.5",
"phpunit/phpunit": "^12.5",
"psr/clock": "^1.0",
"psr/log": "^3.0",
"pyrech/composer-changelogs": "^2.2",
"rector/rector": "^2.3",
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/consumer-automation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ Producer Impact

Any change to ``resources/github-actions``, ``resources/dependabot.yml``,
``.agents/skills``, ``.github/workflows``, or
``FastForward\DevTools\Command\SyncCommand`` changes the default onboarding
``FastForward\DevTools\Console\Command\SyncCommand`` changes the default onboarding
story for every consumer library.
30 changes: 15 additions & 15 deletions docs/api/commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Command Classes
===============

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

.. list-table::
Expand All @@ -11,47 +11,47 @@ resolution, configuration fallback, PSR-4 lookup, and child-command dispatch.
* - Class
- CLI command
- Responsibility
* - ``FastForward\DevTools\Command\AbstractCommand``
* - ``FastForward\DevTools\Console\Command\AbstractCommand``
- n/a
- Shared helpers for path resolution, packaged fallback files, PSR-4
discovery, and subcommand execution.
* - ``FastForward\DevTools\Command\StandardsCommand``
* - ``FastForward\DevTools\Console\Command\StandardsCommand``
- ``standards``
- Runs the full quality pipeline.
* - ``FastForward\DevTools\Command\RefactorCommand``
* - ``FastForward\DevTools\Console\Command\RefactorCommand``
- ``refactor``
- Runs Rector with local or packaged configuration.
* - ``FastForward\DevTools\Command\PhpDocCommand``
* - ``FastForward\DevTools\Console\Command\PhpDocCommand``
- ``phpdoc``
- Runs PHP-CS-Fixer and a focused Rector PHPDoc pass.
* - ``FastForward\DevTools\Command\CodeStyleCommand``
* - ``FastForward\DevTools\Console\Command\CodeStyleCommand``
- ``code-style``
- Runs Composer Normalize and ECS.
* - ``FastForward\DevTools\Command\TestsCommand``
* - ``FastForward\DevTools\Console\Command\TestsCommand``
- ``tests``
- Runs PHPUnit with optional coverage output.
* - ``FastForward\DevTools\Command\DependenciesCommand``
* - ``FastForward\DevTools\Console\Command\DependenciesCommand``
- ``dependencies``
- Reports missing and unused Composer dependencies.
* - ``FastForward\DevTools\Command\DocsCommand``
* - ``FastForward\DevTools\Console\Command\DocsCommand``
- ``docs``
- Builds the HTML documentation site.
* - ``FastForward\DevTools\Command\WikiCommand``
* - ``FastForward\DevTools\Console\Command\WikiCommand``
- ``wiki``
- Builds Markdown API documentation.
* - ``FastForward\DevTools\Command\ReportsCommand``
* - ``FastForward\DevTools\Console\Command\ReportsCommand``
- ``reports``
- Combines the documentation build with coverage generation.
* - ``FastForward\DevTools\Command\SkillsCommand``
* - ``FastForward\DevTools\Console\Command\SkillsCommand``
- ``skills``
- Synchronizes packaged agent skills into ``.agents/skills``.
* - ``FastForward\DevTools\Command\SyncCommand``
* - ``FastForward\DevTools\Console\Command\SyncCommand``
- ``dev-tools:sync``
- Synchronizes consumer-facing scripts, automation assets, and packaged
skills.
* - ``FastForward\DevTools\Command\GitIgnoreCommand``
* - ``FastForward\DevTools\Console\Command\GitIgnoreCommand``
- ``gitignore``
- Merges and synchronizes .gitignore files.
* - ``FastForward\DevTools\Command\CopyLicenseCommand``
* - ``FastForward\DevTools\Console\Command\CopyLicenseCommand``
- ``license``
- Generates a LICENSE file from composer.json license information.
2 changes: 1 addition & 1 deletion docs/configuration/overriding-defaults.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ without forking the whole package.
Resolution Order
----------------

``FastForward\DevTools\Command\AbstractCommand::getConfigFile()`` resolves
``FastForward\DevTools\Console\Command\AbstractCommand::getConfigFile()`` resolves
configuration in this order:

1. Check whether the file exists in the current working directory.
Expand Down
4 changes: 2 additions & 2 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ after deleting a packaged skill link locally.
Why does ``code-style`` touch ``composer.lock``?
------------------------------------------------

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

Where did ``.docheader`` come from?
-----------------------------------

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

Expand Down
12 changes: 6 additions & 6 deletions docs/internals/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Local Command Lifecycle
is given.
5. Individual commands resolve local configuration first and packaged
fallbacks second through
``FastForward\DevTools\Command\AbstractCommand::getConfigFile()``.
``FastForward\DevTools\Console\Command\AbstractCommand::getConfigFile()``.

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

Documentation Pipeline
----------------------

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

Key Abstraction
---------------

``FastForward\DevTools\Command\AbstractCommand`` is the main shared layer. It
``FastForward\DevTools\Console\Command\AbstractCommand`` is the main shared layer. It
centralizes:

- current working directory detection;
Expand Down
27 changes: 15 additions & 12 deletions src/Agent/Skills/SkillsSynchronizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
namespace FastForward\DevTools\Agent\Skills;

use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
use Psr\Log\LoggerInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Filesystem\Path;
Expand All @@ -34,21 +33,25 @@
*/
final class SkillsSynchronizer implements LoggerAwareInterface
{
use LoggerAwareTrait;

/**
* Initializes the synchronizer with an optional filesystem instance.
*
* If no filesystem is provided, a default {@see Filesystem} instance is created.
* Initializes the synchronizer with a filesystem and finder instance.
*
* @param Filesystem|null $filesystem Filesystem instance for file operations
* @param Filesystem $filesystem Filesystem instance for file operations
* @param Finder $finder Finder instance for locating skill directories in the package
* @param LoggerInterface $logger Logger for recording synchronization actions and decisions
*/
public function __construct(
private readonly Filesystem $filesystem = new Filesystem(),
private readonly Finder $finder = new Finder(),
) {
$this->logger = new NullLogger();
private readonly Filesystem $filesystem,
private readonly Finder $finder,
private LoggerInterface $logger,
) {}

/**
* {@inheritDoc}
*/
public function setLogger(LoggerInterface $logger): void
{
$this->logger = $logger;
}

/**
Expand Down
50 changes: 10 additions & 40 deletions src/Composer/Capability/DevToolsCommandProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,24 @@

namespace FastForward\DevTools\Composer\Capability;

use FastForward\DevTools\Command\AbstractCommand;
use Composer\Plugin\Capability\CommandProvider as CommandProviderCapability;
use FastForward\DevTools\Command\CodeStyleCommand;
use FastForward\DevTools\Command\CopyLicenseCommand;
use FastForward\DevTools\Command\DependenciesCommand;
use FastForward\DevTools\Command\DocsCommand;
use FastForward\DevTools\Command\GitAttributesCommand;
use FastForward\DevTools\Command\GitIgnoreCommand;
use FastForward\DevTools\Command\PhpDocCommand;
use FastForward\DevTools\Command\RefactorCommand;
use FastForward\DevTools\Command\ReportsCommand;
use FastForward\DevTools\Command\StandardsCommand;
use FastForward\DevTools\Command\TestsCommand;
use FastForward\DevTools\Command\WikiCommand;
use FastForward\DevTools\Command\SyncCommand;
use FastForward\DevTools\Command\SkillsCommand;
use Composer\Command\BaseCommand;
use Composer\Plugin\Capability\CommandProvider;
use FastForward\DevTools\Console\DevTools;

/**
* Provides a registry of custom dev-tools commands mapped for Composer integration.
* This capability struct MUST implement the defined `CommandProviderCapability`.
* This capability struct MUST implement the defined `CommandProvider`.
*/
final class DevToolsCommandProvider implements CommandProviderCapability
final class DevToolsCommandProvider implements CommandProvider
{
/**
* Dispatches the comprehensive collection of CLI commands.
*
* The method MUST yield an array of instantiated command classes representing the tools.
* It SHALL be queried by the Composer plugin dynamically during runtime execution.
*
* @return array<int, AbstractCommand> the commands defined within the toolset
* {@inheritDoc}
*/
public function getCommands()
{
return [
new CodeStyleCommand(),
new RefactorCommand(),
new TestsCommand(),
new DependenciesCommand(),
new PhpDocCommand(),
new DocsCommand(),
new StandardsCommand(),
new ReportsCommand(),
new WikiCommand(),
new SyncCommand(),
new GitIgnoreCommand(),
new GitAttributesCommand(),
new SkillsCommand(),
new CopyLicenseCommand(),
];
return array_values(array_filter(
DevTools::create()->all(),
static fn(object $command): bool => $command instanceof BaseCommand,
));
}
}
Loading
Loading