Skip to content

feat(cli): add --fetch-timeout / --fetch-retries / retry backoff flags#436

Merged
jdx merged 4 commits intomainfrom
claude/blissful-jemison-883e49
Apr 30, 2026
Merged

feat(cli): add --fetch-timeout / --fetch-retries / retry backoff flags#436
jdx merged 4 commits intomainfrom
claude/blissful-jemison-883e49

Conversation

@jdx
Copy link
Copy Markdown
Contributor

@jdx jdx commented Apr 30, 2026

Summary

  • Adds the global --fetch-timeout, --fetch-retries, --fetch-retry-factor, --fetch-retry-mintimeout, and --fetch-retry-maxtimeout CLI flags so users can drive the registry transport knobs from the command line, matching pnpm's surface.
  • Wires them as a process-wide FETCH_CLI_OVERRIDES snapshot populated once in async_main. resolve_fetch_policy reads it as the ResolveCtx::cli slice, so every make_client caller (install, add, publish, audit, …) honors the flags without per-command plumbing. The existing settings codegen already orders cli > env > npmrc > workspaceYaml.
  • Ports the matching pnpm test (pnpm/test/install/misc.ts:508, 'installation fails with a timeout error') into pnpm_install_misc.bats (now 11/37 from that file) using the new flags directly, plus a positive-path smoke test in fetch_settings.bats covering all five.

Why

The pnpm test passes --fetch-timeout=1 --fetch-retries=0 to force a timeout failure. aube previously surfaced these settings only through .npmrc / pnpm-workspace.yaml / NPM_CONFIG_* env vars — a CLI-equivalent surface was missing. The doc-comment on make_client already anticipated this ('future CLI flags Just Work without touching this function again'), so the wiring slots straight into the existing precedence chain.

Test plan

  • cargo fmt --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test --workspace
  • mise run test:bats test/pnpm_install_misc.bats test/fetch_settings.bats (17/17)
  • aube --help shows the five new flags

🤖 Generated with Claude Code


Note

Medium Risk
Adds new global network transport flags that affect registry fetch behavior across all commands; misconfiguration could cause unexpected timeouts or retry storms, but defaults remain unchanged when flags aren’t used.

Overview
Adds five new global CLI flags (--fetch-timeout, --fetch-retries, --fetch-retry-factor, --fetch-retry-mintimeout, --fetch-retry-maxtimeout) and wires them into the settings resolver so they override .npmrc/env/workspace config for registry fetch policy.

Implements a process-wide snapshot (FETCH_CLI_OVERRIDES) populated in main and consumed by resolve_fetch_policy, so every registry client created via make_client (install/add/publish/audit/…) honors the overrides without per-command plumbing.

Updates generated CLI/docs metadata and adds BATS coverage for the new flags, including a timeout-failure test (aube add --fetch-timeout=1 --fetch-retries=0) and a positive-path smoke test exercising all five knobs.

Reviewed by Cursor Bugbot for commit a7a5c3f. Bugbot is set up for automated code reviews on this repo. Configure here.

@jdx jdx force-pushed the claude/blissful-jemison-883e49 branch from c821389 to bc86f45 Compare April 30, 2026 22:48
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 30, 2026

Greptile Summary

This PR adds five global CLI flags (--fetch-timeout, --fetch-retries, --fetch-retry-factor, --fetch-retry-mintimeout, --fetch-retry-maxtimeout) that map directly to the existing fetchRetries/fetchTimeout/etc. settings layer, using a process-wide OnceLock snapshot (FETCH_CLI_OVERRIDES) that feeds resolve_fetch_policy so all make_client callers honor the flags without per-command plumbing. The implementation is consistent with the existing GLOBAL_VIRTUAL_STORE / GLOBAL_OUTPUT OnceLock pattern, the settings codegen already handled the cli > env > npmrc > workspaceYaml precedence chain, and both a positive-path smoke test and the pnpm-ported timeout-failure test (with a falsifiable output assertion) are included.

