Skip to content

feat(phpup): consolidate 5 CLI binaries as phpup subcommands (PR 6/6) - #71

Merged
phramz merged 1 commit into
mainfrom
feat/local-ci-pr6-cli-consolidation
Apr 24, 2026
Merged

feat(phpup): consolidate 5 CLI binaries as phpup subcommands (PR 6/6)#71
phramz merged 1 commit into
mainfrom
feat/local-ci-pr6-cli-consolidation

Conversation

@phramz

Copy link
Copy Markdown
Contributor

Summary

Sixth and final PR of the local-CI unification rollout (design). Merges cmd/planner, cmd/lockfile-update, cmd/gc-bundles, cmd/hermetic-audit, and cmd/compat-diff into phpup subcommands so the repo ships a single Go binary.

New subcommands (byte-identical stdout/stderr + flag surface to the retired binaries for the same inputs):

SubcommandReplacesInternal package
phpup plancmd/plannerinternal/planner (cli.go added)
phpup lockfile-updatecmd/lockfile-updateinternal/lockfileupdate
phpup gc-bundlescmd/gc-bundlesinternal/gcbundles
phpup hermetic-auditcmd/hermetic-auditinternal/hermeticaudit
phpup compat-diffcmd/compat-diffinternal/compatdiff

Each cmd/<name>/ directory was moved under internal/<name>/ (package renamed from main<name>; func main()func Main(args []string) error). Flags are parsed through a dedicated flag.FlagSet so they don't collide with phpup's setup-flow flag.Parse.

Exit conventions preserved:

  • phpup hermetic-audit: 0 = clean, 1 = findings, 2 = error (via hermeticaudit.ErrFindings returned from Main).
  • phpup compat-diff: 0 = match, 1 = deviation(s), 2 = malformed input (via compatdiff.ExitCode returned from Main).

Updated call sites:

  • .github/workflows/ci.yml: publish job uses bin/phpup lockfile-update instead of go run ./cmd/lockfile-update. github.repository_owner is pulled in via env: to keep run: free of untrusted-input interpolation.
  • .github/workflows/release-please.yml: drops dist/planner-linux-amd64 build; releases ship only phpup-linux-amd64 (planner is phpup plan).
  • Makefile: drops cmd/planner from build / build-linux-*; gc-bundles-dry-run uses $(PHPUP_BIN) gc-bundles.
  • .golangci.yml: subprocess-call allowlist paths retargeted from cmd/lockfile-update/ / cmd/gc-bundles/ → their new internal/…/ homes.

Docs refreshed:CLAUDE.md, CONTRIBUTING.md, README.md, and stale comments in internal/planner/helpers.go / internal/oci/client.go.

Test plan

  • make check green locally (25 Go packages pass; coverage held across all internal packages)
  • phpup plan --help, phpup lockfile-update --help, phpup gc-bundles --help, phpup hermetic-audit --help, phpup compat-diff --help all work and mirror the previous binaries' flags
  • CI ci.yml green on this PR
  • After merge: first push to main runs ci.yml::publish, which now invokes bin/phpup lockfile-update — verify the lockfile-update commit lands on main

Sixth and final PR of the local-CI unification rollout (see
docs/superpowers/specs/2026-04-23-local-ci-unification-design.md).
Merges cmd/planner, cmd/lockfile-update, cmd/gc-bundles,
cmd/hermetic-audit, and cmd/compat-diff into phpup subcommands so the
repo ships a single binary.
New subcommands (byte-identical stdout/stderr + flag surface to the
retired binaries for the same inputs):
phpup plan — was cmd/planner
phpup lockfile-update — was cmd/lockfile-update
phpup gc-bundles — was cmd/gc-bundles
phpup hermetic-audit — was cmd/hermetic-audit
phpup compat-diff — was cmd/compat-diff
Each cmd/<name>/ has been moved under internal/<name>/ (package renamed
from main; func main → func Main(args []string)). Flags are parsed
through a dedicated FlagSet so they don't collide with phpup's
setup-flow flag.Parse. Exit conventions preserved where load-bearing:
- phpup hermetic-audit: 0 = clean, 1 = findings, 2 = error (via
hermeticaudit.ErrFindings returned from Main)
- phpup compat-diff: 0 = match, 1 = deviation(s), 2 = malformed input
(via compatdiff.ExitCode returned from Main)
Updated call sites:
- .github/workflows/ci.yml: `bin/phpup lockfile-update` replaces
`go run ./cmd/lockfile-update` in the publish job. Uses an env var
for github.repository_owner so the `run:` block is free of
untrusted-input interpolation.
- .github/workflows/release-please.yml: drops the
`dist/planner-linux-amd64` build; releases now ship only
phpup-linux-amd64 (planner is accessible as `phpup plan`).
- Makefile: drops the second `go build` of cmd/planner in `build` /
`build-linux-*` targets; `gc-bundles-dry-run` now calls
`$(PHPUP_BIN) gc-bundles` instead of `go run ./cmd/gc-bundles`.
- .golangci.yml: retargeted subprocess-call allowlist paths from
`cmd/lockfile-update/`, `cmd/gc-bundles/` to their new
`internal/lockfileupdate/`, `internal/gcbundles/` homes.
- compat-diff tests build phpup via `./cmd/phpup` and prepend
`compat-diff` to argv to keep the integration-style exit-code
checks intact.
Docs refreshed:
- CLAUDE.md Architecture section now describes phpup as the single
binary hosting runtime + maintainer subcommands.
- CONTRIBUTING.md Project Structure section updated; orphan-bundle
cleanup instruction now uses `phpup gc-bundles`.
- README.md compat-matrix section refers to `phpup compat-diff`.
- Stale comments in internal/planner/helpers.go and
internal/oci/client.go that pointed at the deleted cmd/ paths.
Verification: `make check` green. Each new subcommand exercises
`--help` (help output identical to the retired binaries aside from the
"Usage of phpup <name>:" prefix) and runs through its package test
suite (20+ tests across the five new internal packages).
@phramz
phramz merged commit 0ff12e4 into mainApr 24, 2026
20 checks passed
@phramz
phramz deleted the feat/local-ci-pr6-cli-consolidation branch April 24, 2026 09:37
@github-actionsgithub-actionsBot mentioned this pull request Apr 24, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@phramz