Migrating from Composer¶
phast migrate converts an existing composer.json into a phast.toml. It is a
one-time conversion, not an ongoing sync: after migration, phast.toml is the single
source of truth and Phast neither reads nor writes composer.json again. This is the
same model UV used to replace pip, and it exists to avoid the split-brain state of two
manifests that can silently drift apart.
Run the migration¶
From the directory containing composer.json:
$ phast migrate
composer.json migrated to phast.toml. Run 'phast install' to install dependencies.
$ phast install
If a phast.toml already exists, the command aborts; pass --force to overwrite it.
The migration is non-destructive: composer.json and composer.lock are left exactly
as they were. Keep them around as long as you like, or remove them once the team has
switched; Phast does not care either way.
What is carried over¶
| composer.json | phast.toml |
|---|---|
name, description, type, license, keywords |
[package] |
require |
[require] (constraints copied verbatim) |
require-dev |
[require-dev] |
replace, provide, conflict |
[replace], [provide], [conflict] (copied verbatim) |
autoload (psr-4, psr-0, classmap, files) |
[autoload] |
autoload.exclude-from-classmap |
[autoload] exclude |
autoload-dev |
[autoload-dev] |
scripts |
[scripts] |
minimum-stability, prefer-stable |
[config] |
config.sort-packages |
[config] |
config.platform.php |
[config.platform] (only when set explicitly) |
repositories (composer, packagist, vcs, git) |
[[repositories]] |
repositories (path, package) |
[sources] (per-package path / inline specs) |
extra |
[extra] (carried verbatim) |
config.http-basic, config.bearer |
auth.toml (see below) |
Multi-package endpoints (composer / packagist registries, a vcs discovery repo)
become [[repositories]]. Single-package repositories become [sources] entries keyed
by package name: a type: path repo maps to a { path, version? } spec (its
options.versions pin is preserved), and an inline type: package maps to a
self-describing inline package. [require] / [require-dev] keep their composer.json
order, with platform packages (php, ext-*) tiered first.
The generated phast.toml is formatted with Phast's canonical style, so it is also a
good first look at the format. See The manifest for the full
reference.
Credentials become auth.toml¶
Embedding credentials in a committed manifest is an anti-pattern, so inline credentials
from the composer.json config section are not copied into phast.toml. Instead,
phast migrate merges them with any existing auth.toml/auth.json and writes the
result to ./auth.toml:
Credentials were written to auth.toml. Add auth.toml to your .gitignore to keep
credentials out of version control.
Warning
Do that. auth.toml belongs in .gitignore, next to .env.
Phast also keeps reading Composer's auth.json files (project-local and
~/.composer/auth.json), so existing credential setups continue to work without any
migration step. See Registries and authentication.
Why composer.lock is ignored¶
phast migrate deliberately does not convert composer.lock. That lock was produced by
Composer's resolver under Composer's platform assumptions; reusing it would bake those
assumptions into Phast. Running phast install after migration re-resolves from your
constraints and produces a clean phast.lock.
In practice this means your resolved versions may differ from the old composer.lock:
Phast picks the newest versions your constraints allow. If you depended on older
versions without expressing that in your constraints, tighten the constraints in
phast.toml before installing, using the old composer.lock as a reference.
What is not migrated (yet)¶
Be aware of these gaps before switching a production project:
suggest: informational only, dropped.config.allow-plugins,vendor-dir,bin-dir: not yet supported by Phast.repositoriesoftype: svn: Subversion is not supported and is not planned, so these entries are dropped. If your project depends on one, that dependency will fail to resolve after migrating; move the package to a git host or a registry first.
Script compatibility¶
Scripts are copied verbatim, and most run unchanged: @php ... commands, plain shell
commands, and PHP static callbacks (Vendor\Class::method) are all supported, and Phast
fires the common lifecycle events (pre-/post-install-cmd, pre-/post-update-cmd,
pre-/post-autoload-dump). Unknown event names are silently skipped, so leftover
Composer-specific hooks do no harm.
Two cases need attention:
- Scripts that call
composerdirectly (e.g.composer dump-autoload) will only work if Composer is still installed; Phast does not emulate thecomposerCLI. Replace them with the Phast equivalent or an@phpcommand. - Script references (
"test": "@unit-tests"-style aliases) are not supported yet; inline the referenced commands.
See Running scripts for the details.
Checklist after migrating¶
phast install, and review the resolved versions inphast.lockagainst your oldcomposer.lockwhere it matters.- Run your test suite and any tools under
vendor/bin/. - Add
auth.tomlto.gitignoreif it was created. - Commit
phast.tomlandphast.lock. - Update CI to install Phast and run
phast install(the caching guide shows how to cache between jobs).