Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: pms-bugs@g.o
Subject: [gentoo-dev] [RFC] New version constraints: variant one
Date: Thu, 10 Nov 2016 22:54:16
Message-Id: 20161110235340.3203d688.mgorny@gentoo.org
1 Hello, everyone.
2
3 Following my earlier threads, I'd like to propose a first complete
4 solution for new version restrictions for package dependencies. I
5 honestly doubt it's going to be approved since it's a major change.
6 Nevertheless, I think it's an interesting topic for consideration.
7
8 What is included:
9
10 - conjunctive version ranges,
11 - revision-free and revision-oriented comparisons,
12 - full set of (blocker-free) logical operators.
13
14 What isn't included:
15
16 - disjunctive version ranges,
17 - complete lower bound problem solution,
18 - extensions for prefix matching,
19 - some convenience shortcuts like Ruby's ~> op.
20
21
22 Backwards compatibility [recommended]
23 =====================================
24
25 For backwards compatibility, package dependency specifications using
26 old-style restrictions will still be accepted. Those specifications
27 will retain the old behavior, and have no new features.
28
29
30 New package dependency syntax
31 =============================
32
33 New-style package dependencies use the following syntax:
34
35 <cat> "/" <pkg> [":" <slot>] ["[" <vers> "]"] ["[" <usedep> "]"]
36
37 with <vers> now using the following sub-syntax:
38
39 <op> <version> ["," <op> <version>...]
40
41 The version restriction operator is removed from the front and all
42 package dependency specifications start with the category and package
43 name, followed by optional package slot. This can be followed by
44 optional version restrictions and USE flag restrictions.
45
46 The version constraints (if present) must *always* be placed inside
47 square brackets, even for a single constraint. Each constraint starts
48 with an operator followed by a version string. Multiple constraints are
49 separated using "," character, and are conjunctive (AND-ed).
50
51 The operators are not valid for beginning of a USE dependency string,
52 therefore the version constraint can be clearly distinguished from USE
53 contraints.
54
55 The version and USE flag constraints are always disjoint. If both are
56 present, they must be surrounded by separate pairs of brackets.
57
58 Examples:
59
60 dev-foo/bar:13[foo] # slot + USE
61 dev-foo/bar[>=3] # single version constraint
62 dev-foo/bar:4[>=4.11,<4.20] # slot + version range
63 dev-foo/bar[>=3][foo] # version + USE
64
65
66 Version restrictions
67 ====================
68
69 Each version restriction consists of an operator followed by a version
70 string.
71
72 The following revision-free version comparison operators are provided:
73
74 == exact version match, or prefix match (with *)
75 != exact version non-match, or prefix non-match (with *)
76 < version less than match
77 <= version less or equal to match
78 > version greater than match
79 >= version greater or equal to match
80
81 All those operators compare on versions ignoring the revision part.
82 They must be followed by a valid version with no revision part.
83 Additionally, the == and != operators can accept a version followed by
84 * to indicate prefix match.
85
86 The following revision-oriented version comparison operators are
87 provided:
88
89 === exact version+revision match
90 !== exact version+revision non-match
91 <== version+revision less or equal to match
92 >== version+revision greater or equal to match
93
94 Those operators include both version and revision in the comparison.
95 They must be followed by a valid version with an optional revision
96 part. No revision is equal to -r0. Prefix match is not allowed.
97
98 Examples:
99
100 [==1.3.3] version 1.3.3, any revision
101 [>1.3.3] version >1.3.3 (e.g. 1.3.3.1 or 1.3.4...)
102 [<=1.3.3] version <=1.3.3 (incl. any revision of 1.3.3)
103 [===1.3.3] 1.3.3-r0
104 [>==1.3.3-r2] 1.3.3-r2 or newer
105 [>=1.2,!=1.3.3] version >=1.2 but not 1.3.3 (any revision)
106 [>=1.2,<1.4] version >=1.2 but <1.4
107 [==1.2*] any version starting with 1.2 prefix
108 [>=1.2,<1.8,!=1.6*] version >=1.2 but <1.8, also excluding 1.6*
109
110
111 Mapping from existing dependency syntax
112 =======================================
113
114 It should be noted that whenever revision match is desired, one of *==
115 operators need to be used. They do not include '<' or '>' variants, so
116 the revision needs to be decreased or increased appropriately for <==
117 or >==.
118
119 The behavior of current '~' operator is now equal to '==', so the
120 former is removed.
121
122 =foo-1.2.3 ===1.2.3
123 =foo-1.2.3-r3 ===1.2.3-r3
124 =foo-1.2.3* ==1.2.3*
125 ~foo-1.2.3 ==1.2.3
126 >foo-1.2.3 >==1.2.3-r1
127 >foo-1.2.3-r9999 >1.2.3
128 >=foo-1.2.3 >=1.2.3 or >==1.2.3
129 >=foo-1.2.3-r3 >==1.2.3-r3
130 <foo-1.2.3 <1.2.3
131 <foo-1.2.3-r4 <==1.2.3-r3
132 <=foo-1.2.3 <==1.2.3
133 <=foo-1.2.3-r3 <==1.2.3-r3
134 <=foo-1.2.3-r9999 <=1.2.3
135
136
137 Solutions to other problems
138 ===========================
139
140 The provided operators make it possible to quite conveniently express
141 common types of dependencies. The remaining kinds can be constructed
142 using conjunctive ranges combined with existing operators.
143 In particular, for this specific reason the != and !== operators are
144 provided.
145
146 Disjunctive version ranges were considered needed rarely. If specific
147 versions needs to be excluded from the base version range, the !=
148 and !== operators (optionally in the prefix matching mode) can be used
149 to do so.
150
151 [>=1.2,<1.6,!=1.4*,!=1.5*]
152
153 While I agree that this is not perfect and can become quite verbose at
154 times, the use cases for it are rather limited.
155
156 Revision ranges can be easily constructed using version ranges:
157
158 [>==1.3-r3,<==1.3-r7]
159
160 Not that I see any real use for them.
161
162 Pre-release version ranges can be achieved using the relatively safe
163 _alpha_alpha or _p_p suffixes, or just predicting the upstream version
164 use.
165
166 The convenience Ruby ~> operator needs to be expanded to the verbose
167 range:
168
169 [>=1.3.4,<1.4] or [>=1.3.4,==1.3*]
170
171
172 Rationale
173 =========
174
175 The key goal behind this concept is to optimize for upstream version
176 specifications, and provide the minimal reasonable, clear, symmetric
177 set of tools needed to achieve the correct dependencies.
178
179 The version syntax changes are necessary to be able to clearly express
180 version ranges, and also to distinguish old and new operators.
181 Furthermore, they increase the readability and usefulness of package
182 dependency specifications. The square braces and ordering are based
183 after Exherbo but can be changed if necessary.
184
185 The "," separator for versions is copied from USE dependencies which
186 are conjunctive as well. The disjunctive variant was not included since
187 our research has shown that it is used very rarely (i.e. only once
188 in the few base Exherbo repositories we've checked). Any more complex
189 logic would only make the dependencies less readable for unlikely
190 benefit.
191
192 The default behavior for new operators is meant to accommodate
193 the common necessity of expressing upstream version restrictions
194 in ebuilds. Its major advantage is that all the operators behave
195 symmetrically now (i.e. you don't have to add -r9999 to some of them to
196 match upstream constraints).
197
198 The additional ===, !==, >==, <== operators are provided to accommodate
199 Gentoo-specific revision constraints, and distinguish them from plain
200 upstream version constraints. No variant for '<' and '>' is provided
201 since the resulting syntax would be colliding or confusing, and all
202 possible revisions can be already expressed clearly using existing
203 operators.
204
205 Negations were added for the == and === equality operators to help
206 constructing version ranges. They also provide major readability
207 (and behavior) benefit over the current necessity of disallowing
208 single versions via blockers.
209
210 The prefix matching behavior was retained since it has its use cases.
211 Furthermore, it becomes useful with conjunctive version ranger to
212 disallow single versions matching a generic range.
213
214 --
215 Best regards,
216 Michał Górny
217 <http://dev.gentoo.org/~mgorny/>

Replies