Repository navigation
fix(task): normalize task cwd for source freshness - #11987
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited) Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe change normalizes task-specific working directories by removing ChangesTask working-directory freshness
Estimated code review effort: 2 (Simple) | ~10 minutes Mergeability Score: ⚪ Minimal · up to This localized change normalizes task working-directory paths so valid source files participate in freshness checks, with regression coverage included; no actionable merge-blocking risk remains beyond normal checks and review. Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile SummaryNormalizes lexical current-directory components in task working directories so relative source paths and glob results share the same representation during freshness checks.
Confidence Score: 5/5The PR appears safe to merge; no concrete correctness or security regressions were identified. Removing lexical current-directory components preserves resolved path semantics while aligning the task cwd with normalized source paths, and the added unit and end-to-end tests cover both rerun and fresh-skip behavior. Important Files Changed
Reviews (1): Last reviewed commit: "fix(task): normalize task cwd for source..." | Re-trigger Greptile |
Revert the task-cwd half of the normalizer reconciliation. `task_cwd`'s result is passed to `Command::current_dir`, so resolving `..` there lexically changes where the task actually runs: with `dir = "link/.."` mise executed in `<ws>/real` before and `<ws>` after, because the OS resolves `..` through the symlink at chdir time and a lexical pass does not. Collapsing `.` is safe because `a/./b` and `a/b` are the same directory to both. The `task_state_key` de-duplication that motivated the change was a convenience riding along on a bug fix and is not worth a silent change to where commands execute; nothing in the source-anchoring fix depends on it, since `normalize_pattern` normalizes the joined path itself. `normalize_task_cwd` is left exactly as jdx#11987 wrote it, and `lexical_normalize` now documents that it is for paths that are matched, not for a directory that gets chdir'd into. Inspect the pattern as written in the glob-collapse guard. Checking the path already joined onto `task_cwd` folded the task directory into the string being scanned, so a task in a directory whose literal name contains a glob metacharacter — `dir = "pkg*"` — made an ordinary `../shared/**` entry look like a `..` popping a glob. The pattern was then left unanchored and matched nothing. The guard only ever needed to see what the user wrote. Correct the `sources` documentation, which said relative entries resolve against the config file. They resolve against the task directory, which is the config file's directory only when the task has no `dir`. The separate rule for `[task_config.input_groups]` entries, which do resolve against their defining config, is documented where those are described and is unaffected. Co-Authored-By: Claude <noreply@anthropic.com>
Revert the task-cwd half of the normalizer reconciliation. `task_cwd`'s result is passed to `Command::current_dir`, so resolving `..` there lexically changes where the task actually runs: with `dir = "link/.."` mise executed in `<ws>/real` before and `<ws>` after, because the OS resolves `..` through the symlink at chdir time and a lexical pass does not. Collapsing `.` is safe because `a/./b` and `a/b` are the same directory to both. The `task_state_key` de-duplication that motivated the change was a convenience riding along on a bug fix and is not worth a silent change to where commands execute; nothing in the source-anchoring fix depends on it, since `normalize_pattern` normalizes the joined path itself. `normalize_task_cwd` is left exactly as jdx#11987 wrote it, and `lexical_normalize` now documents that it is for paths that are matched, not for a directory that gets chdir'd into. Inspect the pattern as written in the glob-collapse guard. Checking the path already joined onto `task_cwd` folded the task directory into the string being scanned, so a task in a directory whose literal name contains a glob metacharacter — `dir = "pkg*"` — made an ordinary `../shared/**` entry look like a `..` popping a glob. The pattern was then left unanchored and matched nothing. The guard only ever needed to see what the user wrote. Correct the `sources` documentation, which said relative entries resolve against the config file. They resolve against the task directory, which is the config file's directory only when the task has no `dir`. The separate rule for `[task_config.input_groups]` entries, which do resolve against their defining config, is documented where those are described and is unaffected. Co-Authored-By: Claude <noreply@anthropic.com>
Revert the task-cwd half of the normalizer reconciliation. `task_cwd`'s result is passed to `Command::current_dir`, so resolving `..` there lexically changes where the task actually runs: with `dir = "link/.."` mise executed in `<ws>/real` before and `<ws>` after, because the OS resolves `..` through the symlink at chdir time and a lexical pass does not. Collapsing `.` is safe because `a/./b` and `a/b` are the same directory to both. The `task_state_key` de-duplication that motivated the change was a convenience riding along on a bug fix and is not worth a silent change to where commands execute; nothing in the source-anchoring fix depends on it, since `normalize_pattern` normalizes the joined path itself. `normalize_task_cwd` is left exactly as jdx#11987 wrote it, and `lexical_normalize` now documents that it is for paths that are matched, not for a directory that gets chdir'd into. Inspect the pattern as written in the glob-collapse guard. Checking the path already joined onto `task_cwd` folded the task directory into the string being scanned, so a task in a directory whose literal name contains a glob metacharacter — `dir = "pkg*"` — made an ordinary `../shared/**` entry look like a `..` popping a glob. The pattern was then left unanchored and matched nothing. The guard only ever needed to see what the user wrote. Correct the `sources` documentation, which said relative entries resolve against the config file. They resolve against the task directory, which is the config file's directory only when the task has no `dir`. The separate rule for `[task_config.input_groups]` entries, which do resolve against their defining config, is documented where those are described and is unaffected. Co-Authored-By: Claude <noreply@anthropic.com>
Summary
dir = "./relative"Root cause
The task working directory retained the lexical
./component, while glob expansion returned normalized source paths. The source matcher therefore filtered out valid task-directory-relative sources, leaving only the task definition in the freshness hash and causing changed inputs to be skipped.Fixes the bug reported in #11977.
Validation
cargo test --bin mise task::task_source_checker::tests::relative_sources_match_when_task_dir_starts_with_dot -- --exactmise run test:e2e e2e/tasks/test_task_source_freshness_with_cwdmise run lint-fixcargo clippy --workspace --all-features --all-targets -- -D warningsAI-assisted — Tool: Codex; model: openai/gpt-5; version: unavailable.
Note
Low Risk
Small, localized path normalization in task CWD resolution with targeted tests; no auth, data, or broad API changes.
Overview
Fixes source/output freshness when a task uses a static
dirwith a leading./(e.g.dir = "./relative"). The effective working directory kept a lexical.segment while enumerated source paths were normalized, so the source matcher dropped task-relative files and tasks could stay skipped after inputs changed.task_cwdnow strips current-directory (./) components vianormalize_task_cwdwhile leaving..and other path semantics unchanged. Regression coverage adds a unit test for./suband an e2e scenario forrelative_dirwithsources/outputs.Reviewed by Cursor Bugbot for commit e187af7. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
Bug Fixes
./.Tests