Skip to content

feat(cli): build to a directory and add a quiet mode - #21

Merged
codad5 merged 1 commit into
mainfrom
feat/build-directory
Oct 12, 2026
Merged

codad5 merged 1 commit into
mainfrom
feat/build-directory

Conversation

@codad5

@codad5 codad5 commented Oct 12, 2026

Copy link
Copy Markdown
Owner

What

Two additions to the packager.

Build::plugin(__DIR__)->run('npm run build')->toDirectory('dist/{slug}');   // a folder instead of a zip
Build::plugin(__DIR__)->quiet()->zip();                                     // only warnings are printed

CLI: wptoolkit-build package --dir=PATH and --quiet. Config: "quiet": true.

Why

  • zip() was the only way to finish a build, and staging is deleted afterwards. Deploying by rsync or SVN, mounting a built plugin in a test site, or inspecting exactly what ships (after all steps have run, which dryRun() does not do) needed a zip and an unzip. Our own E2E fixture did exactly that; it now uses toDirectory().
  • zip() always prints its summary, and the only control was withOutput() with an empty closure, which also hides warnings. A consumer's build.php echoed $report->summary() again and printed it twice; the guide now says the summary is printed for you.

toDirectory() safety

The target folder is replaced, so it is checked before any command runs, and again before writing:

  • refused if it is the project or a folder above it. Paths are resolved (., ..) and compared without letter case and through realpath(), because on Windows and macOS the project spelled in another case is the same folder, and its own main file would otherwise make it look like an earlier build;
  • refused if it exists, is not empty, and is not an earlier build of this project (recognised by the project's main file with its header);
  • nothing is written if a step or verification fails.

Other changes

  • Packaging moved out of Build into ZipPackager and DirectoryPackager, sharing StagedFiles. Zip output is byte-for-byte unchanged (the reproducibility test still passes).
  • BuildReport gains directory; for a directory build zip and sha256 are empty and files are relative to the folder.
  • quiet() wins over verbose(); warnings are still printed and still on the report.

Tests

Written first. Directory output equals the zip's file list; commands and verification run; a previous build is replaced, not merged; empty target accepted; a folder holding other files is left untouched; the project, its parent, dist/.., .., an upper-cased project path and a source folder are all refused with the files intact; working tree unchanged; quiet prints nothing but warnings and still returns the report.

🤖 Generated with Claude Code

toDirectory() runs the same steps and verification as zip() and writes a
folder, for rsync or SVN deploys, test sites, or inspecting what ships.
The target is replaced only if it is empty or an earlier build of the
same project; the project itself or a folder above it is refused, with
paths resolved and compared without case. quiet() prints only warnings.
Packaging moves into ZipPackager and DirectoryPackager.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codad5
codad5 merged commit 27103a7 into main Oct 12, 2026
19 checks passed
@codad5
codad5 deleted the feat/build-directory branch October 12, 2026 09:01
@codad5 codad5 mentioned this pull request Oct 12, 2026
Sign up for free to 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