mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
## Summary Adds `bun run --parallel` and `bun run --sequential` — new flags for running multiple package.json scripts concurrently or sequentially with Foreman-style prefixed output. Includes full `--filter`/`--workspaces` integration for running scripts across workspace packages. ### Usage ```bash # Run "build" and "test" concurrently from the current package.json bun run --parallel build test # Run "build" and "test" sequentially with prefixed output bun run --sequential build test # Glob-matched script names bun run --parallel "build:*" # Run "build" in all workspace packages concurrently bun run --parallel --filter '*' build # Run "build" in all workspace packages sequentially bun run --sequential --workspaces build # Glob-matched scripts across all packages bun run --parallel --filter '*' "build:*" # Multiple scripts across all packages bun run --parallel --filter '*' build lint test # Continue running even if one package fails bun run --parallel --no-exit-on-error --filter '*' test # Skip packages missing the script bun run --parallel --workspaces --if-present build ``` ## How it works ### Output format Each script's stdout/stderr is prefixed with a colored, padded label: ``` build | compiling... test | running suite... lint | checking files... ``` ### Label format - **Without `--filter`/`--workspaces`**: labels are just the script name → `build | output` - **With `--filter`/`--workspaces`**: labels are `package:script` → `pkg-a:build | output` - **Fallback**: if a package.json has no `name` field, the relative path from the workspace root is used (e.g., `packages/my-pkg:build`) ### Execution model - **`--parallel`**: all scripts start immediately, output is interleaved with prefixes - **`--sequential`**: scripts run one at a time in order, each waiting for the previous to finish - **Pre/post scripts** (`prebuild`/`postbuild`) are grouped with their main script and run in dependency order within each group - By default, a failure kills all remaining scripts. `--no-exit-on-error` lets all scripts finish. ### Workspace integration The workspace branch in `multi_run.zig` uses a two-pass approach for deterministic ordering: 1. **Collect**: iterate workspace packages using `FilterArg.PackageFilterIterator` (same infrastructure as `filter_run.zig`), filtering with `FilterArg.FilterSet`, collecting matched packages with their scripts, PATH, and cwd. 2. **Sort**: sort matched packages by name (tiebreak by directory path) for deterministic ordering — filesystem iteration order from the glob walker is nondeterministic. 3. **Build configs**: for each sorted package, expand script names (including globs like `build:*`) against that package's scripts map, creating `ScriptConfig` entries with `pkg:script` labels and per-package cwd/PATH. ### Behavioral consistency with `filter_run.zig` | Behavior | `filter_run.zig` | `multi_run.zig` (this PR) | |----------|-------------------|---------------------------| | `--workspaces` skips root package | Yes | Yes | | `--workspaces` errors on missing script | Yes | Yes | | `--if-present` silently skips missing | Yes | Yes | | `--filter` without `--workspaces` includes root | Yes (if matches) | Yes (if matches) | | Pre/post script chains | Per-package | Per-package | | Per-package cwd | Yes | Yes | | Per-package PATH (`node_modules/.bin`) | Yes | Yes | ### Key implementation details - Each workspace package script runs in its own package directory with its own `node_modules/.bin` PATH - `dirpath` from the glob walker is duped to avoid use-after-free when the iterator's arena is freed between patterns - `addScriptConfigs` takes an optional `label_prefix` parameter — `null` for single-package mode, package name for workspace mode - `MultiRunProcessHandle` is registered in the `ProcessExitHandler` tagged pointer union in `process.zig` ## Files changed | File | Change | |------|--------| | `src/cli/multi_run.zig` | New file: process management, output routing, workspace integration, dependency ordering | | `src/cli.zig` | Dispatch to `MultiRun.run()` for `--parallel`/`--sequential`, new context fields | | `src/cli/Arguments.zig` | Parse `--parallel`, `--sequential`, `--no-exit-on-error` flags | | `src/bun.js/api/bun/process.zig` | Register `MultiRunProcessHandle` in `ProcessExitHandler` tagged pointer union | | `test/cli/run/multi-run.test.ts` | 118 tests (102 core + 16 workspace integration) | | `docs/pm/filter.mdx` | Document `--parallel`/`--sequential` + `--filter`/`--workspaces` combination | | `docs/snippets/cli/run.mdx` | Add `--parallel`, `--sequential`, `--no-exit-on-error` parameter docs | ## Test plan All 118 tests pass with debug build (`bun bd test test/cli/run/multi-run.test.ts`). The 16 new workspace tests all fail with system bun (`USE_SYSTEM_BUN=1`), confirming they test new functionality. ### Workspace integration tests (16 tests) 1. `--parallel --filter='*'` runs script in all packages 2. `--parallel --filter='pkg-a'` runs only in matching package 3. `--parallel --workspaces` matches all workspace packages 4. `--parallel --filter='*'` with glob expands per-package scripts 5. `--sequential --filter='*'` runs in sequence (deterministic order) 6. Workspace + failure aborts other scripts 7. Workspace + `--no-exit-on-error` lets all finish 8. `--workspaces` skips root package 9. Each workspace script runs in its own package directory (cwd verification) 10. Multiple script names across workspaces (`build` + `test`) 11. Pre/post scripts work per workspace package 12. `--filter` skips packages without the script (no error) 13. `--workspaces` errors when a package is missing the script 14. `--workspaces --if-present` skips missing scripts silently 15. Labels are padded correctly across workspace packages 16. Package without `name` field uses relative path as label --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Bun Documentation
Official documentation for Bun: the fast, all-in-one JavaScript runtime.
Development
Install the Mintlify CLI to preview the documentation locally:
bun install -g mint
Run the development server:
mint dev
The site will be available at http://localhost:3000.
Contributing
Contributions are welcome! Please open an issue or submit a pull request.