Skip to content

fix(conda): exclude transitive dependency binaries from PATH #8543

Merged
jdx merged 3 commits intojdx:mainfrom
simonepri:feat/conda-filter-bins
Mar 10, 2026
Merged

fix(conda): exclude transitive dependency binaries from PATH #8543
jdx merged 3 commits intojdx:mainfrom
simonepri:feat/conda-filter-bins

Conversation

@simonepri
Copy link
Copy Markdown
Contributor

@simonepri simonepri commented Mar 9, 2026

Problem

Conda packages pull in dependencies that install many binaries onto PATH. For example,
conda:postgresql installs not only psql but also 70+ dependency binaries like
clear, reset, tput, tabs (from ncurses), ldapadd (from openldap), kinit
(from krb5), etc. that shadow standard system commands.

Solution

Instead of exposing the entire bin/ directory (which contains binaries from all
packages), the conda backend now automatically exposes only binaries from the main
package
.

This works by capturing the Vec<PathsEntry> return value from rattler's
link_package() — which lists every file installed by a specific package — and
filtering for entries under bin/. Only those are symlinked into .mise-bins/, which
is what gets added to PATH.

  • No user configuration needed — this is automatic for all conda installs
  • Transitive dependency binaries remain installed (packages that need them can still
    find them) but are not on PATH
  • Falls back to the full bin/ directory for tools installed before this change

Validation

For the conda:postgresql:

  • before (106 binaries on PATH): psql, pg_dump, ... clear, reset, tput, ldapadd, kinit, c_rehash, ...
  • after (36 binaries on PATH): psql, pg_dump, createdb, dropdb, initdb, pg_ctl, postgres, ...

@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 addresses the issue of Conda packages installing numerous binaries that can shadow system commands, leading to unexpected behavior. It introduces a filter_bins option, similar to the GitHub backend, which allows users to explicitly define which binaries from a Conda package should be exposed on their PATH. This provides granular control over installed executables, preventing conflicts and maintaining system integrity.

Highlights

  • New filter_bins option: Introduced a filter_bins option for the Conda backend, allowing users to specify a comma-separated list of binaries to symlink into a filtered .mise-bins directory.
  • Binaries filtering logic: Implemented get_filter_bins() to parse the filter_bins option, supporting both generic and platform-specific keys, and create_symlink_bin_dir() to manage the creation of symlinks for specified binaries.
  • Integration into install process: Hooked the binary filtering logic into both install_fresh() and install_from_locked() post-installation steps to ensure filtered binaries are created correctly.
  • PATH management: Updated list_bin_paths() to return only the .mise-bins directory when filter_bins is active, preventing unwanted binaries from being exposed on PATH.
  • Documentation update: Added comprehensive documentation for the new filter_bins option in the Conda backend, including usage examples.
Changelog
  • docs/dev-tools/backends/conda.md
    • Added a new section detailing the filter_bins option.
    • Provided an example of how to use filter_bins with conda:postgresql.
    • Explained the behavior of filter_bins regarding symlink creation and PATH exposure.
  • src/backend/conda.rs
    • Imported lookup_platform_key for platform-specific option handling.
    • Integrated create_symlink_bin_dir calls into install_fresh and install_from_locked methods.
    • Implemented get_filter_bins to parse the filter_bins configuration from tool version options.
    • Added create_symlink_bin_dir function to create a .mise-bins directory and symlink only specified binaries.
    • Modified list_bin_paths to prioritize the .mise-bins directory if filter_bins is configured.
Activity
  • No activity (comments, reviews, or progress updates) was provided in the context for this pull request.
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.

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

  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.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 9, 2026

Greptile Summary

This PR solves a real usability problem with the conda backend: packages like postgresql were polluting PATH with 70+ transitive-dependency binaries (e.g., clear, kinit, ldapadd). The fix captures the Vec<PathsEntry> return value from rattler's link_package() to identify which files belong to the main package, symlinks only its bin/ entries into a new .mise-bins/ directory, and points PATH at that directory. Legacy installs (pre-.mise-bins) automatically fall back to the original full bin/ directory.

The core feature works correctly and the PR description's validation confirms it for the target case (postgresql: 106 → 36 binaries). Two edge-case concerns remain:

  1. Missing source files are skipped silently — if a file is listed in rattler's PathsEntry but missing from disk (e.g., permission error during installation), no warning is logged, making it hard to diagnose incomplete installs.
  2. Empty .mise-bins directory suppresses the legacy fallback — if all source-file checks fail or the main package has no binaries, .mise-bins is created but empty. On the next run, list_bin_paths detects the directory and returns it instead of falling back to the full bin/ directory, silently hiding the failure.

Confidence Score: 4/5

  • Safe to merge with understanding that edge cases around missing/inaccessible files and empty bin directories have silent failure modes rather than explicit warnings.
  • The core feature is well-implemented and validated in the PR description (postgresql: 106 → 36 binaries on PATH). The install_fresh path identifies the main package with explicit checks; install_from_locked relies on careful ordering but works correctly as designed. Two edge cases remain: silent skips when source files are missing (affects diagnostics), and empty .mise-bins suppressing the fallback (silent failure mode). Neither prevents core functionality in normal scenarios, but both could confuse users in failure cases.
  • src/backend/conda.rs — consider adding diagnostics for missing source files and checking for non-empty .mise-bins before returning it as a bin path.

Last reviewed commit: 70e7167

