Skip to content

feat(deps): add depends field for user-specified tool dependencies#8776

Merged
jdx merged 8 commits intojdx:mainfrom
cprecioso:cprecioso/tool-depends-field
Apr 4, 2026
Merged

feat(deps): add depends field for user-specified tool dependencies#8776
jdx merged 8 commits intojdx:mainfrom
cprecioso:cprecioso/tool-depends-field

Conversation

@cprecioso
Copy link
Copy Markdown
Contributor

@cprecioso cprecioso commented Mar 26, 2026

Allow users to declare explicit installation dependencies between tools in mise.toml, ensuring one tool is fully installed before another starts.

Note

This code in this PR was mainly AI-written. I understand the changes generally but I might be missing nuances since I don't know Rust or the Mise codebase very well. I intend to see the PR through, but feel free to close if it's too far away from workable (although I don't think it is).

Allow users to declare explicit installation dependencies between tools
in mise.toml, ensuring one tool is fully installed before another starts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, 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 enhances the tool management system by enabling users to declare explicit installation dependencies between tools. This feature addresses scenarios where one tool requires another to be fully installed beforehand, such as a package manager needing its language runtime. By introducing a depends field in the configuration, the system can now intelligently order tool installations, leading to more robust and predictable environments. The changes span configuration parsing, dependency graph construction, and user documentation.

Highlights

  • User-specified Tool Dependencies: Introduced a new depends field in mise.toml tool configurations, allowing users to explicitly define installation order for tools. This ensures that a tool's prerequisites are installed before the tool itself.
  • Dependency Resolution Logic: Implemented logic to incorporate user-defined dependencies into the tool installation dependency graph, ensuring correct sequencing and preventing installation failures due to missing prerequisites.
  • Documentation and Schema Updates: Added comprehensive documentation for the new depends field, including usage examples, and updated the mise.json schema to reflect this new configuration option.
  • End-to-End Testing: New end-to-end tests were added to validate the functionality of the depends field, covering successful dependency resolution and the detection of circular dependencies.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new depends field for tool configurations, enabling users to specify explicit installation dependencies between tools. This ensures that tools are installed in the correct order, preventing issues where a tool might require another to be present during its installation. The changes involve updating the documentation, JSON schema, and the parsing logic for mise.toml to handle the new depends field, which can accept a single string or an array of strings. The dependency resolution logic in ToolDeps was enhanced to incorporate these user-defined dependencies into the installation graph. New end-to-end tests and a needs-dummy plugin were added to validate the functionality, including correct installation ordering and circular dependency detection. A review comment emphasized the importance of including the depends field in the Hash implementation for ToolVersionOptions to ensure correctness in hash-based collections.

impl std::hash::Hash for ToolVersionOptions {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.os.hash(state);
self.depends.hash(state);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Adding self.depends.hash(state); to the Hash implementation for ToolVersionOptions is crucial for correctness. Without this, two ToolVersionOptions instances with identical fields except for depends would produce the same hash, leading to incorrect behavior in hash-based collections like HashMap or HashSet where depends is a significant part of the options.

autofix-ci bot and others added 3 commits March 26, 2026 12:20
The needs-dummy plugin requires dummy to be installed first, enabling
the e2e test to verify that `depends` prevents race conditions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cprecioso cprecioso marked this pull request as ready for review March 26, 2026 14:03
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 26, 2026

Greptile Summary

This PR adds a depends field to tool definitions in mise.toml, letting users declare explicit installation ordering constraints between tools (e.g. ensuring python is fully installed before pipx:ruff starts). It introduces a new ToolDeps struct wrapping the existing DepsGraph, extends ToolVersionOptions with a depends named field, updates both TOML deserialization paths, adds schema and documentation, and ships a needs-dummy test plugin to validate the ordering guarantee end-to-end.

Key changes:

  • src/toolset/tool_deps.rs — new file that builds a dependency graph from both backend-declared and user-specified depends edges; emits a warn! when a named dependency is not part of the current install set
  • src/toolset/tool_version_options.rs — adds depends: Option<Vec<String>> named field, updates Hash, is_empty(), and EPHEMERAL_OPT_KEYS
  • src/config/config_file/mise_toml.rs — both deserialization paths handle string / array forms with actionable error messages for invalid types
  • e2e/cli/test_tool_depends + test/data/plugins/needs-dummy/ — new e2e test using a plugin that verifies dummy is on-disk before installing, though the "without depends" failure assertion relies on a race condition and may be non-deterministic
  • schema/mise.json + documentation — correctly reflect the new field as oneOf string or string array

Confidence Score: 4/5

Feature logic is correct and well-integrated, but the e2e test has a race-condition assertion that is not guaranteed to be reliable.

The core implementation — parsing, graph construction, ordering, and error handling — is sound. The previously flagged issues have been addressed. The one concrete P1 remaining is the assert_fail "mise install" line in the new e2e test: it expects a guaranteed failure that depends on a concurrent race, which is not deterministic across CPU count / job settings and could produce persistent flakiness in CI. Resolving the flaky test assertion before merge is recommended.

e2e/cli/test_tool_depends — the first assert_fail block needs a deterministic failure path. src/toolset/tool_version_options.rs — the is_empty() inconsistency between os and depends is worth aligning.

Important Files Changed

Filename Overview
src/toolset/tool_deps.rs New file implementing the dependency graph for tool installation ordering. Correctly wires user-specified depends edges and emits a warn! when a named dependency is absent from the current install set. Core logic is sound.
src/toolset/tool_version_options.rs Adds depends: Option<Vec<String>> named field with proper hashing; is_empty() now includes depends but still omits os, leaving a pre-existing inconsistency more visible. EPHEMERAL_OPT_KEYS addition is correct for the flat-map path.
src/config/config_file/mise_toml.rs Both deserialization paths (MiseTomlToolList and MiseTomlTool) handle depends as string or array with proper error messages for invalid types, addressing the prior unwrap() concern.
e2e/cli/test_tool_depends New e2e test. The positive case (with depends) and the circular-dependency detection are solid, but the first assert_fail relies on a race condition that is not guaranteed to trigger, making the test potentially flaky.
test/data/plugins/needs-dummy/bin/install Helper plugin that verifies dummy is installed before installing itself, correctly simulating a runtime dependency for the e2e test.

Sequence Diagram

sequenceDiagram
    participant Config as mise.toml parser
    participant TVO as ToolVersionOptions
    participant TD as ToolDeps (new)
    participant DG as DepsGraph
    participant Installer as Toolset installer

    Config->>TVO: deserialize [tools] entry with depends=["python"]
    TVO-->>Config: ToolVersionOptions { depends: Some(["python"]) }

    Installer->>TD: ToolDeps::new(requests)
    TD->>DG: build edges from backend deps
    TD->>TVO: read tr.options().depends per request
    TD->>DG: push user edge (pipx:ruff → python)
    DG-->>TD: DepsGraph with ordering constraints

    loop install loop
        TD->>Installer: subscribe() → ready tool
        Installer->>Installer: install tool
        Installer->>TD: complete_success(tr) / complete_failure(tr)
        TD->>DG: unblock dependents or propagate failure
    end
Loading

Greploops — Automatically fix all review issues by running /greploops in Claude Code. It iterates: fix, push, re-review, repeat until 5/5 confidence.
Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal.

Reviews (5): Last reviewed commit: "chore: merge origin/main into cprecioso/..." | Re-trigger Greptile

cprecioso and others added 2 commits March 26, 2026 15:17
- Return proper deserialization error for non-string depends array
  elements instead of panicking via unwrap()
- Warn when a depends target is not in the current install set
- Include os in is_empty() check for consistency with depends

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
cprecioso and others added 2 commits March 26, 2026 18:05
Adding os to is_empty() would change option-merging semantics for
existing os-only configs in toolset_install.rs, which is out of scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jdx jdx enabled auto-merge (squash) April 4, 2026 16:35
@jdx jdx merged commit f60f0e8 into jdx:main Apr 4, 2026
35 checks passed
jdx pushed a commit that referenced this pull request Apr 5, 2026
### 🚀 Features

- **(ci)** auto-convert external PRs to draft mode by @jdx in
[#8896](#8896)
- **(deps)** add `depends` field for user-specified tool dependencies by
@cprecioso in [#8776](#8776)
- **(dotnet)** support runtime-only installs by @fragon10 in
[#8524](#8524)
- **(npm)** apply install_before to transitive dependencies by @risu729
in [#8851](#8851)
- **(task)** allow passing arguments to task dependencies via
{{usage.*}} templates by @jdx in
[#8893](#8893)
- add options field to BackendListVersionsCtx by @esteve in
[#8875](#8875)

### 🐛 Bug Fixes

- **(backend)** filter PEP 440 .dev versions in fuzzy version matching
by @richardthe3rd in [#8849](#8849)
- **(ci)** update COPR BuildRequires rust version to match MSRV 1.88 by
@jdx in [#8911](#8911)
- **(ci)** add Ruby build dependencies to e2e Docker image by @jdx in
[#8910](#8910)
- **(ci)** add missing build dependencies to e2e Docker image by @jdx in
[#8912](#8912)
- **(ci)** add missing build dependencies to e2e Docker image by @jdx in
[#8914](#8914)
- **(ci)** use Node 24 LTS for corepack e2e test by @jdx in
[#8915](#8915)
- **(ci)** add libxml2 and pkg-config to e2e Docker image by @jdx in
[#8917](#8917)
- **(ci)** add libxml2-dev to e2e image and disable Swift SPM tests by
@jdx in [#8918](#8918)
- **(docs)** use sans-serif font for badges by @jdx in
[#8887](#8887)
- **(env)** parse --env=VALUE and -E=VALUE flag forms correctly by @jdx
in [#8889](#8889)
- **(exec)** use i64::from() for seccomp syscall numbers to survive
autofix by @jdx in [#8882](#8882)
- **(github)** preserve tool options like filter_bins when version
specified via CLI by @jdx in
[#8888](#8888)
- **(github)** use alias-specific options when tool_alias has its own
config by @jdx in [#8892](#8892)
- **(install)** add locked_verify_provenance setting and detect github
attestations at lock time by @jdx in
[#8901](#8901)
- **(lock)** prune stale version entries during filtered `mise lock
<tool>` runs by @altendky in
[#8599](#8599)
- **(python)** use lockfile URL for precompiled installs by @hehaoqian
in [#8750](#8750)
- **(release)** verify all build targets succeed before releasing by
@jdx in [#8886](#8886)
- **(ruby)** support build revisions for precompiled binaries in
mise.lock by @jdx in [#8900](#8900)
- **(swift)** fall back to Ubuntu 24.04 for unsupported Ubuntu versions
by @jdx in [#8916](#8916)
- **(zsh)** avoid duplicate trust warning after cd by @timothysparg in
[#8898](#8898)
- update flake.lock and add fix for rust-bindgen to default.nix by
@esteve in [#8874](#8874)
- when direnv diff is empty, do not try to parse it by @yaleman in
[#8857](#8857)
- skip trust check for plain .tool-versions in task list by @dportalesr
in [#8876](#8876)

### 🚜 Refactor

- **(go)** rename go_* settings to go.* namespace by @jdbruijn in
[#8598](#8598)

### 📚 Documentation

- **(tasks)** clarify task_config.includes behavior by @risu729 in
[#8905](#8905)

### 🧪 Testing

- **(ci)** run e2e tests inside Docker containers by @jdx in
[#8899](#8899)

### 📦️ Dependency Updates

- bump ubi from 0.8 to 0.9 by @jdx in
[#8906](#8906)
- bump zip from 3 to 8 by @jdx in
[#8908](#8908)
- update lockfile deps (hold back rattler) by @jdx in
[#8909](#8909)
- update bun.lock by @jdx in
[#8913](#8913)

### 📦 Registry

- add turso
([github:tursodatabase/turso-cli](https://github.com/tursodatabase/turso-cli))
by @kenn in [#8884](#8884)
- remove carp test by @jdx in
[#8894](#8894)

### Chore

- **(ci)** add workflow to warn PRs modifying vendored aqua-registry by
@jdx in [#8897](#8897)
- **(ci)** use github.token for draft conversion in auto-draft workflow
by @jdx in [#8903](#8903)
- remove deprecated settings older than 12 months by @jdx in
[#8904](#8904)

### New Contributors

- @dportalesr made their first contribution in
[#8876](#8876)
- @timothysparg made their first contribution in
[#8898](#8898)
- @hehaoqian made their first contribution in
[#8750](#8750)
- @jdbruijn made their first contribution in
[#8598](#8598)
- @cprecioso made their first contribution in
[#8776](#8776)
- @yaleman made their first contribution in
[#8857](#8857)
- @kenn made their first contribution in
[#8884](#8884)
- @fragon10 made their first contribution in
[#8524](#8524)

## 📦 Aqua Registry Updates

#### New Packages (6)

- [`ahkohd/oyo`](https://github.com/ahkohd/oyo)
- [`bellicose100xp/jiq`](https://github.com/bellicose100xp/jiq)
- [`kurama/dealve-tui`](https://github.com/kurama/dealve-tui)
- [`micahkepe/jsongrep`](https://github.com/micahkepe/jsongrep)
- [`textfuel/lazyjira`](https://github.com/textfuel/lazyjira)
- [`ubugeeei/vize`](https://github.com/ubugeeei/vize)

#### Updated Packages (1)

- [`sigstore/cosign`](https://github.com/sigstore/cosign)
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.

2 participants