Conversation
Handle `uv run` as a transparent prefix (like `sudo` or `env`) in both `classify_command` and `rewrite_segment`. The inner command is matched against existing rules, and `uv run` is preserved in the rewritten output so the virtualenv stays active: uv run pytest tests/ -v → uv run rtk pytest tests/ -v uv run ruff check . → uv run rtk ruff check . uv run python -m pytest → uv run rtk pytest tests/ This is the #1 unhandled command in `rtk discover` (1,062 occurrences over 30 days). The approach is complementary to #176 which adds a first-class `rtk uv` command — this PR requires no new command handler since rtk runs inside `uv run` and filters output normally.
pszymkowiak
left a comment
There was a problem hiding this comment.
Thanks @lgbarn — good direction, uv run as transparent prefix is the right idea. A few things to fix before merge.
Blocker: retarget to develop, not master. All feature work goes through develop first.
P0 — 3 bugs:
1. uv run --frozen pytest tests/ misclassified as Unsupported
strip_uv_run_prefix only strips the literal "uv run ". Real-world usage often has uv flags (--frozen, --no-dev, --with pkg, --python 3.12). After stripping, --frozen pytest tests/ doesn't match any rule. Guard with:
// Bail if next token is a uv flag, not an inner command
Some(rest) if !rest.starts_with('-') => Cow::Borrowed(rest),2. uv run alone (no inner command)
No test, fragile path through empty string. Add a test:
assert_eq!(rewrite_command("uv run", &[]), None);3. PYTHONPATH=. uv run pytest tests/ not rewritten
uv run strip runs before ENV_PREFIX strip. cmd_part starts with PYTHONPATH=, so "uv run " prefix doesn't match. Fix: strip env prefix first, then detect uv run.
P1 — design consideration:
The existing rewrite_prefixes array in rules.rs already handles multi-word prefixes ("python -m pytest" → rtk pytest). Adding "uv run pytest", "uv run ruff check", "uv run mypy" to each rule's prefixes would achieve the same result with zero pipeline changes. If you prefer the general approach, consider a data-driven transparent_prefixes field in RewriteRule instead of ad-hoc functions.
Missing tests: uv run --frozen pytest, PYTHONPATH=. uv run pytest, uv run python -m pytest, RTK_DISABLED=1 uv run pytest, uv run pytest 2>&1.
Fix the P0s and retarget to develop, and this is ready.
Address PR #1044 review feedback: P0-1: strip_uv_run_prefix now skips uv-specific flags (--frozen, --with pkg, --python ver, etc.) to find the inner command. Previously "uv run --frozen pytest" was misclassified as Unsupported. P0-2: Add test for "uv run" alone (no inner command) → returns None. P0-3: Add test for env prefix + uv run ("PYTHONPATH=. uv run pytest") confirming correct rewrite ordering. New helper split_uv_run() extracts (prefix_with_flags, inner_command) and is shared by both classify_command and rewrite_segment paths. Added tests: --frozen, --with <pkg>, env prefix, RTK_DISABLED, redirect.
lgbarn
left a comment
There was a problem hiding this comment.
Thanks for the detailed review @pszymkowiak — all 3 P0s are addressed in the second commit (d08a3c4):
P0-1 ✓ — split_uv_run() now skips uv flags (--frozen, --with pkg, -p 3.12, etc.) before finding the inner command. Tests: test_classify_uv_run_frozen_pytest, test_rewrite_uv_run_frozen_pytest, test_rewrite_uv_run_with_pkg_pytest.
P0-2 ✓ — split_uv_run() returns None when no inner command follows the flags. Test: test_rewrite_uv_run_alone.
P0-3 ✓ — rewrite_segment now strips env prefix before detecting uv run, so PYTHONPATH=. uv run pytest rewrites correctly. Test: test_rewrite_env_prefix_uv_run_pytest.
Retarget ✓ — Base branch is develop.
On the P1 (data-driven transparent_prefixes): I considered adding it to RewriteRule, but uv run is the only transparent prefix today, and generalizing it introduces complexity without a second use case to validate the design. The bespoke split_uv_run is ~40 lines, well-tested, and easy to rip out if #176 lands a first-class rtk uv handler. If another transparent prefix shows up (e.g., poetry run, pipenv run), happy to refactor into a data-driven field at that point.
Ready for re-review when you get a chance.
Summary
uv runas a transparent prefix (likesudo/env) in bothclassify_commandandrewrite_segmentuv runis preserved so the virtualenv stays activeMotivation
uv runis the #1 unhandled command inrtk discover— 1,062 occurrences over 30 days. Sinceuv runis just a virtualenv wrapper, the real command follows it and can be matched by existing RTK rules.Relationship to #176
PR #176 takes a different approach: a first-class
rtk uvcommand with subcommand dispatch (uv run pytest→rtk uv run pytest). This PR is complementary — it treatsuv runas a transparent prefix so no new command handler is needed. RTK runs insideuv runand filters output normally. If #176 lands first, this PR's approach can be superseded.Changes
src/discover/registry.rsstrip_uv_run_prefix()inclassify_command; adduv_prefixpreservation inrewrite_segmentformat stringsDesign decisions
strip_uv_run_prefixavoids allocation when no prefix is present (majority of commands)uv runin output ensures the virtualenv is active when RTK invokes the inner tool. Verified:uv run rtk --versionworks since RTK is in global PATHuv runand captures/filters output normallyTest plan
cargo test uv_run— 6 new tests pass (classify + rewrite for pytest, ruff, mypy, python -m pytest)cargo test— 1259 passed, 3 ignored, 0 faileduv pip listrewrite unchanged (stillrtk pip list)uv run rtk --versionconfirms RTK is accessible insideuv runCloses #294 (partial — covers
uv runprefix stripping)