Route build-step composer calls through ephpm composer (opt-in) - #36
Open
luthermonson wants to merge 1 commit into
Open
luthermonson wants to merge 1 commit into
luthermonson wants to merge 1 commit into
Conversation
…composer`
Add an opt-in `--use-ephpm-composer` / `SWITCHBOARD_EPHPM_COMPOSER` flag
(default off) that routes a preview's Composer invocations through the
embedded `ephpm composer` (vivacity) fast Rust installer, without touching
PR authors' manifests and without breaking vivacity's fallback.
When on:
- each `build:`/`seed:` command whose leading token is exactly `composer`
is rewritten to `ephpm composer` before it runs in the tenant sandbox
(`route_composer_command`), and
- the implicit `composer install` (run when a manifest declares no build
steps and a `composer.json` exists) runs as `ephpm composer install …`
instead of the single-token `--composer` binary.
Only a genuine leading `composer` token is rewritten — `my-composer`,
`php composer.phar`, `echo composer`, and non-leading occurrences pass
through untouched, as does an already-routed `ephpm composer …`.
Recursion-safe by construction: switchboard rewrites only its own
constructed command and never shadows `composer` on `PATH`, so vivacity's
out-of-scope fallback (`Command::new("composer")`, a `PATH` search that
ignores shell aliases) still resolves to the host's real PHP composer. The
host must therefore keep a real PHP `composer` on `PATH` for the fallback;
this is documented on the flag and in the README config table.
Tests: pure-rewrite cases (leading rewrite, flag-off no-op, non-leading /
look-alike ignored), the end-to-end sandbox argv (`ephpm exec … -- sh -c
"cd … && ephpm composer install …"`), and the config flag parse. Full
suite green (314 passed). Recursion-safety verified separately with stub
`ephpm`/`composer` binaries: one `ephpm composer` hop reaches the real
`composer` and terminates (no infinite shim recursion).
|
ePHPm Preview — deployed (health check pending)
Preview updates automatically on each push to this PR. |
1 similar comment
|
ePHPm Preview — deployed (health check pending)
Preview updates automatically on each push to this PR. |
|
ePHPm Preview — deployed (health check pending)
Preview updates automatically on each push to this PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an opt-in flag that routes a preview's Composer invocations through the embedded
ephpm composer(vivacity) fast Rust installer, so PR users' build steps transparently use the fast installer without changing their manifests and without breaking vivacity's fallback.--use-ephpm-composer/SWITCHBOARD_EPHPM_COMPOSER(default off, opt-in).When on:
build:/seed:command whose leading token is exactlycomposeris rewritten toephpm composerbefore it runs in the tenant sandbox (route_composer_command).composer install(run when a manifest declares no build steps and acomposer.jsonexists) runs asephpm composer install …instead of the single-token--composerbinary.PR authors' manifests are never edited — only the command switchboard constructs and executes changes.
Approach: token-rewrite (recommended, chosen)
Switchboard already wraps every untrusted step as
ephpm exec … --site <key> -- sh -c "cd '<dir>' && <cmd>". The change rewrites the leadingcomposertoken of<cmd>toephpm composer. This is deterministic, shell-agnostic (doesn't depend onshopt -s expand_aliases), and recursion-safe.Only a genuine leading
composertoken is rewritten:composer install --no-dev→ephpm composer install --no-devmy-composer …,php composer.phar …,composer.phar …,echo composer …, and non-leadingcomposeroccurrences pass through untouched.ephpm composer …(leading tokenephpm) is left alone — no double-rewrite.Recursion safety
vivacity's out-of-scope fallback shells out with
Command::new("composer")— aPATHsearch that ignores shell aliases. Switchboard rewrites only its own constructed command and never shadowscomposeronPATH, so that fallback resolves to the host's real PHP composer, not back into the rewrite.Operator requirement (documented on the flag and in the README): the host must keep a real PHP
composeronPATH, and anephpmbinary that carries thecomposersubcommand, for the fallback to work.Tests
Rust unit/integration tests (in
src/deployer.rs/src/config.rs):composer→ephpm composer(args preserved; barecomposer; leading whitespace preserved), plus the end-to-end sandbox argv asserts the executed command isephpm exec … -- sh -c "cd '<dir>' && ephpm composer install --no-dev"and the program is still theephpmbinary.php artisan … composer,echo composer …,my-composer …,composer.phar …,php composer.phar …, and re-enteredephpm composer …are all left untouched.--use-ephpm-composerparses; defaults to off.Full suite: 314 passed, 0 failed (
cargo test).cargo clippy --all-targetsclean.Recursion-safety verified separately with stub
ephpm/composerbinaries onPATH: driving the exact constructed command once produced exactly oneephpm composerinvocation followed by one realcomposerinvocation, exit 0, no hang — proving the fallback reaches the real composer with no infinite shim recursion.