You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is me floating an idea I had for creating packages that have variable dependencies based on what features are requested, that doesn't rely on creating a unique subpackage per feature definition. Any and all feedback, criticism, corrections, etc. welcome. Please poke as many holes in this as you can find. (Bonus points if you have an idea for how said hole can be plugged.)
The problem
IMHO the explosion of feature-subpackages creates distracting amounts of clutter in the package collection, as well as overly verbose package names (inserting the feature name into the package name for each feature provided), when all of those feature packages contain nothing other than unique Provides: and Requires: dependencies (no actual files), meaning there'd be no reason for the subpackages at all if the main package could express the necessary information.
An example
Take the rust-hyper package in Fedora 44. Like many Rust packages, it consists of a main package (rust-hyper-devel) that contains all of the files for the package, plus EIGHT subpackages for its various features.
What I would propose, instead of the current glut of subpackages, is a way of defining dependencies "for" only specific Provides:. All of the various feature Provides: (crate(hyper/server), crate(hyper/default), etc.) would be defined on the main package, instead of in subpackages, and the dependencies for each Provides: would be set as Requires: conditional on a specific Provides:.
So, for example, the .spec syntax, wrapped for readability, might be (and this is of course subject to change, it's just an example of one possible format — also, in reality these Requires: would be created by the Rust build tooling, only the Provides: for the feature crates would be defined in the .spec file, in place of the current subpackages):
The idea is that, installing the package rust-hyper-devel-1.11.0-1.fc44.noarch either by package name or via its crate(hyper)Provides: would install the package files, and pull in the unconditional Requires: (the ones without for %{some_provide} conditions) as dependencies.
Installing, or using as a dependency, one of the crate(hyper/foo) provides, would also pull in any Requires: listed as for crate(hyper/foo).
Open questions
Is this remotely workable, from an RPM package definition / database perspective? (Obviously it would require new features developed for both RPM and DNF5, but does it seem possible to write that code within the current codebase / APIs?)
Is this remotely implementable, in the Rust or Python build tooling? (Since the Provides: for extras subpackages are autogenerated based on the packaging metadata, that tooling would need to be able to generate conditional Requires: ... for metadata instead.)
Are there any feature/extra packages that contain files other than the %ghost copy of their package definition? For example, source files that are unique to the feature in question?
If so, that would probably torpedo this, but I think the answer is "No". Even if such files could theoretically exist (in terms of the native package definition), I don't believe our current tooling has any means of expressing that kind of relationship. The complete set of source files is included in the main package. (I believe. PLEASE correct me if I'm wrong!)
Would the conditional Requires: ... for dependency definitions be sufficient for this to work, or would the RPM definition of "installed" need to change to separately track individual Provides:?
Currently if a package is installed, it's assumed that all of its Provides: are available, and all of its Requires: are installed (or RPM flags the package as missing dependencies). But for these packages, having the physical package installed means that not all Provides: will necessarily be "active", and so not all of their Requires: ... for dependencies will necessarily be installed. A conditional Requires: ... for %{some_provide} only needs to be installed if there's some installed package that Requires: %{some_provide}.
So, would it be sufficient to have the Requires: ... for dependencies only activate when the Provides: is activated as a dependency (or an explicit request, like sudo dnf install %{some_provide}), or would the RPM database need to track whichProvides: of a given package have been installed, and which have not? (Or is there some other way of making this work?)
Perhaps the most important question, as it makes the others moot if the answer is no: Would there be any interest in migrating some future Fedora / RHEL release's Rust, Python, etc. packaging to use these features, instead of the current glut-o'-subpackages setup?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
This is me floating an idea I had for creating packages that have variable dependencies based on what features are requested, that doesn't rely on creating a unique subpackage per feature definition. Any and all feedback, criticism, corrections, etc. welcome. Please poke as many holes in this as you can find. (Bonus points if you have an idea for how said hole can be plugged.)
The problem
IMHO the explosion of feature-subpackages creates distracting amounts of clutter in the package collection, as well as overly verbose package names (inserting the feature name into the package name for each feature provided), when all of those feature packages contain nothing other than unique
Provides:andRequires:dependencies (no actual files), meaning there'd be no reason for the subpackages at all if the main package could express the necessary information.An example
Take the
rust-hyperpackage in Fedora 44. Like many Rust packages, it consists of a main package (rust-hyper-devel) that contains all of the files for the package, plus EIGHT subpackages for its various features.The subpackages look like this:
The proposal
What I would propose, instead of the current glut of subpackages, is a way of defining dependencies "for" only specific
Provides:. All of the various featureProvides:(crate(hyper/server),crate(hyper/default), etc.) would be defined on the main package, instead of in subpackages, and the dependencies for eachProvides:would be set asRequires:conditional on a specificProvides:.So, for example, the
.specsyntax, wrapped for readability, might be (and this is of course subject to change, it's just an example of one possible format — also, in reality theseRequires:would be created by the Rust build tooling, only theProvides:for the feature crates would be defined in the.specfile, in place of the current subpackages):The idea is that, installing the package
rust-hyper-devel-1.11.0-1.fc44.noarcheither by package name or via itscrate(hyper)Provides:would install the package files, and pull in the unconditionalRequires:(the ones withoutfor %{some_provide}conditions) as dependencies.Installing, or using as a dependency, one of the
crate(hyper/foo)provides, would also pull in anyRequires:listed asfor crate(hyper/foo).Open questions
Is this remotely workable, from an RPM package definition / database perspective? (Obviously it would require new features developed for both RPM and DNF5, but does it seem possible to write that code within the current codebase / APIs?)
Is this remotely implementable, in the Rust or Python build tooling? (Since the
Provides:for extras subpackages are autogenerated based on the packaging metadata, that tooling would need to be able to generate conditionalRequires: ... formetadata instead.)Are there any feature/extra packages that contain files other than the
%ghostcopy of their package definition? For example, source files that are unique to the feature in question?If so, that would probably torpedo this, but I think the answer is "No". Even if such files could theoretically exist (in terms of the native package definition), I don't believe our current tooling has any means of expressing that kind of relationship. The complete set of source files is included in the main package. (I believe. PLEASE correct me if I'm wrong!)
Would the conditional
Requires: ... fordependency definitions be sufficient for this to work, or would the RPM definition of "installed" need to change to separately track individualProvides:?Currently if a package is installed, it's assumed that all of its
Provides:are available, and all of itsRequires:are installed (or RPM flags the package as missing dependencies). But for these packages, having the physical package installed means that not allProvides:will necessarily be "active", and so not all of theirRequires: ... fordependencies will necessarily be installed. A conditionalRequires: ... for %{some_provide}only needs to be installed if there's some installed package thatRequires: %{some_provide}.So, would it be sufficient to have the
Requires: ... fordependencies only activate when theProvides:is activated as a dependency (or an explicit request, likesudo dnf install %{some_provide}), or would the RPM database need to track whichProvides:of a given package have been installed, and which have not? (Or is there some other way of making this work?)Perhaps the most important question, as it makes the others moot if the answer is no: Would there be any interest in migrating some future Fedora / RHEL release's Rust, Python, etc. packaging to use these features, instead of the current glut-o'-subpackages setup?
All reactions