Confidence Score: 5/5

Safe to merge — no logic errors, security issues, or behavioral regressions found.

All five flags slot cleanly into the existing precedence infrastructure, the OnceLock pattern is consistent with other process-wide globals, documentation and generated files are in sync, and both a positive-path and a falsifiable negative-path test are present. Previously flagged concerns (exit-code-only test, integer-typed retry factor) are either addressed or already captured in prior review threads.

No files require special attention.

Important Files Changed

Filename Overview
crates/aube/src/main.rs Adds five Option clap fields for the new fetch flags and a fetch_cli_overrides_from_cli helper that converts them to (name, value) pairs; wired into async_main before command dispatch. Implementation follows existing patterns cleanly.
crates/aube/src/commands/mod.rs Adds FETCH_CLI_OVERRIDES: OnceLock with set_fetch_cli_overrides / fetch_cli_overrides accessors, consistent with existing GLOBAL_VIRTUAL_STORE / GLOBAL_OUTPUT OnceLock pattern. resolve_fetch_policy now passes the CLI bag to ResolveCtx::cli.
crates/aube-settings/settings.toml Registers CLI source aliases for fetchRetries, fetchRetryFactor, fetchRetryMintimeout, fetchRetryMaxtimeout, and fetchTimeout; adds two usage examples. No type or default changes.
test/pnpm_install_misc.bats Adds a timeout-failure test using --fetch-timeout=1 --fetch-retries=0; asserts both assert_failure and a partial match on 'failed to fetch is-odd' to pin the failure mode. Previously-noted gap (exit-code-only check) is addressed.
test/fetch_settings.bats Adds a positive-path smoke test exercising all five new CLI flags with generous values against local Verdaccio; asserts success and node_modules presence.
aube.usage.kdl Inserts five new global flag declarations (alphabetically ordered) with long-help strings matching the Rust doc-comments; no structural issues.
docs/cli/index.md Auto-generated docs updated with sections for the five new flags; content mirrors the long-help strings accurately.
docs/cli/commands.json Generated JSON schema updated with five new flag entries; all fields (global, hide, arg.required) are consistent with existing flag definitions.
docs/settings/index.md Settings docs updated to surface the new CLI flag aliases and add two Examples: blocks; accurate and consistent with settings.toml changes.
test/PNPM_TEST_IMPORT.md Test tracking doc updated from 20/37 to 21/37 and the fetch-timeout-fails entry noted in the Done list; remaining work list accurate.

Reviews (4): Last reviewed commit: "[autofix.ci] apply automated fixes" | Re-trigger Greptile

Comment thread test/pnpm_install_misc.bats
Comment thread crates/aube/src/main.rs
jdx added a commit that referenced this pull request Apr 30, 2026
Addresses Greptile review on PR #436:

- Bats timeout test asserted only `assert_failure`, which would also
  pass for a clap parse error or missing fixture. Pin the failure to
  the registry-fetch path with `assert_output --partial "failed to
  fetch is-odd"` (the wrapper miette context emitted by `add.rs`).
  Greptile suggested asserting on the substring "timeout" verbatim,
  but reqwest's Display swallows the inner cause — the user-visible
  error reads `error sending request for url ...` without the word
  timeout, so we anchor on the aube-side wrapper instead.
