Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions docs/COMMANDER-MIGRATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Commander Migration Status

Goal: remove the abandoned `args` package, keep CLI behavior stable, and support packaging to a single bundled executable (Node SEA or similar). See `AGENTS.md` for broader architecture traps.

## Migration Outcome

- `src/lib/cli/command.js` is the active Commander-backed compatibility wrapper for all bins that call `command()`.
- `args` has been removed from `package.json` and `npm-shrinkwrap.json`.
- Root command flow (`src/bin/vip.js`) now dispatches via the shared Commander wrapper again, preserving login gating and subcommand chaining.
- Temporary side-path wrapper work has been removed (`src/lib/cli/command-commander.ts` deleted).

## Compatibility Behaviors Preserved

- Legacy command contract stays the same: `command(opts).option(...).argv(process.argv, handler)`.
- Alias behavior remains pre-parse: `@app` and `@app.env` are stripped before `--`; alias + `--app/--env` still errors.
- `_opts` controls are still honored: app/env context fetch, confirmation gating, output formatting, wildcard command handling, required positional args.
- Shared formatting/output and telemetry hooks are still in the wrapper path.
- Local nested subcommand dispatch still works via sibling executable resolution.

## Post-Migration Hardening

- Short-flag compatibility was restored for long options without explicit aliases:
- Example: `--elasticsearch` accepts `-e`, `--phpmyadmin` accepts `-p`, etc.
- Auto-short generation skips reserved global flags (`-h`, `-v`, `-d`) and avoids duplicate collisions.
- `vip dev-env exec` now performs bounded readiness checks before deciding an environment is not running.
- `startEnvironment()` now includes bounded post-start readiness checks and one recovery `landoStart` retry if the environment stays `DOWN` after rebuild/start.

## Remaining Technical Debt

- `_opts` is still module-level state in `src/lib/cli/command.js` and can leak between command instances in one process.
- Help text parity against historical `args` output is close but still a verification target for high-traffic commands.
- Full dev-env E2E can still show Docker/Lando infrastructure flakiness (network cleanup and startup latency), which is environment-level, not parser-level.

## Verification Commands

- `npm run build`
- `npm run check-types`
- `npm run test:e2e:dev-env -- --runInBand __tests__/devenv-e2e/001-create.spec.js __tests__/devenv-e2e/005-update.spec.js`
- `npm run test:e2e:dev-env -- --runInBand __tests__/devenv-e2e/008-exec.spec.js __tests__/devenv-e2e/010-import-sql.spec.js`

## Single-Bundle Direction

- Preferred: `esbuild` bundle rooted at `src/bin/vip.js`.
- Keep native deps external (`@postman/node-keytar`) for SEA/packaging workflows.
- Candidate build target:
- `dist/vip.bundle.cjs` for SEA ingestion or launcher wrapping.
- Example command:
- `esbuild src/bin/vip.js --bundle --platform=node --target=node20 --format=cjs --outfile=dist/vip.bundle.cjs --banner:js="#!/usr/bin/env node" --external:@postman/node-keytar`

## Next Refactor Steps

1. Remove global `_opts` state from `src/lib/cli/command.js` by moving to per-instance configuration.
2. Add parser contract tests for aliasing, wildcard behavior, and short/long boolean coercion.
3. Add stable startup/readiness integration checks around dev-env commands in CI environments with Docker.
4. Add bundling script(s) and SEA config proof-of-concept for a single-file executable artifact.
133 changes: 14 additions & 119 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@
"@automattic/vip-search-replace": "^2.0.0",
"@json2csv/plainjs": "^7.0.3",
"@wwa/single-line-log": "^1.1.4",
"args": "5.0.3",
"chalk": "^5.6.2",
"check-disk-space": "3.4.0",
"cli-columns": "^4.0.0",
"cli-table3": "^0.6.3",
"commander": "^14.0.3",
"configstore": "^8.0.0",
"debug": "4.4.3",
"ejs": "^5.0.1",
Expand Down
22 changes: 21 additions & 1 deletion src/bin/vip-dev-env-exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@

const exampleUsage = 'vip dev-env exec';
const usage = 'vip dev-env exec';
const ENV_UP_CHECK_ATTEMPTS = 5;
const ENV_UP_CHECK_DELAY_MS = 1500;

const sleep = ms => new Promise( resolve => setTimeout( resolve, ms ) );

async function waitForEnvironmentReadiness( lando, slug ) {
const instancePath = getEnvironmentPath( slug );

for ( let attempt = 1; attempt <= ENV_UP_CHECK_ATTEMPTS; attempt++ ) {
if ( await isEnvUp( lando, instancePath ) ) {

Check warning on line 29 in src/bin/vip-dev-env-exec.js

View workflow job for this annotation

GitHub Actions / Lint

Unexpected `await` inside a loop
return true;
}

if ( attempt < ENV_UP_CHECK_ATTEMPTS ) {
await sleep( ENV_UP_CHECK_DELAY_MS );

Check warning on line 34 in src/bin/vip-dev-env-exec.js

View workflow job for this annotation

GitHub Actions / Lint

Unexpected `await` inside a loop
}
}

return false;
}

const examples = [
{
Expand Down Expand Up @@ -80,7 +100,7 @@
}

if ( ! opt.force ) {
const isUp = await isEnvUp( lando, getEnvironmentPath( slug ) );
const isUp = await waitForEnvironmentReadiness( lando, slug );
if ( ! isUp ) {
throw new UserError(
'A WP-CLI command can only be executed on a running local environment.'
Expand Down
2 changes: 1 addition & 1 deletion src/bin/vip.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const runCmd = async function () {
.command( 'whoami', 'Retrieve details about the current authenticated VIP-CLI user.' )
.command( 'wp', 'Execute a WP-CLI command against an environment.' );

cmd.argv( process.argv );
await cmd.argv( process.argv );
};

/**
Expand Down
Loading
Loading