-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
[RFC / POC] Feature system : allow libraries to declare grouped optional dependencies #12354
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
base: main
Are you sure you want to change the base?
Conversation
ae84fa5 to
8b582b7
Compare
|
oof, thanks but I am afraid that's gonna take me a while to digest :D |
There is no rush, it's a first implementation that should work, but since it's my first time really digging into composer i may have miss some details so take your times |
|
Always resolving dependencies will all features that are not required would be a nightmare regarding dependency hell IMO, as it means that dependencies you don't want will still create conflicts with other packages in the solver. |
|
Yeah I haven't looked yet at the implementation but this absolutely should be update-time only, you select which features you want when you update dependencies, these are then included in the requirements in the poolbuilder, and then at install time you just have a list of things to install like usual in the lock file, features have no impact at all at install time (except that probably the lock file needs a list of features to be able to dump this in InstalledVersions style fashion if we want that.. Although I'd argue class_exists() checks should maybe be preferred at runtime to see if the dependency you need is present. |
|
I think my wording was wrong, it's not dependencies that are resolved with all features, it is only dependencies that are required by features of the root package to ensure that any combination of features for the root package is valid (since it's the worst case). It is the same thing that is done with Dependencies provided by a feature in another package are not resolved / fetched unless the user want it. It will certainly prevent some possibilities (like i have a feature that allow to work with older packages) but this has been done to have something working as a first implementation, and avoid some complexity, it could always be achieved latter. Example Package A : {
"name": "vendor/a",
"require": {
"symfony/validator": "^7.0"
},
"feature": {
"saas-provider": {
"require": {
"symfony/http-client": "^7.0",
"symfony/serializer": "^7.0"
}
}
}
}My package (root package) that require A : {
"name": "my-library",
"require": {
"vendor/a": "^1.0"
},
"feature": {
"a-shiny-feature": {
"require": {
"jolicode/automapper": "^9.0"
}
}
}
}In this case the
It will also be installed by default unless i restrict the installation with composer install/update --no-featuresIn this case, it will still be in However if i require the {
"name": "my-library",
"require": {
"vendor/a": "^1.0"
},
"feature": {
"a-shiny-feature": {
"require": {
"jolicode/automapper": "^9.0"
}
}
},
"require-feature": {
"vendor/a": ["saas-provider"]
}
}Then i will have |
It's already done in this PR, i mainly have save the I think it's important to have that and not rely on |
8c895a2 to
c7d96c4
Compare
faea253 to
2203174
Compare
2203174 to
716014a
Compare
|
Hey there, Is there any news concerning looking at this ? I really believe this would be a great feature for a lot of libraries and maintainers and simplify a lot some processes. From my point of view this PR is ready for a first version, but i'm available if you think it need more (or even less). |
|
I'm currently trying to wrap up 2.9, then I think I probably should look at this.. Sorry it's been so long. It's too big to sneak into 2.9 on a short schedule tho especially as it'll require packagist adjustments too, so I rather take time and let people play with snapshots for a while. |
|
No worries, if this is accepted i would gladly do the PR on packagist to make the changes, if needed. |
716014a to
1be24c6
Compare
Ref #11635
Motivation
Some packages propose optional dependencies to add optional features to their library.
This is actually mainly implemented by :
InstalledVersionsfile of composer to see if the dependency is installed)Also when feature may require multiple dependencies some library author prefer to propose a intermediate package that have the necessary requires in order to offer a better DX for end user (no need to require multiple packages, better handling of versions, ...)
When doing this, library author often prefers to have a monolith repository and splitting directory into multiple git repository which allows to create PR that can update both the main library and the optional dependency without too much hassle
Let's be honest, the current way is complicated and add a lot of maintenance for library authors, this PR aims to add a new way in composer to handle this use case.
Goals
Declaring features
In order for the author of a library to declare features he will now have to do add this lines in its composer.json file :
Using features
In order for a user to use a feature of a library he will now have to add this lines in its composer.json file :
Detecting features
When the library want to detect if a feature is enabled it will now be able to do this in PHP :
Testing features
New arguments are provided to the
installandupdatecommands in order for library authors to test their features.Features dependencies of the root package (not of others packages unless required) are always resolved in the
composer.lockfile.This ensure that given any combination the set of dependencies is always correct, like
require-devdependenciesHowever, like
require-devit is possible to avoid installing the package link to a featureSome examples :
In order to achieve that packages are now splitted like this in the composer.lock files :
This allow library authors to install and test their packages with any possible combination of features :
Errors
In order to provider better information for end user some rules where added to the SAT resolution :
None goals
To keep this first version simple, some changes are not considered in this PR :
SAT resolution depending on feature (if i require a feature that is only available in a specific version it would be nice to restrict the version or tell user why its current set of dependencies is not possible). There is some rules for feature and SAT but right now the implementation is "stupid"(This has been done finally)requiresection like the following :However this syntax would bring a too big BC break (older versions of composer would not be able to understand this).
Things to do in this PR :
hasFeaturemethod inInstalledVersions