-
Notifications
You must be signed in to change notification settings - Fork 0
CLI Reference
The standalone executable is installed by php-upgrade-preflight/cli.
upgrade-intel analyze --target=package:constraint [options]
upgrade-intel analyze --target-platform-profile=PATH [options]
Use the Composer-generated launcher for your operating system:
vendor/bin/upgrade-intel --helpvendor\bin\upgrade-intel.bat --help- The
analyzesubcommand is required unless-hor--helpis present. - Value options use one token:
--name=value. -
--path /work/appis invalid; use--path=/work/app. -
--debugis a flag and must not have a value. - Scalar options may be supplied once.
- Repeatable options are
--target,--with-extension,--without-extension,--source, and--framework. - At least one
--target,--target-php, or--target-platform-profileis required. - Diagnostics go to stderr. The report goes to stdout unless
--outputis used.
| Option | Repeatable | Default | Meaning |
|---|---|---|---|
--path=PATH |
No | Current directory | Project directory to analyze |
--target=PACKAGE:VALUE |
Yes | None | Composer package target and constraint |
--target-php=VERSION |
No | None | Exact target PHP platform version |
--target-platform-profile=PATH |
No | None | Schema 1.0 JSON platform profile |
--from-php=VALUE |
No | None | Known exact current PHP version |
--with-extension=EXT[:VERSION] |
Yes | None | Model an extension as present, optionally at an exact version |
--without-extension=EXT |
Yes | None | Model an extension as absent |
--source=PATH |
Yes | Adapter/default paths | Additional file or directory inside the project |
--framework=NAME |
Yes | Auto-detection | Explicit installed framework adapter |
--format=json|markdown |
No | json |
Report writer |
--output=PATH |
No | stdout | Report file outside the project |
--composer-mode=compatible|restricted |
No | compatible |
Composer state and network policy |
--composer-executable=PATH |
No | composer |
Composer command or executable selection |
--composer-version=RANGE |
No | >=2.0.0 <3.0.0 |
Accepted Composer version constraint |
--composer-timeout=SEC |
No | 300 |
Scenario timeout, 1–3600 seconds |
--composer-diagnostic-timeout=SEC |
No | 60 |
Diagnostic timeout, 1–900 seconds |
--debug |
No | Off | Preserve workspaces and expose exact temporary paths |
-h, --help
|
No | — | Print help and return 0 |
--path must resolve to an existing directory. Relative paths are resolved from the command's current directory.
cd /work/tools
vendor/bin/upgrade-intel analyze --path=../legacy-app --target-php=8.2Set-Location C:\work\tools
vendor\bin\upgrade-intel.bat analyze --path=..\legacy-app --target-php=8.2Each --source must resolve to an existing file or directory inside the analyzed project. Relative source paths are project-relative. Duplicate normalized paths collapse.
vendor/bin/upgrade-intel analyze \
--path=/work/app \
--target-php=8.2 \
--source=app \
--source=tests/Featurevendor\bin\upgrade-intel.bat analyze `
--path=C:\work\app `
--target-php=8.2 `
--source=app `
--source=tests\FeatureA source path outside the project is rejected even if it exists.
--target splits at the first colon and validates the package name and Composer constraint.
--target=laravel/framework:^13.0
--target=laravel/passport:^12.0Repeat an identical package target if necessary; it collapses. Conflicting constraints for the same package are invalid.
--target-php accepts an exact major, major.minor, or major.minor.patch value. Values normalize to three components in the target set.
--target-php=8.3
--target=php:8.3These two PHP forms are equivalent. If both are supplied, they must normalize to the same exact value. A range such as --target-php=^8.3 is invalid because simulation needs a concrete platform value.
--from-php also accepts an exact major, major.minor, or major.minor.patch. It describes the current project for staging; it does not change the PHP interpreter running the analyzer.
Composer extension names use ext-name form.
vendor/bin/upgrade-intel analyze \
--path=/work/app \
--target-php=8.3 \
--with-extension=ext-curl:8.3.0 \
--with-extension=ext-json \
--without-extension=ext-xdebugvendor\bin\upgrade-intel.bat analyze `
--path=C:\work\app `
--target-php=8.3 `
--with-extension=ext-curl:8.3.0 `
--with-extension=ext-json `
--without-extension=ext-xdebugRules:
- exact versions and absences are written only to analyzer-owned temporary manifests;
- matching repeats collapse;
- different versions for one extension are contradictory;
- present and absent for one extension are contradictory;
- absence simulation requires Composer 2.2+;
- presence without a version uses a conservative sentinel and cannot prove a versioned constraint;
- a sentinel-related constraint failure becomes a non-blocking
extension-version-unknownadvisory; - unlisted extensions may still come from the analyzer host and are reported as host-dependent.
A profile inventories the deployment platform more broadly than named extension switches.
{
"schema_version": "1.0",
"completeness": "complete",
"packages": {
"php": "8.3.0",
"ext-curl": "8.3.0",
"ext-xdebug": false,
"lib-curl": "8.6.0",
"php-64bit": "8.3.0",
"composer-plugin-api": "2.6.0"
}
}vendor/bin/upgrade-intel analyze \
--path=/work/app \
--target=laravel/framework:^12.0 \
--target-platform-profile=/work/profiles/php-83-production.jsonvendor\bin\upgrade-intel.bat analyze `
--path=C:\work\app `
--target=laravel/framework:^12.0 `
--target-platform-profile=C:\work\profiles\php-83-production.jsonSupported names include php, ext-*, lib-*, PHP subtypes such as php-64bit, and Composer platform packages. Values are exact versions or false for verified absence.
Use partial when inventory is incomplete. Unlisted platform packages then remain host-dependent. Use complete only when every supported safely simulated class was considered and every unlisted value should be absent.
Complete profiles require Composer 2.2+. Composer 2.0 or 2.1 produces an operationally unknown result before workspace creation; the request is not silently weakened to partial.
Request values take precedence over the profile, which takes precedence over original config.platform. Equal request/profile values are accepted. Contradictions are rejected. A complete profile cannot be combined with a presence-only extension assumption.
Executable-bound values such as composer, composer-plugin-api, and composer-runtime-api are recorded as toolchain_bound; the analyzer does not claim that config.platform safely simulates them.
The CLI discovers installed adapters through Composer package metadata. With no --framework, every discovered adapter may run automatic detection.
vendor/bin/upgrade-intel analyze \
--path=/work/app \
--target=laravel/framework:^11.0 \
--framework=laravelExplicit names are case-insensitive and deduplicated. An unavailable explicit adapter is invalid input and returns exit code 2. A malformed unrelated installed adapter manifest is skipped with a stderr diagnostic; adapter class or name collisions fail analysis rather than selecting an arbitrary winner.
The Artisan entry point does not accept --framework; it always enables Laravel.
compatible is the default. Composer may inherit global config, authentication, proxy settings, cache, Git/SSH setup, and network access. Use it when private repositories need the normal host environment.
--composer-mode=compatibleEvidence from compatible mode depends on host state and is not cross-host reproducibility proof.
restricted uses fresh analyzer-owned Composer home, cache, and XDG roots; writes empty Composer config/auth files; scrubs controlled credential, proxy, and askpass variables; and requests best-effort offline behavior.
--composer-mode=restrictedIt is not an operating-system network sandbox. The selected executable, helper processes, system trust, and credentials embedded in project input remain boundaries. A fresh offline cache miss is repository_metadata_unavailable, an operational uncertainty, not a dependency blocker.
Scripts, plugins, installation, audit, interaction, and progress are disabled in both modes.
Choose a Composer executable without publishing its exact path in the report:
--composer-executable=/opt/composer/composer--composer-executable=C:\tools\composer\composer.batThe default expected range is Composer 2. A detected executable outside --composer-version stops scenario execution. Scenario and diagnostic timeouts are separate:
--composer-timeout=600 --composer-diagnostic-timeout=90The parser first requires digits; the configuration then enforces 1–3600 and 1–900. Note that the literal 0 contains digits but fails the allowed range.
Without --output, the report is written to stdout and diagnostics to stderr:
vendor/bin/upgrade-intel analyze --path=/work/app --target-php=8.2 > /tmp/report.jsonShell redirection happens before the analyzer validates a destination. Do not redirect stdout into the analyzed project.
Prefer --output, which validates that the destination is outside the project, is not a directory, and has an existing writable parent:
mkdir -p /work/reports
vendor/bin/upgrade-intel analyze --path=/work/app --target-php=8.2 --output=/work/reports/app.jsonNew-Item -ItemType Directory -Force C:\work\reports | Out-Null
vendor\bin\upgrade-intel.bat analyze --path=C:\work\app --target-php=8.2 --output=C:\work\reports\app.jsonOn success with --output, stdout contains a short “Wrote report” message rather than report JSON.
Never use $?, $LASTEXITCODE, or a CI step's green/red state as the upgrade verdict.
| Process code | Contract |
|---|---|
0 |
Help or a valid canonical report was produced |
1 |
Report production failed internally or operationally |
2 |
Invocation validation failed |
resolution.status |
Direct final-target meaning |
|---|---|
feasible |
Final target resolved with no package changes |
feasible_with_changes |
Final target resolved with candidate package changes |
blocked |
Composer blockers prevent final-target resolution |
unknown |
No reliable feasibility conclusion was reached |
The five-minute demo returns process code 0 while resolution.status is blocked.
For framework work, read three independent dimensions:
-
resolution.status— direct final-target Composer scenarios. -
transition.framework_guidance[].status— adapter rule-pack coverage. -
staged_resolution.execution_stateandstaged_resolution.status— adjacent-stage Composer chain.
--debug deliberately preserves temporary Composer workspaces and exposes exact temp_path values. Those workspaces contain copied manifests and possibly sensitive project input.
vendor/bin/upgrade-intel analyze --path=/work/app --target-php=8.2 --debugDebug reports and retained workspaces are non-shareable. Redaction remains active in rendered output, but it does not sanitize retained files on disk.
Multiple package targets:
vendor/bin/upgrade-intel analyze \
--path=/work/app \
--target=laravel/framework:^11.0 \
--target=laravel/passport:^11.0 \
--target-php=8.2 \
--framework=laravel \
--format=markdown \
--output=/work/reports/laravel-11.mdWindows equivalent:
vendor\bin\upgrade-intel.bat analyze `
--path=C:\work\app `
--target=laravel/framework:^11.0 `
--target=laravel/passport:^11.0 `
--target-php=8.2 `
--framework=laravel `
--format=markdown `
--output=C:\work\reports\laravel-11.mdRestricted PHP-only check:
vendor/bin/upgrade-intel analyze \
--path=/work/app \
--from-php=7.4 \
--target-php=8.1 \
--composer-mode=restricted \
--format=jsonPHP 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