Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add support for optional dependencies #1019

Merged
merged 70 commits into from
Jan 27, 2025

Conversation

prsabahrami
Copy link
Contributor

Description

I have updated the matchspec parser to parse the list of features. (e.g. sympy[version=1.2, optional_features=[feat1, feat2]] into [feat1, feat2]).
In addition, I added SolverPackageRecord::RecordWithFeature which represents a package with a single feature. Hence, the goal is to turn sympy[feat1, feat2] into sympy[feat1], sympy[feat2]. We also need to assure that both of these adhere to the correct version of sympy.

@prsabahrami prsabahrami changed the title Adding support for optional dependencies feat: Add support for optional dependencies Jan 8, 2025
Copy link
Collaborator

@baszalmstra baszalmstra left a comment

Choose a reason for hiding this comment

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

Very nice work thus far! I think you almost got it!

crates/rattler_conda_types/src/repo_data/mod.rs Outdated Show resolved Hide resolved
crates/rattler_conda_types/src/repo_data/mod.rs Outdated Show resolved Hide resolved
crates/rattler_solve/src/resolvo/mod.rs Outdated Show resolved Hide resolved
crates/rattler_solve/src/resolvo/mod.rs Outdated Show resolved Hide resolved
crates/rattler_solve/src/resolvo/mod.rs Outdated Show resolved Hide resolved
crates/rattler_solve/src/resolvo/mod.rs Outdated Show resolved Hide resolved
@tdejager
Copy link
Collaborator

tdejager commented Jan 9, 2025

@baszalmstra @prsabahrami Do you think we need to version the MatchSpec implementation in rust with this feature addition? Or maybe have an explicit cargo feature that marks this as an extension? That way consumers of the libary cannot seralize into matchspecs that cannot be parse by e.g conda?

@baszalmstra
Copy link
Collaborator

@tdejager That seems smart!

@wolfv
Copy link
Contributor

wolfv commented Jan 9, 2025

I think we might even want to gate the whole feature behind a compile time option for now? Until we have a CEP that passed?

@prsabahrami
Copy link
Contributor Author

@baszalmstra I have updated the pool to take in NameType which an enum of either single String or a pair of name and feature. Please let me know what you think!

crates/rattler_solve/src/resolvo/mod.rs Show resolved Hide resolved
Comment on lines 62 to 65
let feature = value
.optional_features
.as_ref()
.and_then(|features| features.first().cloned());
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess this should be None?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We need to have an assertion here to make sure that only 1 feature is in the optional_features of value and then select the only one as the SolverMatchSpec::feature. I'm not sure why it would be None.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It should be None initially. In parse_match_spec we then explicitly add a feature.

crates/rattler_solve/src/resolvo/mod.rs Outdated Show resolved Hide resolved
crates/rattler_solve/src/resolvo/mod.rs Outdated Show resolved Hide resolved
Comment on lines 62 to 65
let feature = value
.optional_features
.as_ref()
.and_then(|features| features.first().cloned());
Copy link
Collaborator

Choose a reason for hiding this comment

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

It should be None initially. In parse_match_spec we then explicitly add a feature.

crates/rattler_solve/src/resolvo/mod.rs Show resolved Hide resolved
Copy link
Collaborator

@baszalmstra baszalmstra left a comment

Choose a reason for hiding this comment

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

Im still thinking about the name optional_features. I wonder if its descriptive enough.

Im a little on the fence about the name features. It implies that a certain "feature" is enabled but in reality the only thing that changes is that an extra set of dependencies is required. This might ofcourse cause new functionality to be unlocked but not necessarily.

Im starting to think that the name extras might be better.. Wdyt?

Also optional is a bit strange in this context. Optional to me would imply that a solution without the optional features is also valid, where it is in fact not. Perhaps in the matchspec we could just drop this part? E.g. foobar[features=[baz]]

.github/workflows/rust-compile.yml Outdated Show resolved Hide resolved
crates/rattler_conda_types/src/match_spec/mod.rs Outdated Show resolved Hide resolved
crates/rattler_conda_types/Cargo.toml Outdated Show resolved Hide resolved
crates/rattler_conda_types/src/match_spec/mod.rs Outdated Show resolved Hide resolved
crates/rattler_conda_types/src/match_spec/parse.rs Outdated Show resolved Hide resolved
crates/rattler_conda_types/src/repo_data/mod.rs Outdated Show resolved Hide resolved
crates/rattler_solve/Cargo.toml Outdated Show resolved Hide resolved
@@ -94,7 +94,7 @@ impl super::SolverImpl for Solver {
>(
&mut self,
task: SolverTask<TAvailablePackagesIterator>,
) -> Result<Vec<RepoDataRecord>, SolveError> {
) -> Result<SolverResult, SolveError> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you create an issue for this so we dont forget?

@@ -94,7 +94,7 @@ impl super::SolverImpl for Solver {
>(
&mut self,
task: SolverTask<TAvailablePackagesIterator>,
) -> Result<Vec<RepoDataRecord>, SolveError> {
) -> Result<SolverResult, SolveError> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Furthermore, maybe it would be good to error out if a matchspec with extras is used. That way we provide a clear error message when people try it.

│ └─ foo 4.0.2
└─ foo[with-bar] * cannot be installed because there are no viable options:
└─ foo[with-bar] 3.0.2 would require
└─ foo ==3.0.2 py36h1af98f8_1[md5=fb731d9290f0bcbf3a054665f33ec94f, sha256=67a63bec3fd3205170eaad532d487595b8aaceb9814d13c6858d7bac3ef24cd4], which cannot be installed because there are no viable options:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Mm this error is pretty uninformative. Especially if there will be multiple solvables that provide that extra. It will probably list every single solvable and extra here.

Perhaps it would be possible to merge all the SolvableWithFeature solvables of a single version into a single solvable? I assume that will result in a much clearer error message and reduce the total number of solvables..

Co-authored-by: Bas Zalmstra <[email protected]>
@prsabahrami
Copy link
Contributor Author

Created an issue for supporting this in libsolv. #1032

@baszalmstra baszalmstra merged commit fb92618 into conda:main Jan 27, 2025
15 checks passed
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.

4 participants