Add prefer-stable flag to pick stable package over unstable ones when possible #1740

Merged
merged 2 commits into from Apr 2, 2013

Conversation

Projects
None yet
@Seldaek
Member

Seldaek commented Mar 28, 2013

The thing with dev packages, and especially with some libs requiring dev packages themselves, is that people are often forced to set minimum-stability to dev to avoid going mad tracking deep dependencies. That leads to everything being dev, which is clearly not ideal for most usages. This provides a new flag that tells composer to pick more stable versions when it can, while still allowing dev versions to be installed if that's the only option.

Add "prefer-stable":true in a composer.json that has "minimum-stability" set to something else than stable, and see what happens with composer update --dry-run. It should update packages to stable versions when it can.

If you really want a dev version, instead of just requiring it with @dev like before, you should require explicitly the version you want, e.g. 1.0.x-dev or dev-master.

Happy easter 馃惏

@stof

This comment has been minimized.

Show comment Hide comment
@stof

stof Mar 28, 2013

Contributor

The doc needs to be updated too

Contributor

stof commented Mar 28, 2013

The doc needs to be updated too

@Seldaek

This comment has been minimized.

Show comment Hide comment
@Seldaek

Seldaek Mar 28, 2013

Member

Yeah it's not polished, but I don't want to spend time updating docs until this is proven to be a good approach.

Member

Seldaek commented Mar 28, 2013

Yeah it's not polished, but I don't want to spend time updating docs until this is proven to be a good approach.

@stof

This comment has been minimized.

Show comment Hide comment
@stof

stof Mar 28, 2013

Contributor

The idea seems good at least.

Contributor

stof commented Mar 28, 2013

The idea seems good at least.

@naderman

This comment has been minimized.

Show comment Hide comment
@naderman

naderman Mar 28, 2013

Member

PR looks good to me +1

Member

naderman commented Mar 28, 2013

PR looks good to me +1

@lsmith77

This comment has been minimized.

Show comment Hide comment
@lsmith77

lsmith77 Mar 28, 2013

+1 on the idea.

+1 on the idea.

@schmittjoh

This comment has been minimized.

Show comment Hide comment
@schmittjoh

schmittjoh Mar 28, 2013

Contributor

Idea sounds really good.

Contributor

schmittjoh commented Mar 28, 2013

Idea sounds really good.

@trq

This comment has been minimized.

Show comment Hide comment
@trq

trq Mar 28, 2013

馃憤 Awesome idea!

trq commented Mar 28, 2013

馃憤 Awesome idea!

@horechek

This comment has been minimized.

Show comment Hide comment
@horechek

horechek Mar 28, 2013

+1

+1

@rande

This comment has been minimized.

Show comment Hide comment
@rande

rande Mar 29, 2013

+1

rande commented Mar 29, 2013

+1

@everzet

This comment has been minimized.

Show comment Hide comment
@everzet

everzet Mar 29, 2013

Contributor

Why not making it true by default?

Contributor

everzet commented Mar 29, 2013

Why not making it true by default?

@amacneil

This comment has been minimized.

Show comment Hide comment
@amacneil

amacneil Mar 29, 2013

This isn't the best solution. You haven't solved the problem, which you define as:

The thing with dev packages, and especially with some libs requiring dev packages themselves, is that people are often forced to set minimum-stability to dev to avoid going mad tracking deep dependencies

I will still need to set "minimum-stability": "dev" in pretty much every project to avoid "going mad tracking deep dependencies", which makes minimum-stability flag useless, and this new prefer-stable flag just another setting I have to add to every project by default.

A better solution would be if the minimum-stability flag only affected packages actually required in composer.json, and not sub-dependencies. There's no need to ever set a minimum stability for sub-dependencies, by definition I don't care about them, as long as they meet the requirements of packages I depend on.

That way, for most projects you would leave the minimum-stability line out altogether and get stable versions of any packages you specify, and for any sub-dependencies you would get the most stable version available. If you want beta/dev versions of any package, you can specify that requirement in your composer.json file.

This isn't the best solution. You haven't solved the problem, which you define as:

The thing with dev packages, and especially with some libs requiring dev packages themselves, is that people are often forced to set minimum-stability to dev to avoid going mad tracking deep dependencies

