-
Notifications
You must be signed in to change notification settings - Fork 0
CLI Package Internals
php-upgrade-preflight/cli provides the framework-neutral upgrade-intel executable. It owns command syntax, adapter discovery, request construction, and output delivery. Core owns analysis.
Composer exposes bin/upgrade-intel. The script looks for an autoloader in this order:
- Composer's
_composer_autoload_pathglobal, when supplied; - the monorepo root
vendor/autoload.phplayout; - a nearby
autoload.phplayout; - the package-local
vendor/autoload.phplayout.
If none exists, it prints Unable to find Composer autoload.php. to standard error and exits 1.
vendor/bin/upgrade-intel analyze --target=vendor/package:^2.0 [options]
vendor/bin/upgrade-intel analyze --target-platform-profile=platform.json [options]The literal analyze command is required. -h and --help are recognized before ordinary parsing.
CommandLineOptions::all() is the single source for accepted option names, parse modes, defaults, and help text.
| Option | Repeatable | Default | Meaning |
|---|---|---|---|
--path=PATH |
No | Current directory | Project root to analyze |
--target=PACKAGE:VALUE |
Yes | Empty | Composer package target; php:VERSION is normalized specially |
--target-php=VERSION |
No | None | Exact simulated PHP value |
--target-platform-profile=PATH |
No | None | JSON target platform profile |
--from-php=VALUE |
No | None | Exact current PHP evidence for staged reasoning |
--with-extension=EXT[:VERSION] |
Yes | Empty | Assume an extension is present, optionally at a version |
--without-extension=EXT |
Yes | Empty | Assume an extension is absent |
--source=PATH |
Yes | Empty | Add a project-contained source path |
--framework=NAME |
Yes | Empty | Explicitly activate an installed adapter by name |
--format=json|markdown |
No | json |
Report writer |
--output=PATH |
No | Standard output | Write the rendered report to a validated destination |
--composer-mode=MODE |
No | compatible |
compatible or restricted
|
--composer-executable=PATH |
No | composer |
Composer command or executable path |
--composer-version=RANGE |
No | >=2.0.0 <3.0.0 |
Expected Composer version constraint |
--composer-timeout=SEC |
No | 300 |
Scenario timeout, validated by the model from 1 through 3600 |
--composer-diagnostic-timeout=SEC |
No | 60 |
Diagnostic timeout, validated by the model from 1 through 900 |
--debug |
No | Off | Preserve temporary Composer workspaces and expose debug paths |
-h, --help
|
No | — | Print help |
At least one package target, target PHP, or target-platform profile is required.
The parser accepts long values only as --name=value; it does not consume a following token as the value.
Correct:
vendor/bin/upgrade-intel analyze --target=phpunit/phpunit:^12.0Rejected:
vendor/bin/upgrade-intel analyze --target phpunit/phpunit:^12.0Single-valued options and flags are rejected when repeated. List options and extension assumptions are intentionally repeatable.
vendor/bin/upgrade-intel analyze \
--target=laravel/framework:^13.0 \
--target=laravel/passport:^13.0 \
--source=app \
--source=packages/Billing/srcUnknown options produce the generic Unknown option. diagnostic. A flag with a value, such as --debug=true, is rejected because --debug is valueless.
AnalyzeCommand converts parsed strings to:
-
UpgradeTargetvalues; - an optional
TargetPlatformProfileloaded from JSON; -
ExtensionAssumptionvalues; -
ComposerExecutionConfiguration; - one validated
UpgradeRequest.
The command validates an output destination before analysis starts. This avoids spending time on Composer scenarios only to discover that the requested report path is invalid.
| Exit code | CLI meaning |
|---|---|
0 |
A valid report was rendered or written, or help was printed |
1 |
Analysis or delivery failed unexpectedly |
2 |
Invocation was invalid |
A valid report whose resolution is blocked or unknown still exits 0. Consumers must inspect the JSON report status instead of translating the process exit code into upgrade readiness.
Example CI pattern:
vendor/bin/upgrade-intel analyze \
--path=. \
--target=laravel/framework:^12.0 \
--target-php=8.3 \
--format=json \
--output=build/upgrade-report.json
# Next, validate and inspect metadata.schema_version and resolution.status.FrameworkIntegrationRegistry enumerates installed Composer packages and asks AdapterManifestReader to inspect each package's composer.json.
An adapter package advertises classes like this:
{
"extra": {
"php-upgrade-preflight": {
"framework-adapters": [
"Vendor\\UpgradeAdapter\\FrameworkIntegration"
]
}
}
}The advertised value must be a non-empty JSON list. Every item must be a non-empty, trimmed class name. The registry also requires each loaded class to:
- exist and be instantiable;
- have no required constructor parameters;
- implement
FrameworkIntegration; - return a non-empty, trimmed integration name;
- avoid duplicate class and case-insensitive integration-name registrations.
Healthy integrations are sorted case-insensitively by name, then by class name, giving stable discovery order.
Discovery is isolated per installed package. If one package has unreadable or invalid adapter metadata, the registry skips that package, keeps other integrations, and exposes a diagnostic on standard error.
This behavior differs for an explicit request:
vendor/bin/upgrade-intel analyze \
--target=laravel/framework:^12.0 \
--framework=laravelIf laravel is unavailable, the command fails validation. When adapter packages were skipped, the error names them and includes their manifest-read reasons so the missing adapter is diagnosable.
With no --framework, Core may activate installed adapters through project detection. With --framework=name, the requested named integration must be installed and available.
All command exceptions are written to standard error after SensitiveOutputRedactor::redact(). Reports go to standard output unless --output is supplied.
Operational messages use path-exposure policy. For example, a successful file write prints a safe path marker when the real path should not be exposed.
--debug is deliberately different: it preserves temporary workspaces for investigation. Those workspaces can contain copied Composer metadata and should be handled as potentially sensitive.
vendor/bin/upgrade-intel analyze --path=. --target-php=8.3vendor/bin/upgrade-intel analyze \
--path=. \
--target=symfony/console:^7.0 \
--from-php=8.1 \
--target-php=8.2 \
--format=markdownvendor/bin/upgrade-intel analyze \
--target=laravel/framework:^11.0 \
--target-php=8.2 \
--with-extension=curl:8.2.0 \
--without-extension=imagickvendor/bin/upgrade-intel analyze \
--target=vendor/package:^2.0 \
--composer-mode=restricted \
--composer-timeout=120 \
--composer-diagnostic-timeout=30Restricted mode can prevent network-backed resolution when artifacts are not already available. Treat that as an environment/evidence limitation, not automatically as a package blocker.
| Class | Responsibility |
|---|---|
CommandLineOption |
Immutable definition of one option |
CommandLineOptions |
Complete option vocabulary, defaults, modes, and help rendering |
CommandLineParser |
Shell-string validation and normalized option array |
AnalyzeCommand |
Request construction, delegation, rendering, exit codes |
AdapterManifestReader |
Strictly read one package's adapter metadata |
FrameworkIntegrationRegistry |
Enumerate, instantiate, sort, select, and diagnose adapters |
DefaultAnalyzerFactory |
Construct DefaultUpgradeAnalyzer with discovered integrations |
AnalyzerFactory |
Injection seam for alternate analyzer construction |
PHP Upgrade Preflight — common product and monorepo Wiki · Common repository
- Home
- Key Concepts
- Package Map
- Class and Service Index
- Getting Started
- CLI Reference
- Artisan Command
- Reading the Report
- Safety and Trust Boundaries
- Troubleshooting and FAQ
- Architecture Overview
- Core Package Guide
- Core Analysis Pipeline
- Core Service Reference
- Determinism and Evidence
- Report Schema
- CLI Package Internals
- Laravel Package Internals
- Test Adapters
- Writing a Framework Adapter
- Laravel Adapter Internals
- Contributing
- Roadmap and Status
- Tools Reference
- Quality and Release Tooling
- Release Wiki Strategy