Bug 1389871 - [RFE] version range dependency
Summary: [RFE] version range dependency
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: rpm
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Packaging Maintenance Team
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Keywords: Reopened
: 1287594 (view as bug list)
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2016-10-29 06:55 UTC by Remi Collet
Modified: 2017-08-23 14:20 UTC (History)
12 users (show)

(edit)
Clone Of:
(edit)
Last Closed: 2017-08-23 14:20:41 UTC


Attachments (Terms of Use)


External Trackers
Tracker ID Priority Status Summary Last Updated
Github rpm-software-management rpm issues 159 None None None 2017-05-25 00:55 UTC
Red Hat Bugzilla 1287594 None None None Never

Internal Trackers: 1287594

Description Remi Collet 2016-10-29 06:55:18 UTC
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

Ex:

- 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 ?

Comment 1 Panu Matilainen 2016-11-09 05:58:21 UTC
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

which becomes:
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.

Comment 2 Vít Ondruch 2016-11-09 08:43:51 UTC
Panu, is it really that simple and does it actually work? Please take a look at bug 1287594.

Comment 3 Remi Collet 2016-11-09 09:13:14 UTC
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.

Comment 4 Florian Festi 2016-11-09 10:19:05 UTC
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.

Comment 5 Neal Gompa 2016-11-09 14:06:32 UTC
(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.

Comment 6 Neal Gompa 2016-11-09 14:08:52 UTC
(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

Comment 7 Remi Collet 2016-11-09 14:17:52 UTC
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.

Comment 8 Neal Gompa 2016-11-10 16:06:23 UTC
(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.

Comment 9 Neal Gompa 2016-11-10 16:07:00 UTC
Err...

Requires:  ((php-composer(justinrainbow/json-schema) < 3) and (php-(composer(justinrainbow/json-schema) >= 1.6))

Comment 10 Remi Collet 2016-11-11 09:10:07 UTC
An example showing why boolean doesn't not solves "range version" dependency:

# rpm -q rpm
rpm-4.13.0-1.fc25.x86_64

# 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.

Comment 11 Vít Ondruch 2016-11-11 09:28:35 UTC
(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 ;)

Comment 12 Igor Gnatenko 2016-11-16 08:26:30 UTC
*** Bug 1287594 has been marked as a duplicate of this bug. ***

Comment 13 Panu Matilainen 2017-08-23 14:20:41 UTC
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)


Note You need to log in before you can comment on or make changes to this bug.