Skip to documentation

Specialized Commands

Use the standalone commands when you want one tool instead of the full standards pipeline.

External Changelog CLI

Run the independent Fast Forward Changelog 0.2.0 CLI through cpx --skip-local . CPX and PHP 8.5 must be available on its execution path; the consumer's PHP 8.3 requirement stays unchanged.

cpx --skip-local fast-forward/changelog:0.2.0 add "Fixes release-note rendering." --category=fixed --no-interaction
cpx --skip-local fast-forward/changelog:0.2.0 check --no-interaction
cpx --skip-local fast-forward/changelog:0.2.0 status --source=tags --no-interaction

Contributions use independent .changelog/*.md files. Inspect external command help for its options and output contracts. See External Fast Forward Changelog for runtime requirements and release-preview boundaries.

tests

Runs PHPUnit with the resolved phpunit.xml .

composer tests
composer tests -- --filter=EventTracerTest

Important details:

  • local phpunit.xml is preferred over the packaged default;
  • --coverage=<path> creates HTML, Testdox, Clover, and raw coverage output;
  • --coverage-summary keeps coverage text output to PHPUnit's summary;
  • cache stays enabled by default; --cache forces it on and --no-cache forces it off for a single run;
  • when --cache-dir is omitted, PHPUnit keeps its default cache directory;
  • --cache-dir only affects PHPUnit's result cache when caching is enabled;
  • progress output is disabled by default;
  • --progress re-enables PHPUnit progress output in text mode;
  • --json and --pretty-json still suppress PHPUnit progress output automatically;
  • --pretty-json stays valid JSON and does not add ANSI color escapes;
  • in agent-driven runs, the command also captures PHPUnit output in structured mode automatically and stores the bundled PHPUnit agent-reporter payload in output . --json and --pretty-json therefore keep the same structured shape, with raw_output preserved under output when PHPUnit writes extra text before the final JSON;
  • the packaged configuration registers the DevTools PHPUnit extension.

dependencies

Analyzes missing, unused, misplaced, and outdated Composer dependencies.

composer dependencies
composer dependencies --max-outdated=10
composer dependencies --max-outdated=-1
composer dependencies --dev
composer dependencies --dump-usage=symfony/console
composer dependencies --show-shadow-dependencies
composer dependencies --upgrade --dev

Important details:

  • it ships shipmonk/composer-dependency-analyser and rector/swiss-knife as direct dependencies of fast-forward/dev-tools ;
  • it uses composer-dependency-analyser for missing, unused, and misplaced dependency checks, with a packaged config that consumer repositories can override locally;
  • --dump-usage=<package> forwards to composer-dependency-analyser --dump-usages <package> --show-all-usages ;
  • --show-shadow-dependencies keeps shadow dependency findings visible for audits; without it, DevTools hides intentional Fast Forward dependency-group shadows so CI does not fail on ecosystem or meta packages that deliberately install related dependencies for consumers;
  • it uses swiss-knife breakpoint --limit=<max-outdated> to fail when too many outdated dependencies accumulate;
  • --max-outdated=-1 keeps the Rector Swiss Knife outdated report in the output but ignores Rector Swiss Knife's failure so only dependency-analyser findings fail the command;
  • the packaged tests.yml workflow uses --max-outdated=-1 by default, so dependency health stays required in CI while outdated-package counts are reported without failing the workflow on their own;
  • it previews swiss-knife raise-to-installed and swiss-knife open-versions before the analyzers;
  • --upgrade runs swiss-knife raise-to-installed , swiss-knife open-versions , composer update -W , and composer normalize before the analyzers;
  • it returns a non-zero exit code when missing, unused, misplaced, or too many outdated dependencies are found.

metrics

Analyzes code metrics with PhpMetrics.

composer metrics
composer metrics --target=.dev-tools/metrics
FAST_FORWARD_WORKSPACE_DIR=.artifacts composer metrics
composer --working-dir=packages/example metrics

Important details:

  • it ships phpmetrics/phpmetrics as a direct dependency of fast-forward/dev-tools ;
  • when invoked through Composer, you MAY use Composer's inherited --working-dir option to analyze another checkout without changing directories first;
  • --target stores the HTML report plus report.json and report-summary.json in the same directory for CI artifacts or manual review;
  • when --target is omitted, metrics output is written under the selected DevTools workspace, usually .dev-tools/metrics ;
  • --json and --pretty-json keep the top-level DevTools response structured while forwarding JSON or quieter modes to the wrapped tools where available;
  • it suppresses deprecation notices emitted by the PhpMetrics dependency itself so the command output stays readable;
  • it keeps PhpMetrics' Composer analysis enabled so report generation includes root package metadata, while default exclusions keep nested fixture projects out of that Composer scan;
  • it limits PhpMetrics' per-package Packagist socket wait so package freshness enrichment cannot leave report generation stuck indefinitely.

code-style

Runs Composer Normalize and ECS.

composer code-style
composer code-style --fix

Important details:

  • it always executes composer update --lock --quiet first;
  • without --fix , Composer Normalize runs in --dry-run mode;
  • ECS uses local ecs.php when present, otherwise the packaged fallback;
  • progress output is disabled by default; --progress re-enables it for text mode;
  • --json and --pretty-json forward JSON mode to ECS and suppress its progress bar.

refactor

Runs Rector against the current project.

composer refactor --fix

Important details:

  • without --fix , Rector runs in dry-run mode;
  • local rector.php is preferred when present;
  • the packaged default includes Fast Forward custom Rector rules plus shared Rector sets;
  • progress output is disabled by default; --progress re-enables it for text mode;
  • --json and --pretty-json forward --output-format json to Rector and disable its progress bar.

phpdoc

Coordinates PHP-CS-Fixer and a focused Rector pass for missing method PHPDoc.

composer phpdoc
composer phpdoc --fix

Important details:

  • it creates .docheader from the packaged template when the file is missing;
  • it uses .php-cs-fixer.dist.php and rector.php through the same local-first fallback logic;
  • the Rector phase explicitly runs FastForward\DevTools\Rector\AddMissingMethodPhpDocRector ;
  • cache stays enabled by default; --cache forces it on and --no-cache forces it off for the PHP-CS-Fixer phase;
  • when --cache-dir is omitted, PHP-CS-Fixer keeps its default cache directory;
  • --cache-dir only affects PHP-CS-Fixer when caching is enabled;
  • progress output is disabled by default; --progress re-enables it for text mode;
  • --json and --pretty-json switch PHP-CS-Fixer to JSON output with progress disabled and run the Rector phase in JSON mode without its progress bar.

docs

Builds the HTML documentation site with phpDocumentor.

composer docs --source=docs --target=.dev-tools

Important details:

  • docs/ must exist unless you pass another --source directory;
  • API pages are built from the PSR-4 paths declared in composer.json ;
  • guide pages are built from the selected source directory;
  • --template defaults to vendor/fast-forward/phpdoc-bootstrap-template ;
  • cache stays enabled by default; --cache forces it on and --no-cache forces it off for a single run;
  • when --cache-dir is omitted, phpDocumentor keeps its default cache directory;
  • --cache-dir only affects phpDocumentor when caching is enabled;
  • progress output is disabled by default; --progress re-enables it for text mode;
  • --json and --pretty-json also disable phpDocumentor's progress output.

wiki

Builds Markdown API pages for a GitHub wiki.

composer wiki

Important details:

  • the default output directory is .github/wiki ;
  • normal dev-tools:sync and the direct Wiki workflow explicitly use .dev-tools/wiki-generated without initializing a submodule;
  • --init remains an explicit legacy option for submodule users;
  • it uses the Markdown template from vendor/saggre/phpdocumentor-markdown/themes/markdown ;
  • cache stays enabled by default; --cache forces it on and --no-cache forces it off for a single run;
  • when --cache-dir is omitted, phpDocumentor keeps its default cache directory;
  • --cache-dir only affects phpDocumentor when caching is enabled;
  • it is especially useful together with the reusable wiki workflow.

reports

Runs the documentation and test-report pipeline used by GitHub Pages.

composer reports

Important details:

  • it calls docs , tests --coverage , and metrics with defaults rooted in the selected DevTools workspace;
  • with the default workspace, that is equivalent to docs --target .dev-tools , tests --coverage .dev-tools/coverage --coverage-summary , and metrics --target .dev-tools/metrics --junit .dev-tools/coverage/junit.xml ;
  • docs remains detached, while tests and metrics run in sequence so PhpMetrics can reuse the JUnit report generated by PHPUnit;
  • cache stays enabled by default for the nested docs and tests steps; --cache forces that explicit intent on and --no-cache forces it off;
  • when --cache-dir is omitted, nested tools keep their own default cache directories;
  • progress output stays disabled by default across the nested steps, and --progress re-enables it for human-readable runs;
  • --json and --pretty-json are propagated to each subprocess, while their progress output is suppressed where supported;
  • human-readable runs keep nested command output grouped with concise local section boundaries, pass color-friendly environment variables to subprocesses, and forward explicit ANSI flags to Symfony Console tools;
  • queued subprocesses run with XDEBUG_MODE=off when Xdebug is loaded but the command does not need Xdebug for coverage, or when PCOV can provide coverage instead;
  • it is the reporting stage used by standards .

skills

Synchronizes packaged agent skills into the consumer repository.

composer skills

Important details:

  • it verifies the packaged .agents/skills directory before doing any work;
  • it creates the consumer .agents/skills directory when missing;
  • it creates missing symlinks and repairs broken ones;
  • it preserves an existing non-symlink directory instead of overwriting it.

agents

Synchronizes packaged project-agent prompts into the consumer repository.

composer agents

Important details:

  • it verifies the packaged .agents/agents directory before doing any work;
  • it creates the consumer .agents/agents directory when missing;
  • it creates missing symlinks and repairs broken ones;
  • it preserves an existing non-symlink directory instead of overwriting it;
  • it uses the same generic synchronization rules as skills through FastForward\\DevTools\\Sync\\PackagedDirectorySynchronizer .

funding

Synchronizes supported funding metadata between Composer and GitHub formats.

composer funding
composer funding --dry-run
composer funding --check

Important details:

  • it keeps composer.json funding entries and .github/FUNDING.yml in sync for GitHub Sponsors and custom URLs;
  • it preserves unsupported Composer funding providers and unsupported YAML keys instead of rewriting them;
  • it creates .github/FUNDING.yml when Composer already declares supported funding metadata;
  • it supports --dry-run , --check , and --interactive so funding drift can be surfaced in CI and reviewed locally.

codeowners

Generates managed CODEOWNERS files from repository metadata.

composer codeowners
composer codeowners --dry-run
composer codeowners --interactive

Important details:

  • it inspects composer.json author homepages to infer GitHub handles for .github/CODEOWNERS ;
  • when direct ownership cannot be inferred, it renders a commented fallback instead of copying hard-coded owners into the consumer repository;
  • --interactive lets maintainers provide explicit owners before writing the catch-all * rule;
  • dev-tools:sync runs codeowners automatically alongside the other consumer bootstrap steps.

dev-tools:sync

Synchronizes consumer-facing automation and defaults.

composer dev-tools:sync

Important details:

  • it updates composer.json scripts and removes only deprecated DevTools-managed extra.grumphp.config-default-path values;
  • it calls funding so supported funding metadata stays aligned between composer.json and .github/FUNDING.yml ;
  • it copies missing workflow stubs, .editorconfig , and dependabot.yml ;
  • it calls codeowners to generate .github/CODEOWNERS from local metadata;
  • in normal mode it generates local API Markdown in .dev-tools/wiki-generated without creating a Git submodule;
  • it calls gitignore to merge the canonical .gitignore with the project's .gitignore;
  • it calls gitattributes to manage export-ignore rules in .gitattributes;
  • it refreshes packaged Git hooks that prefer a local grumphp.yml override and otherwise use a project-relative reference to the active packaged DevTools grumphp.yml path resolved when sync installs them;
  • it calls skills so .agents/skills contains links to the packaged skill set;
  • it calls agents so .agents/agents contains links to the packaged project-agent set.

gitattributes

Manages .gitattributes export-ignore rules for leaner Composer package archives.

composer gitattributes

Important details:

  • it adds export-ignore entries for repository-only files and directories;
  • it only adds entries for paths that actually exist in the repository;
  • it respects the extra.gitattributes.keep-in-export configuration to keep specific paths in exported archives;
  • it preserves existing custom .gitattributes rules;
  • it deduplicates equivalent entries and sorts them with directories before files, then alphabetically;
  • it uses CandidateProvider, ExistenceChecker, ExportIgnoreFilter, Merger, Reader, and Writer components from the GitAttributes namespace.

gitignore

Merges and synchronizes .gitignore files.

composer gitignore --source=/path/to/source/.gitignore --target=/path/to/target/.gitignore

Important details:

  • it reads the canonical .gitignore from dev-tools and merges with the project's existing .gitignore;
  • by default, the source is the packaged .gitignore and the target is the project's root .gitignore;
  • duplicates are removed and entries are sorted alphabetically;
  • it uses the Reader, Merger, and Writer components from the GitIgnore namespace.

license

Generates a LICENSE file from composer.json license information.

composer license

Important details:

  • it reads the license field from composer.json ;
  • it supports common open-source licenses (MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, GPL-3.0, LGPL-3.0, and MPL-2.0);
  • it resolves placeholders such as [year] , [author] , and [project] using information from composer.json ;
  • it uses template files from resources/license-templates/ ;
  • it skips generation if a LICENSE file already exists.

copy-resource

Copies packaged or local resources into the consumer repository.

composer copy-resource --source <path> --target <path> --overwrite

Important details:

  • source is resolved using FileLocatorInterface ;
  • target is resolved to an absolute path using FilesystemInterface ;
  • both --source and --target are required options;
  • without --overwrite , existing target files are skipped;
  • supports both files and directories as sources.

git-hooks

Installs packaged Fast Forward Git hooks.

composer git-hooks

Important details:

  • copies hook files from source to target directory;
  • sets executable permissions on copied hooks with 0o755 ;
  • removes an existing drifted hook before recopying it so stale target permissions do not block replacements;
  • --source defaults to resources/git-hooks ;
  • --target defaults to .git/hooks ;
  • --no-overwrite preserves existing hook files.

update-composer-json

Updates composer.json with Fast Forward dev-tools scripts and metadata.

composer update-composer-json --file=composer.json

Important details:

  • adds dev-tools script entrypoint to composer.json;
  • adds dev-tools:fix script for automated fixing;
  • removes only deprecated DevTools-managed extra.grumphp.config-default-path values;
  • if the target file does not exist, exits silently with code 0;
  • existing scripts with the same name are overwritten;
  • preserves consumer-owned GrumPHP settings.
Search results