refactor: migrate shell layer to tinyexec + per-command e2e tests#210
Open
rqbazan wants to merge 4 commits into
Open
refactor: migrate shell layer to tinyexec + per-command e2e tests#210rqbazan wants to merge 4 commits into
rqbazan wants to merge 4 commits into
Conversation
🦋 Changeset detectedLatest commit: f368be9 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Big single landing for three intertwined improvements that were
prepped on this branch:
1. **clibuddy: replace zx with tinyexec.** The new `ShellService` API
is `run(cmd, args, opts?)` (verbose, streams stdio) and
`runCaptured(cmd, args, opts?)` (silent, returns Output), both
throwing `NonZeroExitError` by default. Drops `quote/isRaw/
defaultQuote/getPreferLocal/localBaseBinPath/mute()/quiet()/
isProcessOutput` and the `./test-helpers` export. Adds
`resolveBinPath(pkg, { from, binPath?, binName? })` to find the
absolute path to a package's bin even when its `exports` map is
restrictive (oxlint) or absent (@biomejs/biome).
2. **run-run: use the new shell + tighten exec to string[].** Every
`ToolService` now resolves its bin path with `resolveBinPath` and
passes it to `ShellService.run` with `display: <friendly-name>`,
bypassing the `node_modules/.bin/<bin>` shims that run-run itself
publishes (tools/biome, tools/oxlint, tools/oxfmt, tools/tsdown)
which would otherwise loop. `ToolService.exec` now accepts only
`string[]`. `tscheck` runs pre-scripts with `shell: true` so they
can use `&&`, pipes, env-var substitution.
3. **vland init: prompt for install/git + fix git commit.** Adds
default-yes confirms when the user doesn't pass --install/--no-
install / --git/--no-git on the CLI. The git-commit failure
(`pathspec 'initial' did not match`) caused by missing $'…'
wrapping in the old custom quote() goes away naturally with array-
based exec.
**Tests reorganised.** Drop the clibuddy/test-helpers mock entirely.
run-run integration tests are split into one file per command
(cli, jsc, lint, format, tsc, build-lib), each spawning the real
`rr` binary against a temp fixture (`makeFixture` helper) and
asserting on observable output. vland init keeps its existing
integration coverage (commit message exact-match, no pathspec errors,
prompt-default behaviour in non-TTY).
Verification: pnpm test (22 tests across 7 files, all green) and
pnpm test:types (4 packages clean).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
d662e9c to
174d876
Compare
`BiomeService.check()` calls `biome ci` instead of `biome check` when `isCI` is true (std-env). The jsc tests asserted on `check` only, which made them green locally but red on GitHub Actions. Relax the regex to match either subcommand — the test's intent is that biome receives properly tokenized flags, not which subcommand it's invoked with. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Preview releaseLatest commit: Some packages have been released:
Note Use the PR number as tag to install any package. For instance: |
The clack spinner already says "Installing dependencies with pnpm…" but `installDependencies` from nypm was running with stdio inherited, so deprecation warnings (DEP0169 url.parse), upstream `unrun` ENOENT warnings, and pnpm's `Ignored build scripts` notice all leaked into the terminal — confusing UX next to the spinner. nypm exposes `silent: true` which pipes stdio. If install fails the spinner already flips to "Failed to install dependencies" and we debug-log the captured error. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The project-name prompt always suggested `my-app` regardless of which template was picked, and the outro always recommended `pnpm dev` even for the `library` template (which has no `dev` script in its package.json). Add a `TEMPLATE_META` map keyed by template name with: - `placeholder` — used in the project-name `text()` prompt - `runScript` — appended to the outro's next-steps line Mappings: - library → `my-lib`, next: `pnpm test` (libraries don't have a dev server) - backend → `my-api`, next: `pnpm dev` - monorepo → `my-mono`, next: `pnpm dev` (turbo run dev) Add a backend-specific install-resolution test alongside the existing library one to lock in both branches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Three intertwined improvements landing together because they share the same shell layer rewrite:
@vlandoss/clibuddy(minor, breaking pre-1.0): replacezxwithtinyexec. NewShellServiceAPI:run(cmd, args, opts?)— verbose, streams stdio, prints$ <cmd> <args>prefix.runCaptured(cmd, args, opts?)— silent, returnsOutput { stdout, stderr, exitCode }.NonZeroExitErroron non-zero exit by default; opt out with{ throwOnError: false }.at(cwd)/child(opts)for inherited config.resolveBinPath(pkg, { from, binPath?, binName? })helper that finds an installed package's bin even whenexportsis restrictive (oxlint) or absent (@biomejs/biome).isNonZeroExitErrorreplacesisProcessOutput.$\...`template-literal API,quote/isRaw/defaultQuote,getPreferLocal/localBaseBinPath,mute()/quiet(),./test-helpers` export.node_modules/.binto PATH, solocalBaseBinPathis no longer needed.@vlandoss/run-run(patch): allToolServicesubclasses (biome, oxlint, oxfmt, tsdown, tsc) resolve their bin viaresolveBinPathand pass the absolute path withdisplay: <friendly-name>. This bypasses thenode_modules/.bin/<bin>shims that run-run itself publishes (tools/biomeetc.), which would otherwise loop back throughrr tools <bin>indefinitely.ToolService.execaccepts onlystring[].tscheckrunspretsc/pretypecheckwithshell: trueso they can use&&, pipes, env-var substitution. End-user CLI behaviour unchanged.@vlandoss/vland(minor):vland initprompts (default-yes) for installing dependencies and initialising git when--install/--no-install/--git/--no-gitaren't passed. Non-interactive defaults: bothtrue. Also: the git-commit-failure (pathspec 'initial' did not match) caused by the old customquote()not wrapping whitespace strings is gone — array-based exec makes each token survive.Tests reorganised
clibuddy/test-helpers(the zx mock). e2e is the strategy now.cli,jsc,lint,format,tsc,build-lib. Each spawns the realrrbinary against a temp fixture (makeFixturehelper) and asserts on observable output.Test plan
🤖 Generated with Claude Code