I will still need to set "minimum-stability": "dev" in pretty much every project to avoid "going mad tracking deep dependencies", which makes minimum-stability flag useless, and this new prefer-stable flag just another setting I have to add to every project by default.

A better solution would be if the minimum-stability flag only affected packages actually required in composer.json, and not sub-dependencies. There's no need to ever set a minimum stability for sub-dependencies, by definition I don't care about them, as long as they meet the requirements of packages I depend on.

That way, for most projects you would leave the minimum-stability line out altogether and get stable versions of any packages you specify, and for any sub-dependencies you would get the most stable version available. If you want beta/dev versions of any package, you can specify that requirement in your composer.json file.

@stof

This comment has been minimized.

Show comment Hide comment
@stof

stof Mar 29, 2013

Contributor

@adrianmacneil IMO, this feature solves the issue: it allows to prefer stable packages when available while still allowing alpha or dev packages when they are needed to match the requirement.

Making minimum-stability affecting only the root requirements is a bad idea IMO:

  • if I want to forbid dev versions (some companies are against using dev packages), it should affect all packages, not only a subset of them
  • your logic would mean adding all packages in the root requirement to force them to be stable. But this means that you require the developer to resolve the dependency graph manually to find the whole list, thus defeating the goal of a dependency manager (which is meant to manage them for you). My current project defines 34 requirements in the root package, but uses 74 packages. I don't want to list them all (and to update the list each time a dev modifies the dependencies of a library)
Contributor

stof commented Mar 29, 2013

@adrianmacneil IMO, this feature solves the issue: it allows to prefer stable packages when available while still allowing alpha or dev packages when they are needed to match the requirement.

Making minimum-stability affecting only the root requirements is a bad idea IMO:

  • if I want to forbid dev versions (some companies are against using dev packages), it should affect all packages, not only a subset of them
  • your logic would mean adding all packages in the root requirement to force them to be stable. But this means that you require the developer to resolve the dependency graph manually to find the whole list, thus defeating the goal of a dependency manager (which is meant to manage them for you). My current project defines 34 requirements in the root package, but uses 74 packages. I don't want to list them all (and to update the list each time a dev modifies the dependencies of a library)
@hason

This comment has been minimized.

Show comment Hide comment
@hason

hason Mar 29, 2013

Contributor

Maybe it would be good to have a parameter allow-dev for the case described in #1436 and in @adrianmacneil comment:

"minimum-stability": "stable",
"allow-dev": "true"
Contributor

hason commented Mar 29, 2013

Maybe it would be good to have a parameter allow-dev for the case described in #1436 and in @adrianmacneil comment:

"minimum-stability": "stable",
"allow-dev": "true"
@amacneil

This comment has been minimized.

Show comment Hide comment
@amacneil

amacneil Mar 29, 2013

It's not just dev packages, beta packages are a problem too. The case where you want to prevent anything but stable is much less common than the case where you just want composer to install what you asked for without complaining. Currently, as proposed this solution means you need to add two lines to pretty much every composer file just to avoid weird package dependency issues. I'm sure we can find a solution which means for the most common requirement no extra configuration is necessary.

Here's an example composer.json which is causing me grief:

{
    "require": { "illuminate/database": "v4.0.0-BETA3" }
}

RIght now, composer can't solve that, which I believe is a problem that needs fixing. Composer has no problem with me specifying the beta package, but because that beta package depends on other beta packages, it complains.

Maybe a better solution would simply be to leave the minimum-stability setting alone, but automatically allow packages to depend on other packages of equal or higher stability. Either way, I think composer should prefer using the most stable version of a package which meets the requirements (essentially making this new prefer-stable flag true by default). It seems very unlikely that you would want the latest dev-master of every package in your requirements, and if you ever did you are still free to specify -dev-master on a per-package basis.

It's not just dev packages, beta packages are a problem too. The case where you want to prevent anything but stable is much less common than the case where you just want composer to install what you asked for without complaining. Currently, as proposed this solution means you need to add two lines to pretty much every composer file just to avoid weird package dependency issues. I'm sure we can find a solution which means for the most common requirement no extra configuration is necessary.

Here's an example composer.json which is causing me grief:

{
    "require": { "illuminate/database": "v4.0.0-BETA3" }
}

RIght now, composer can't solve that, which I believe is a problem that needs fixing. Composer has no problem with me specifying the beta package, but because that beta package depends on other beta packages, it complains.

