feat: ability to install package subsets#4404
Conversation
Co-authored-by: Tim de Jager <tim@prefix.dev> Co-authored-by: Ruben Arts <ruben.arts@hotmail.com>
Co-authored-by: Ruben Arts <ruben.arts@hotmail.com>
|
Okay did a final user test myself on the Things I added in the messaging:
|
| pub only: Option<String>, | ||
| } | ||
|
|
||
| const SKIP_CUTOFF: usize = 5; |
There was a problem hiding this comment.
This just for the display method.
| /// Skip a package and its entire dependency subtree. This performs a hard exclusion: the package and its dependencies are not installed unless reachable from another non-skipped root. | ||
| #[arg(long)] | ||
| pub skip_with_deps: Option<Vec<String>>, | ||
|
|
||
| /// Install and build only this package and its dependencies | ||
| #[arg(long)] | ||
| pub only: Option<String>, |
There was a problem hiding this comment.
Added these CLI args.
| let filter = InstallFilter::new() | ||
| .skip_direct(args.skip.clone().unwrap_or_default()) | ||
| .skip_with_deps(args.skip_with_deps.clone().unwrap_or_default()) | ||
| .target_package(args.only.clone()); |
There was a problem hiding this comment.
Here you see an example of setting an install filter.
crates/pixi_cli/src/install.rs
Outdated
| ); | ||
| } | ||
|
|
||
| if !all_skipped_packages.is_empty() { |
There was a problem hiding this comment.
This includes all the messaging, if we ever add the flag somewhere else we should consider reusing this.
| .with_download_client(command_dispatcher.download_client().clone()) | ||
| .with_package_cache(command_dispatcher.package_cache().clone()) | ||
| .with_reinstall_packages(self.force_reinstall) | ||
| .with_ignored_packages(self.ignore_packages.unwrap_or_default()) |
There was a problem hiding this comment.
This is the new rattler feature that ignores installed packages.
| @@ -0,0 +1,458 @@ | |||
| use itertools::Itertools; | |||
There was a problem hiding this comment.
This the file that contains the graph reachability stuff and is kind of the meat of this feature.
| } | ||
| } | ||
|
|
||
| /// Filters packages using two skip modes and optional target selection. |
There was a problem hiding this comment.
Read this here carefully.
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; |
There was a problem hiding this comment.
I added simple unit tests to verify this behavior.
| .partition::<Vec<_>, _>(|p| p.as_conda().is_some()); | ||
|
|
||
| // TODO: use the same ignore logic for PyPI | ||
| let (ignored_conda, _ignored_pypi) = ignored |
There was a problem hiding this comment.
I've kept the behavior as before for PyPI. So that if you do:
pixi install --frozen --skip foobar`It works like before, but we need to improve that, because without --frozen first this was required it might work unintuitively.
| @@ -0,0 +1,205 @@ | |||
| use pixi_core::{InstallFilter, UpdateLockFileOptions}; | |||
There was a problem hiding this comment.
This contains some integration tests, with an e2e test to check if all works as expected.
|
Found an easter egg: |
|
I see |
| .partition::<Vec<_>, _>(|p| p.as_conda().is_some()); | ||
|
|
||
| // TODO: use the same ignore logic for PyPI | ||
| let (ignored_conda, _ignored_pypi) = ignored |
There was a problem hiding this comment.
Currently it also skips python if I do pixi install --only pypi-dependency since python is not a dependency. We need to always install python when we install only a pypi-dependency.
There was a problem hiding this comment.
I just made all of this work.
There is, lets pick it up in a subsequent PR. |
ruben-arts
left a comment
There was a problem hiding this comment.
Really cool! Thanks Tim
Overview
This Introduces install filtering to control what from the lockfile is installed. Adds new CLI options to skip packages, skip with full dependency subtree, or target a single package.
Why?
In some cases it might be desirable to skip part of the installation, e.g. for docker builds. Or you could be working on a pixi build project and only test part of the build changes. This unifies the behavior that was introduced with: #3092 by @olivier-lacroix
@ruben-arts noticed, that especially when also developing build backends it can be really annoying if you are only interested in a certain packages that it still tries to build others.
This kind of ties in with a new philosophy that we are trying out where we allow the user to play with the environment a bit more as long as you are able to recover.
When running these commands without
--frozen, it can be the case that the lock file no longer reflects the environment changes.CLI Changes
pixi installoptions:--skip <NAME>: soft skip; omit package but still install its deps.--skip-with-deps <NAME>: hard skip; omit package and its dependency subtree unless reachable via another root.Some examples:
pixi install --skip foopixi install --skip-with-deps torchpixi install --package numpypixi install --package app --skip-with-deps dev-docs --skip lintersHow was this tested?
tests/integration_rust/install_filter_tests.rscovering:What was skipped.
Notes for the reviewer
InstallSubsetincrates/pixi_core/src/lock_file/install_subset.rsbuilds a reachability graph over lockfile packages and applies:skip_with_depsskip(direct skip, traverse deps)--onlyInstallFilterinpixi_core::environment threadsskip/target options through install/update paths.update_prefixfilters lockfile packages before installing.