This is mostly an bug open for discussion.
In PHP world (composer) dependencies are described, according to semver.org as a version range.
Ex: "justinrainbow/json-schema": "^1.6 || ^2.0",
Which means version compatible with 1.6 or 2.0, so >= 1.6 and < 3
For now, we use:
Requires: php-composer(justinrainbow/json-schema) >= 1.6
Requires: php-composer(justinrainbow/json-schema) < 3
But this is a bit messy, especially as we now have a lot of packages with multi-versions available
- php-JsonSchema provides php-composer(justinrainbow/json-schema) = 1.6.1
- php-justinrainbow-json-schema provides php-composer(justinrainbow/json-schema) = 2.0.5
Of course, we can switch to package name, but this looks like a workaround.
What is the best way to describe such dependency ?
AFAIK, boolean can help but cannot (for now) apply on the same dependency, right ?
I don't think there's any shorthand syntax for it (existing or planned) but you could use a macro to shorten it a bit, eg something like:
%define rangedep() ((%3 %2 %1) and (%3 %4 %5))
Requires: %rangedep 2.0 >= foo < 5.0
Requires: ((foo >= 2.0) and (foo < 5.0))
OTOH its all a bit academic since rich dependencies are not permitted in requires in Fedora at the moment. I can't say what works best in the php case.
Closign as there's no bug here, discussion on this is better done on eg fedora-packaging.
Panu, is it really that simple and does it actually work? Please take a look at bug 1287594.
IIC, for now, we can only have 2 constraints, so which can be indeed resolved by 2 different packages (#1287594)
While the initial idea for this RFE is to have a single constraint, so which must be resolved by the "same" package.
Reopening. This is a valid RFE.
We had a brief discussion on adding this as part of the rich dependencies but decided not to. Not so much because it is not needed but to not complicate the change further. The way to solve we need an operator and demands the same package matching for all the subterms. This could either be done with the proposed syntax or by exposing the operator in the syntax rich deps syntax.
(In reply to Panu Matilainen from comment #1)
> Requires: ((foo >= 2.0) and (foo < 5.0))
I don't think that works like you'd expect it to. The semantic versioning construct that Remi is describing is designed to express simultaneous Requires/Conflicts.
As Vit points out with bug 1287594, you get weird results with that logic.
In the Ruby, PHP, Golang, Rust, and increasingly the Python world, there are native constructs for handling semantically versioned dependencies.
Currently, in RPM, we do not have a way to properly represent the simultaneous Requires and Conflicts that this represents.
We can sort of do this by saying:
Requires: foo >= %min_ver
Conflicts: foo >= %max_ver
If rich dependencies allowed expressing Requires and Conflicts under a single stanza, you could get closer to this semantic. Though I'm not sure that it is needed.
Ideally, a clear and clean way to map this structure with an operator would also make it possible for multiversion dependencies to be better expressed in rich dependencies.
(In reply to Neal Gompa from comment #5)
> We can sort of do this by saying:
> Requires: foo >= %min_ver
> Conflicts: foo >= %max_ver
Also note that the build-time equivalent would be:
BuildRequires: foo >= %min_ver
BuildConflicts: foo >= %max_ver
I don't think (Build)Conflicts solves the issue
This is only a possible "workaround" for build, not for runtime.
When multiple versions exist, and can be installed in parallel, you need to constraint the one you need, without conflict, as the other can be required by another package.
(In reply to Remi Collet from comment #7)
> I don't think (Build)Conflicts solves the issue
> This is only a possible "workaround" for build, not for runtime.
> When multiple versions exist, and can be installed in parallel, you need to
> constraint the one you need, without conflict, as the other can be required
> by another package.
Then the only way to do that would be to do:
Requires: ((php-composer(justinrainbow/json-schema) < 3) and php-(composer(justinrainbow/json-schema) >= 1.6))
(Ordering above indicates preference for newest over oldest)
However, since all of our tools blow up whenever we want to use rich dependencies in Requires, Conflicts, and Recommends, you can't do it just yet.
Requires: ((php-composer(justinrainbow/json-schema) < 3) and (php-(composer(justinrainbow/json-schema) >= 1.6))
An example showing why boolean doesn't not solves "range version" dependency:
# rpm -q rpm
# rpm -i bar-1-1.fc25.remi.noarch.rpm
error: Failed dependencies:
((foo >= 2) and (foo <= 3)) is needed by bar-1-1.fc25.remi.noarch
# rpm -i foo1-1-1.fc25.remi.noarch.rpm
# rpm -q --provides foo1
foo = 1
foo1 = 1-1.fc25.remi
# rpm -i foo4-4-1.fc25.remi.noarch.rpm
# rpm -q --provides foo4
foo = 4
foo4 = 4-1.fc25.remi
# pm -ivh bar-1-1.fc25.remi.noarch.rpm
Preparing... ################################# [100%]
Updating / installing...
1:bar-1-1.fc25.remi ################################# [100%]
Last command works, when we expect a way to disallow it.
(In reply to Remi Collet from comment #10)
> An example showing why boolean doesn't not solves "range version" dependency:
Thank you for confirming my suspicion from comment #2. At least the behavior is consistent ;)
*** Bug 1287594 has been marked as a duplicate of this bug. ***
This has been implemented in rpm as of >= 4.13.90 which is in rawhide/f27 now, using the new "with" rich dependency syntax:
Requires: (foo >= 1.0 with foo < 2.0)