- Doc-comment on `--fetch-retry-factor` now spells out that fractional
  factors are rejected (the underlying `FetchPolicy.retry_factor` is
  `u32`, matching `settings.toml`'s `int` type and the npmrc parser),
  so users coming from a "factors are floats" mental model see why
  clap rejects `1.5`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
jdx added a commit that referenced this pull request Apr 30, 2026
Addresses Greptile review on PR #436:

- Bats timeout test asserted only `assert_failure`, which would also
  pass for a clap parse error or missing fixture. Pin the failure to
  the registry-fetch path with `assert_output --partial "failed to
  fetch is-odd"` (the wrapper miette context emitted by `add.rs`).
  Greptile suggested asserting on the substring "timeout" verbatim,
  but reqwest's Display swallows the inner cause — the user-visible
  error reads `error sending request for url ...` without the word
  timeout, so we anchor on the aube-side wrapper instead.
- Doc-comment on `--fetch-retry-factor` now spells out that fractional
  factors are rejected (the underlying `FetchPolicy.retry_factor` is
  `u32`, matching `settings.toml`'s `int` type and the npmrc parser),
  so users coming from a "factors are floats" mental model see why
  clap rejects `1.5`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jdx jdx force-pushed the claude/blissful-jemison-883e49 branch from 0c4de33 to 78f3869 Compare April 30, 2026 22:57
@jdx jdx enabled auto-merge (squash) April 30, 2026 23:10
jdx and others added 4 commits April 30, 2026 18:11
Mirrors pnpm's global CLI surface for the registry transport knobs.
Previously these settings were reachable only through `.npmrc` /
`pnpm-workspace.yaml` / `NPM_CONFIG_*` env vars; the pnpm parity test
in `pnpm/test/install/misc.ts:508` ('installation fails with a timeout
error') passes them as `--fetch-timeout=1 --fetch-retries=0`, so we
need the same surface.

Wires the flags as global args on the top-level Cli, populates a
process-wide `FETCH_CLI_OVERRIDES` once from `async_main`, and threads
it into `resolve_fetch_policy` as the `ResolveCtx::cli` slice — the
existing settings codegen already orders `cli > env > npmrc >
workspaceYaml`. Adds the corresponding pnpm test port in
`pnpm_install_misc.bats` (11/37 in the install/misc.ts file) plus a
positive-path smoke test in `fetch_settings.bats` covering all five
new flags.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses Greptile review on PR #436:

- Bats timeout test asserted only `assert_failure`, which would also
  pass for a clap parse error or missing fixture. Pin the failure to
  the registry-fetch path with `assert_output --partial "failed to
  fetch is-odd"` (the wrapper miette context emitted by `add.rs`).
  Greptile suggested asserting on the substring "timeout" verbatim,
  but reqwest's Display swallows the inner cause — the user-visible
  error reads `error sending request for url ...` without the word
  timeout, so we anchor on the aube-side wrapper instead.
- Doc-comment on `--fetch-retry-factor` now spells out that fractional
  factors are rejected (the underlying `FetchPolicy.retry_factor` is
  `u32`, matching `settings.toml`'s `int` type and the npmrc parser),
  so users coming from a "factors are floats" mental model see why
  clap rejects `1.5`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jdx jdx force-pushed the claude/blissful-jemison-883e49 branch from 40f84d7 to a7a5c3f Compare April 30, 2026 23:14
@jdx jdx merged commit 63fcb9a into main Apr 30, 2026
18 checks passed
@jdx jdx deleted the claude/blissful-jemison-883e49 branch April 30, 2026 23:20
@github-actions
Copy link
Copy Markdown

Benchmark changes

Versions:

  • aube: 1.5.1 -> 1.5.2
  • pnpm: 11.0.2 -> 11.0.3

Public ratios: warm installs vs Bun 4x -> 3x; warm installs vs pnpm 5x -> 8x.

Benchmark aube bun pnpm
Fresh install (warm cache) 1021ms -> 718ms (-30%) 4134ms -> 2350ms (-43%) 4717ms -> 5394ms (+14%)
CI install (warm cache, GVS disabled) 2920ms -> 2443ms (-16%) 3396ms -> 3064ms (-10%) 4864ms -> 5837ms (+20%)
CI install (cold cache, GVS disabled) 10801ms -> 9359ms (-13%) 10012ms -> 9493ms (-5%) 9722ms -> 9227ms (-5%)

a7a5c3f vs 2ad5c54 | aube/bun/pnpm | 3 scenarios | 3 runs | 500mbit/50ms | generated by Codex.

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