Maybe a better solution would simply be to leave the minimum-stability setting alone, but automatically allow packages to depend on other packages of equal or higher stability. Either way, I think composer should prefer using the most stable version of a package which meets the requirements (essentially making this new prefer-stable flag true by default). It seems very unlikely that you would want the latest dev-master of every package in your requirements, and if you ever did you are still free to specify -dev-master on a per-package basis.

@bamarni

This comment has been minimized.

Show comment Hide comment
@bamarni

bamarni Mar 29, 2013

Contributor

I share @adrianmacneil concern, the main issue is that one would still have to set a global stability policy to dev, only because of maybe a few packages, I guess we all do that (just not get mad as you said :)).

What about his example, I don't exactly know how composer behaves in that case? Maybe it's because the package requirment should be like "4.0.0@beta"? In that situation imo composer should also allow beta packages for deeper requirments of this illuminate/database package (if it's not already the case, sorry I haven't tested it).

Contributor

bamarni commented Mar 29, 2013

I share @adrianmacneil concern, the main issue is that one would still have to set a global stability policy to dev, only because of maybe a few packages, I guess we all do that (just not get mad as you said :)).

What about his example, I don't exactly know how composer behaves in that case? Maybe it's because the package requirment should be like "4.0.0@beta"? In that situation imo composer should also allow beta packages for deeper requirments of this illuminate/database package (if it's not already the case, sorry I haven't tested it).

@Seldaek

This comment has been minimized.

Show comment Hide comment
@Seldaek

Seldaek Mar 29, 2013

Member

@adrianmacneil the problem you describe with beta packages I believe comes from the fact that the whole illuminate stuff is still an unstable ecosystem. That means for projects using this yes you must have a dev or at least beta minimum-stability. That is not the case for everything though. In symfony projects nowadays I can mostly get away with the default stable setting, and require a couple bundles in dev versions. And even that part would not be necessary if bundle authors would tag more often.

Now regarding having it read the stability requirements from the packages you require, that can't really work for similar reasons as the recursive repositories problem. Another reason is that it would take control away from the root package, which is not acceptable to many people that want tight control over their dependencies.

@hason not sure what that would bring? If you want to allow unstable packages, you lower the minimum stability and you're done. I suppose that would work easier if we make prefer-stable true by default.


Finally on the topic of enabling this by default. I think it might indeed be good, but I'd like to hear from anyone that thinks that's a bad idea.

Member

Seldaek commented Mar 29, 2013

@adrianmacneil the problem you describe with beta packages I believe comes from the fact that the whole illuminate stuff is still an unstable ecosystem. That means for projects using this yes you must have a dev or at least beta minimum-stability. That is not the case for everything though. In symfony projects nowadays I can mostly get away with the default stable setting, and require a couple bundles in dev versions. And even that part would not be necessary if bundle authors would tag more often.

Now regarding having it read the stability requirements from the packages you require, that can't really work for similar reasons as the recursive repositories problem. Another reason is that it would take control away from the root package, which is not acceptable to many people that want tight control over their dependencies.

@hason not sure what that would bring? If you want to allow unstable packages, you lower the minimum stability and you're done. I suppose that would work easier if we make prefer-stable true by default.


Finally on the topic of enabling this by default. I think it might indeed be good, but I'd like to hear from anyone that thinks that's a bad idea.

@bamarni

This comment has been minimized.

Show comment Hide comment
@bamarni

bamarni Mar 29, 2013

Contributor

馃憤 for making this as default then, thx for your explanations @Seldaek

Contributor

bamarni commented Mar 29, 2013

馃憤 for making this as default then, thx for your explanations @Seldaek

@jeromemacias

This comment has been minimized.

Show comment Hide comment
@jeromemacias

jeromemacias Mar 30, 2013

Contributor

+1 and making this by default

Contributor

jeromemacias commented Mar 30, 2013

+1 and making this by default

@Taluu

This comment has been minimized.

Show comment Hide comment
@Taluu

Taluu Mar 30, 2013

Contributor

馃憤 for this idea, and making it by default. :)

Contributor

Taluu commented Mar 30, 2013

馃憤 for this idea, and making it by default. :)

@Seldaek

This comment has been minimized.

Show comment Hide comment
@Seldaek

Seldaek Mar 30, 2013

Member