Comment thread src/backend/conda.rs Outdated
Comment thread src/backend/conda.rs Outdated
Comment thread src/backend/conda.rs Outdated
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 filter_bins support to the conda backend, a valuable feature for managing binaries from conda packages. However, it also introduces a critical path traversal vulnerability where user-supplied binary names are used to construct filesystem paths without proper sanitization, potentially leading to arbitrary file overwrite or deletion during tool installation. While the implementation includes updates to the installation process and list_bin_paths, there are also suggestions to improve maintainability and efficiency. It is crucial to address the path traversal by validating that all binary names are relative and remain within the intended directories.

Comment thread src/backend/conda.rs Outdated
Comment thread src/backend/conda.rs Outdated
Comment thread src/backend/conda.rs Outdated
@jdx
Copy link
Copy Markdown
Owner

jdx commented Mar 9, 2026

Conda packages often pull in dependencies that install many binaries onto PATH. For example, conda:postgresql installs not only psql but also hundreds of dependency binaries like clear, reset, tput, tabs, and other ncurses utilities that shadow standard system commands. Running clear after installing conda:postgresql can break your terminal because it picks up the conda-provided ncurses clear instead of the system one.

I think this is the wrong solution to this problem, we shouldn't put transitive deps on PATH.

@simonepri
Copy link
Copy Markdown
Contributor Author

Thanks for taking a look at this already @jdx! What do you recommend?

## Problem

Conda packages often pull in dependencies that install many binaries onto PATH. For example, `conda:postgresql` installs not only `psql` but also hundreds of dependency binaries like `clear`, `reset`, `tput`, `tabs`, and other ncurses utilities that shadow standard system commands. Running `clear` after installing `conda:postgresql` can break your terminal because it picks up the conda-provided ncurses `clear` instead of the system one.

There is currently no way to control which binaries from a conda package are exposed on PATH.

## Solution

Add `filter_bins` support to the conda backend, matching the existing implementation in the GitHub backend. When `filter_bins` is specified, only the listed binaries are symlinked into a `.mise-bins` directory, and `list_bin_paths` returns only that directory instead of the full `bin/` path.

```toml
[tools]
"conda:postgresql" = { version = "latest", filter_bins = "psql,pg_dump,pg_restore,createdb,dropdb" }
```

### Changes

- Added `get_filter_bins()` to parse the `filter_bins` option (supports both generic and platform-specific keys via `lookup_platform_key`)
- Added `create_symlink_bin_dir()` to create a `.mise-bins` directory with symlinks only to the specified binaries
- Hooked into both `install_fresh()` and `install_from_locked()` post-install steps
- Updated `list_bin_paths()` to return only `.mise-bins` when `filter_bins` is set
- Updated conda backend documentation with the new option and the `conda:postgresql` example
@simonepri simonepri force-pushed the feat/conda-filter-bins branch from 1b5f5c0 to 9b3b695 Compare March 9, 2026 22:04
@jdx
Copy link
Copy Markdown
Owner

jdx commented Mar 9, 2026

not putting the transitive bins on PATH

Comment thread src/backend/conda.rs Outdated
@simonepri
Copy link
Copy Markdown
Contributor Author

simonepri commented Mar 9, 2026

Done (vibe-coded) and updated the PR description, PTAL.

@simonepri simonepri force-pushed the feat/conda-filter-bins branch 2 times, most recently from 9cc95be to f27da2a Compare March 9, 2026 22:27
@simonepri simonepri changed the title feat(conda): add filter_bins support to conda backend feat(conda): exclude transitive dependency binaries from PATH Mar 9, 2026
@simonepri simonepri force-pushed the feat/conda-filter-bins branch from f27da2a to 6f69c39 Compare March 9, 2026 22:31
…ically

Instead of requiring users to manually specify filter_bins, the conda
backend now automatically exposes only binaries from the main package.

Uses rattler link_package return value (Vec<PathsEntry>) to identify
which files belong to the main package vs transitive dependencies, then
symlinks only the main packages binaries into .mise-bins/.

This prevents conda dependencies (e.g. ncurses clear/reset/tput when
installing postgresql) from shadowing system commands.
@simonepri simonepri force-pushed the feat/conda-filter-bins branch from 6f69c39 to 0373620 Compare March 9, 2026 22:35
Comment thread src/backend/conda.rs
Comment thread src/backend/conda.rs
@simonepri simonepri changed the title feat(conda): exclude transitive dependency binaries from PATH fix(conda): exclude transitive dependency binaries from PATH Mar 9, 2026
@jdx jdx merged commit 9985fcb into jdx:main Mar 10, 2026
35 checks passed
mise-en-dev added a commit that referenced this pull request Mar 10, 2026
### 🐛 Bug Fixes

- **(conda)** exclude transitive dependency binaries from PATH by
@simonepri in [#8543](#8543)

### New Contributors

- @simonepri made their first contribution in
[#8543](#8543)

## 📦 Aqua Registry Updates

#### New Packages (1)

-
[`stackrox/stackrox/roxctl`](https://github.com/stackrox/stackrox/roxctl)

#### Updated Packages (7)

- [`dprint/dprint`](https://github.com/dprint/dprint)
- [`j178/prek`](https://github.com/j178/prek)
- [`jdx/hk`](https://github.com/jdx/hk)
- [`jdx/mise`](https://github.com/jdx/mise)
- [`jdx/usage`](https://github.com/jdx/usage)
- [`mvdan/sh`](https://github.com/mvdan/sh)
- [`pnpm/pnpm`](https://github.com/pnpm/pnpm)
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.

3 participants