feat(prepare): add --explain flag for provider diagnostics#8409
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a --explain flag to mise prepare for diagnosing provider freshness, which is a great addition for usability and scripting. The implementation is solid, introducing a FreshnessResult enum for structured freshness checks and detailed reasons. The e2e tests are comprehensive. I've made a couple of suggestions to improve code quality by removing an explicit exit call in favor of standard error handling and pointing out some potentially unreachable code. Overall, this is a well-executed feature.
| miseprintln!("Provider '{}' not found", provider_id); | ||
| miseprintln!(""); | ||
| miseprintln!("Available providers:"); | ||
| for p in engine.list_providers() { | ||
| miseprintln!(" {}", p.id()); | ||
| } | ||
| std::process::exit(1); |
There was a problem hiding this comment.
Calling std::process::exit here makes the function harder to test and reuse. It's better to return a Result and let the caller handle exiting. You can use eyre::bail! to return an error with a formatted message.
You'll need to add use itertools::Itertools; at the top of the file.
| miseprintln!("Provider '{}' not found", provider_id); | |
| miseprintln!(""); | |
| miseprintln!("Available providers:"); | |
| for p in engine.list_providers() { | |
| miseprintln!(" {}", p.id()); | |
| } | |
| std::process::exit(1); | |
| let available_providers = engine | |
| .list_providers() | |
| .iter() | |
| .map(|p| format!(" {}", p.id())) | |
| .collect::<Vec<_>>() | |
| .join("\n"); | |
| eyre::bail!("Provider '{}' not found.\n\nAvailable providers:\n{}", provider_id, available_providers); |
| (_, None) => Ok(FreshnessResult::OutputsMissing( | ||
| "outputs do not exist".to_string(), | ||
| )), |
There was a problem hiding this comment.
This match arm appears to be unreachable. The loop at lines 455-462 checks for missing outputs and returns early if any are found. If execution reaches this point, it means all output paths exist, so Self::last_modified(&outputs) should always return Some, making outputs_mtime always Some. You can likely remove this arm.
Greptile Summaryadds Key Changes
Implementation Quality
Confidence Score: 5/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
Start[check_freshness] --> CheckOutputs{outputs.is_empty?}
CheckOutputs -->|yes| NoOutputs[Return NoOutputs]
CheckOutputs -->|no| CheckSession{any output in STALE_OUTPUTS?}
CheckSession -->|yes| SessionStale[Return SessionStale]
CheckSession -->|no| CheckExists{all outputs exist?}
CheckExists -->|no| Missing[Return OutputsMissing]
CheckExists -->|yes| GetMtimes[Get sources & outputs mtimes]
GetMtimes --> Match{Match mtimes}
Match -->|src > out| Stale[Return Stale]
Match -->|src <= out| Fresh[Return Fresh]
Match -->|no sources| NoSources[Return NoSources]
Match -->|outputs unreadable| MissingFallback[Return OutputsMissing]
Last reviewed commit: 937dd23 |
| .map(|p| p.as_ref()) | ||
| } | ||
|
|
||
| /// Check freshness for a specific provider (public API for --why) |
11aa4f0 to
da3c742
Compare
|
bugbot run |
Add `mise prepare --explain <provider>` to show detailed diagnostic info about a specific provider: sources, outputs, command, auto status, and fresh/stale verdict with reason. Exit code 0 if fresh, 1 if stale. Also adds FreshnessResult enum for structured freshness checking with human-readable stale reasons shown in dry-run output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix check_staleness unwrap_or(true) -> unwrap_or(false) to preserve "assume fresh on error" behavior and avoid spurious stale warnings - Replace std::process::exit with bail! in explain_provider - Fix unreachable (_, None) match arm to use Stale instead of OutputsMissing since missing outputs are already handled above - Fix comment referencing --why instead of --explain Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change `mise prepare --explain <provider>` to `mise prepare <provider> --explain`. The positional provider argument also works without --explain to run just that provider (like --only). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reorder struct fields so long-only flags appear in alphabetical order: --explain, --list, --only, --skip. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes test_subcommands_are_sorted failure by reordering struct fields so -f (force) comes before -n (dry-run). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
b0e4ee7 to
e2580f1
Compare
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.24 x -- echo |
28.4 ± 1.0 | 27.4 | 39.2 | 1.19 ± 0.06 |
mise x -- echo |
24.0 ± 0.8 | 22.6 | 29.7 | 1.00 |
✅ Performance improvement for x -- echo is 19% |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.24 env |
28.0 ± 0.7 | 27.0 | 32.7 | 1.21 ± 0.04 |
mise env |
23.2 ± 0.4 | 22.4 | 25.7 | 1.00 |
✅ Performance improvement for env is 21% |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.24 hook-env |
29.1 ± 0.8 | 27.9 | 39.6 | 1.17 ± 0.05 |
mise hook-env |
24.8 ± 0.8 | 23.2 | 30.2 | 1.00 |
✅ Performance improvement for hook-env is 17% |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.2.24 ls |
24.2 ± 0.8 | 22.4 | 29.5 | 1.02 ± 0.04 |
mise ls |
23.6 ± 0.5 | 21.5 | 27.7 | 1.00 |
xtasks/test/perf
| Command | mise-2026.2.24 | mise | Variance |
|---|---|---|---|
| install (cached) | 167ms | 154ms | +8% |
| ls (cached) | 91ms | 83ms | +9% |
| bin-paths (cached) | 99ms | ✅ 88ms | +12% |
| task-ls (cached) | 856ms | 845ms | +1% |
✅ Performance improvement: bin-paths cached is 12%
### 🚀 Features - **(hooks)** add task references to hooks and watch_files by @jdx in [#8400](#8400) - **(prepare)** add git-submodule built-in provider by @jdx in [#8407](#8407) - **(prepare)** add human-readable stale reasons to prepare output by @jdx in [#8408](#8408) - **(prepare)** add dependency ordering to prepare steps by @jdx in [#8401](#8401) - **(prepare)** add --explain flag for provider diagnostics by @jdx in [#8409](#8409) - **(prepare)** add per-provider timeout support by @jdx in [#8405](#8405) - **(prepare)** add blake3 content-hash freshness checking by @jdx in [#8404](#8404) - **(tasks)** monorepo vars and per-task vars by @halms in [#8248](#8248) ### 🐛 Bug Fixes - **(aqua)** restore bin_paths disk cache with fresh_file invalidation by @jdx in [#8398](#8398) - **(idiomatic)** use generic parser for idiomatic files by @risu729 in [#8171](#8171) - **(install)** apply precompiled options to all platforms in lockfile by @jdx in [#8396](#8396) - **(install)** normalize "v" prefix when matching lockfile versions by @jdx in [#8413](#8413) - **(prepare)** improve git submodule parser and fix check_staleness error handling by @jdx in [#8412](#8412) - **(python)** respect precompiled settings in lock file generation by @jdx in [#8399](#8399) - **(python)** clarify uv_venv_auto docs + prevent uv shim recursion in venv creation by @halms in [#8402](#8402) - **(task)** remove deprecated `# mise` task header syntax by @jdx in [#8403](#8403) - **(vfox)** avoid eager metadata loading during config file detection by @jdx in [#8397](#8397) - clarify GitHub attestations to be artifact ones by @scop in [#8394](#8394) - ignore comments in idiomatic version files by @iloveitaly in [#7682](#7682) ### 🚜 Refactor - unify archive detection by @risu729 in [#8137](#8137) ### 📚 Documentation - remove duplicated docs for npm.package_manager by @risu729 in [#8414](#8414)
Summary
mise prepare --explain <provider>flag to show detailed diagnostic info about a specific prepare providerFreshnessResultenum for structured freshness checking with human-readable stale reasons in dry-run outputTest plan
--explainwith stale provider (missing output)--explainwith fresh provider--explainwith unknown provider🤖 Generated with Claude Code
Note
Low Risk
Primarily adds an experimental CLI flag and supporting output paths; the main behavior change is new positional provider filtering and
--explainreturning non-zero when stale.Overview
Adds provider-level diagnostics to
mise preparevia a new--explainmode and an optional positional[PROVIDER]argument to target a single prepare provider.--explainprints the provider’s sources/outputs (with existence markers), auto status, command, and a fresh/stale verdict (exiting non-zero when stale), backed by newPrepareEngineAPIs to find a provider and expose its freshness check.Updates generated CLI docs/man page/fig completions to reflect the new argument/flag and extends
e2e/cli/test_prepareto cover--explainfor fresh, stale, and unknown providers.Written by Cursor Bugbot for commit e2580f1. This will update automatically on new commits. Configure here.