OK it's now on by default and I added docs. If there are no objections will try to merge this soon (it probably could use a blog post to clarify things - also have other stuff I want to write about).

Member

Seldaek commented Mar 30, 2013

OK it's now on by default and I added docs. If there are no objections will try to merge this soon (it probably could use a blog post to clarify things - also have other stuff I want to write about).

@till

This comment has been minimized.

Show comment Hide comment
@till

till Mar 31, 2013

Contributor

馃憤

Contributor

till commented Mar 31, 2013

馃憤

@Seldaek

This comment has been minimized.

Show comment Hide comment
@Seldaek

Seldaek Apr 1, 2013

Member

OK I realized there is a not so cool side effect of having this on by default. If you have the default minimum-stability (stable), and just want to get one package in dev, you can for now require: "foo/bar": "2.*@dev" for example. But doing so with prefer-stable enabled won't change anything, you'll still get a stable.

So I'd say either we handle those flagged packages specifically (I guess disabling the prefer-stable behavior for them?) or we disable this by default. I think disabled by default might be best because the more "automatic" things we add the more confused people get. Also it would avoid some WTFs for people updating their existing projects.

Member

Seldaek commented Apr 1, 2013

OK I realized there is a not so cool side effect of having this on by default. If you have the default minimum-stability (stable), and just want to get one package in dev, you can for now require: "foo/bar": "2.*@dev" for example. But doing so with prefer-stable enabled won't change anything, you'll still get a stable.

So I'd say either we handle those flagged packages specifically (I guess disabling the prefer-stable behavior for them?) or we disable this by default. I think disabled by default might be best because the more "automatic" things we add the more confused people get. Also it would avoid some WTFs for people updating their existing projects.

@everzet

This comment has been minimized.

Show comment Hide comment
@everzet

everzet Apr 1, 2013

Contributor

@Seldaek even if I'll have both "prefer-stable":true and "minimum-stability": "dev" set in composer.json manually, I'll still expect "foo/bar": "2.*@dev" to install dev version of the package as that's what I explicitly stated it to do.

If it's not the case currently, I'll assume it's broken. And if feature is broken - it doesn't matter whether if it is enabled by default or not :)

Contributor

everzet commented Apr 1, 2013

@Seldaek even if I'll have both "prefer-stable":true and "minimum-stability": "dev" set in composer.json manually, I'll still expect "foo/bar": "2.*@dev" to install dev version of the package as that's what I explicitly stated it to do.

If it's not the case currently, I'll assume it's broken. And if feature is broken - it doesn't matter whether if it is enabled by default or not :)

@naderman

This comment has been minimized.

Show comment Hide comment
@naderman

naderman Apr 2, 2013

Member

2.@dev was never meant to always install dev versions. The @dev is meant to set minimum stability. Meaning you want a 2. version, preferably stable but are allowing a dev version. If you want the dev version explicitly use 2.x-dev.

Member

naderman commented Apr 2, 2013

2.@dev was never meant to always install dev versions. The @dev is meant to set minimum stability. Meaning you want a 2. version, preferably stable but are allowing a dev version. If you want the dev version explicitly use 2.x-dev.

@everzet

This comment has been minimized.

Show comment Hide comment
@everzet

everzet Apr 2, 2013

Contributor

@naderman ah, ok. My bad then.

Contributor

everzet commented Apr 2, 2013

@naderman ah, ok. My bad then.

@Seldaek

This comment has been minimized.

Show comment Hide comment
@Seldaek

Seldaek Apr 2, 2013

Member

OK updated the code back to disabled by default, updated the PR description with details on usage, merging.

Member

Seldaek commented Apr 2, 2013

OK updated the code back to disabled by default, updated the PR description with details on usage, merging.

Seldaek added a commit that referenced this pull request Apr 2, 2013

Merge pull request #1740 from Seldaek/preferstable
Add prefer-stable flag to pick stable package over unstable ones when possible

@Seldaek Seldaek merged commit 79100be into composer:master Apr 2, 2013

1 check passed

default The Travis build passed
Details

lsmith77 referenced this pull request in jackalope/jackalope-jackrabbit Apr 8, 2013

digitalkaoz pushed a commit to digitalkaoz/composer that referenced this pull request Nov 22, 2013

Merge pull request #1740 from Seldaek/preferstable
Add prefer-stable flag to pick stable package over unstable ones when possible
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment