@@ -12,6 +12,7 @@ import (
12
12
// checked against.
13
13
type Constraints struct {
14
14
constraints [][]* constraint
15
+ containsPre []bool
15
16
}
16
17
17
18
// NewConstraint returns a Constraints instance that a Version instance can
@@ -22,11 +23,10 @@ func NewConstraint(c string) (*Constraints, error) {
22
23
c = rewriteRange (c )
23
24
24
25
ors := strings .Split (c , "||" )
25
- or := make ([][]* constraint , len (ors ))
26
+ lenors := len (ors )
27
+ or := make ([][]* constraint , lenors )
28
+ hasPre := make ([]bool , lenors )
26
29
for k , v := range ors {
27
-
28
- // TODO: Find a way to validate and fetch all the constraints in a simpler form
29
-
30
30
// Validate the segment
31
31
if ! validConstraintRegex .MatchString (v ) {
32
32
return nil , fmt .Errorf ("improper constraint: %s" , v )
@@ -43,12 +43,22 @@ func NewConstraint(c string) (*Constraints, error) {
43
43
return nil , err
44
44
}
45
45
46
+ // If one of the constraints has a prerelease record this.
47
+ // This information is used when checking all in an "and"
48
+ // group to ensure they all check for prereleases.
49
+ if pc .con .pre != "" {
50
+ hasPre [k ] = true
51
+ }
52
+
46
53
result [i ] = pc
47
54
}
48
55
or [k ] = result
49
56
}
50
57
51
- o := & Constraints {constraints : or }
58
+ o := & Constraints {
59
+ constraints : or ,
60
+ containsPre : hasPre ,
61
+ }
52
62
return o , nil
53
63
}
54
64
@@ -57,10 +67,10 @@ func (cs Constraints) Check(v *Version) bool {
57
67
// TODO(mattfarina): For v4 of this library consolidate the Check and Validate
58
68
// functions as the underlying functions make that possible now.
59
69
// loop over the ORs and check the inner ANDs
60
- for _ , o := range cs .constraints {
70
+ for i , o := range cs .constraints {
61
71
joy := true
62
72
for _ , c := range o {
63
- if check , _ := c .check (v ); ! check {
73
+ if check , _ := c .check (v , cs . containsPre [ i ] ); ! check {
64
74
joy = false
65
75
break
66
76
}
@@ -83,12 +93,12 @@ func (cs Constraints) Validate(v *Version) (bool, []error) {
83
93
// Capture the prerelease message only once. When it happens the first time
84
94
// this var is marked
85
95
var prerelesase bool
86
- for _ , o := range cs .constraints {
96
+ for i , o := range cs .constraints {
87
97
joy := true
88
98
for _ , c := range o {
89
99
// Before running the check handle the case there the version is
90
100
// a prerelease and the check is not searching for prereleases.
91
- if c . con . pre == "" && v .pre != "" {
101
+ if ! cs . containsPre [ i ] && v .pre != "" {
92
102
if ! prerelesase {
93
103
em := fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
94
104
e = append (e , em )
@@ -98,7 +108,7 @@ func (cs Constraints) Validate(v *Version) (bool, []error) {
98
108
99
109
} else {
100
110
101
- if _ , err := c .check (v ); err != nil {
111
+ if _ , err := c .check (v , cs . containsPre [ i ] ); err != nil {
102
112
e = append (e , err )
103
113
joy = false
104
114
}
@@ -227,16 +237,16 @@ type constraint struct {
227
237
}
228
238
229
239
// Check if a version meets the constraint
230
- func (c * constraint ) check (v * Version ) (bool , error ) {
231
- return constraintOps [c.origfunc ](v , c )
240
+ func (c * constraint ) check (v * Version , includePre bool ) (bool , error ) {
241
+ return constraintOps [c.origfunc ](v , c , includePre )
232
242
}
233
243
234
244
// String prints an individual constraint into a string
235
245
func (c * constraint ) string () string {
236
246
return c .origfunc + c .orig
237
247
}
238
248
239
- type cfunc func (v * Version , c * constraint ) (bool , error )
249
+ type cfunc func (v * Version , c * constraint , includePre bool ) (bool , error )
240
250
241
251
func parseConstraint (c string ) (* constraint , error ) {
242
252
if len (c ) > 0 {
@@ -305,16 +315,14 @@ func parseConstraint(c string) (*constraint, error) {
305
315
}
306
316
307
317
// Constraint functions
308
- func constraintNotEqual (v * Version , c * constraint ) (bool , error ) {
309
- if c .dirty {
310
-
311
- // If there is a pre-release on the version but the constraint isn't looking
312
- // for them assume that pre-releases are not compatible. See issue 21 for
313
- // more details.
314
- if v .Prerelease () != "" && c .con .Prerelease () == "" {
315
- return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
316
- }
318
+ func constraintNotEqual (v * Version , c * constraint , includePre bool ) (bool , error ) {
319
+ // The existence of prereleases is checked at the group level and passed in.
320
+ // Exit early if the version has a prerelease but those are to be ignored.
321
+ if v .Prerelease () != "" && ! includePre {
322
+ return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
323
+ }
317
324
325
+ if c .dirty {
318
326
if c .con .Major () != v .Major () {
319
327
return true , nil
320
328
}
@@ -345,12 +353,11 @@ func constraintNotEqual(v *Version, c *constraint) (bool, error) {
345
353
return true , nil
346
354
}
347
355
348
- func constraintGreaterThan (v * Version , c * constraint ) (bool , error ) {
356
+ func constraintGreaterThan (v * Version , c * constraint , includePre bool ) (bool , error ) {
349
357
350
- // If there is a pre-release on the version but the constraint isn't looking
351
- // for them assume that pre-releases are not compatible. See issue 21 for
352
- // more details.
353
- if v .Prerelease () != "" && c .con .Prerelease () == "" {
358
+ // The existence of prereleases is checked at the group level and passed in.
359
+ // Exit early if the version has a prerelease but those are to be ignored.
360
+ if v .Prerelease () != "" && ! includePre {
354
361
return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
355
362
}
356
363
@@ -391,11 +398,10 @@ func constraintGreaterThan(v *Version, c *constraint) (bool, error) {
391
398
return false , fmt .Errorf ("%s is less than or equal to %s" , v , c .orig )
392
399
}
393
400
394
- func constraintLessThan (v * Version , c * constraint ) (bool , error ) {
395
- // If there is a pre-release on the version but the constraint isn't looking
396
- // for them assume that pre-releases are not compatible. See issue 21 for
397
- // more details.
398
- if v .Prerelease () != "" && c .con .Prerelease () == "" {
401
+ func constraintLessThan (v * Version , c * constraint , includePre bool ) (bool , error ) {
402
+ // The existence of prereleases is checked at the group level and passed in.
403
+ // Exit early if the version has a prerelease but those are to be ignored.
404
+ if v .Prerelease () != "" && ! includePre {
399
405
return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
400
406
}
401
407
@@ -406,12 +412,11 @@ func constraintLessThan(v *Version, c *constraint) (bool, error) {
406
412
return false , fmt .Errorf ("%s is greater than or equal to %s" , v , c .orig )
407
413
}
408
414
409
- func constraintGreaterThanEqual (v * Version , c * constraint ) (bool , error ) {
415
+ func constraintGreaterThanEqual (v * Version , c * constraint , includePre bool ) (bool , error ) {
410
416
411
- // If there is a pre-release on the version but the constraint isn't looking
412
- // for them assume that pre-releases are not compatible. See issue 21 for
413
- // more details.
414
- if v .Prerelease () != "" && c .con .Prerelease () == "" {
417
+ // The existence of prereleases is checked at the group level and passed in.
418
+ // Exit early if the version has a prerelease but those are to be ignored.
419
+ if v .Prerelease () != "" && ! includePre {
415
420
return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
416
421
}
417
422
@@ -422,11 +427,10 @@ func constraintGreaterThanEqual(v *Version, c *constraint) (bool, error) {
422
427
return false , fmt .Errorf ("%s is less than %s" , v , c .orig )
423
428
}
424
429
425
- func constraintLessThanEqual (v * Version , c * constraint ) (bool , error ) {
426
- // If there is a pre-release on the version but the constraint isn't looking
427
- // for them assume that pre-releases are not compatible. See issue 21 for
428
- // more details.
429
- if v .Prerelease () != "" && c .con .Prerelease () == "" {
430
+ func constraintLessThanEqual (v * Version , c * constraint , includePre bool ) (bool , error ) {
431
+ // The existence of prereleases is checked at the group level and passed in.
432
+ // Exit early if the version has a prerelease but those are to be ignored.
433
+ if v .Prerelease () != "" && ! includePre {
430
434
return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
431
435
}
432
436
@@ -455,11 +459,10 @@ func constraintLessThanEqual(v *Version, c *constraint) (bool, error) {
455
459
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
456
460
// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
457
461
// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
458
- func constraintTilde (v * Version , c * constraint ) (bool , error ) {
459
- // If there is a pre-release on the version but the constraint isn't looking
460
- // for them assume that pre-releases are not compatible. See issue 21 for
461
- // more details.
462
- if v .Prerelease () != "" && c .con .Prerelease () == "" {
462
+ func constraintTilde (v * Version , c * constraint , includePre bool ) (bool , error ) {
463
+ // The existence of prereleases is checked at the group level and passed in.
464
+ // Exit early if the version has a prerelease but those are to be ignored.
465
+ if v .Prerelease () != "" && ! includePre {
463
466
return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
464
467
}
465
468
@@ -487,16 +490,15 @@ func constraintTilde(v *Version, c *constraint) (bool, error) {
487
490
488
491
// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
489
492
// it's a straight =
490
- func constraintTildeOrEqual (v * Version , c * constraint ) (bool , error ) {
491
- // If there is a pre-release on the version but the constraint isn't looking
492
- // for them assume that pre-releases are not compatible. See issue 21 for
493
- // more details.
494
- if v .Prerelease () != "" && c .con .Prerelease () == "" {
493
+ func constraintTildeOrEqual (v * Version , c * constraint , includePre bool ) (bool , error ) {
494
+ // The existence of prereleases is checked at the group level and passed in.
495
+ // Exit early if the version has a prerelease but those are to be ignored.
496
+ if v .Prerelease () != "" && ! includePre {
495
497
return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
496
498
}
497
499
498
500
if c .dirty {
499
- return constraintTilde (v , c )
501
+ return constraintTilde (v , c , includePre )
500
502
}
501
503
502
504
eq := v .Equal (c .con )
@@ -516,11 +518,10 @@ func constraintTildeOrEqual(v *Version, c *constraint) (bool, error) {
516
518
// ^0.0.3 --> >=0.0.3 <0.0.4
517
519
// ^0.0 --> >=0.0.0 <0.1.0
518
520
// ^0 --> >=0.0.0 <1.0.0
519
- func constraintCaret (v * Version , c * constraint ) (bool , error ) {
520
- // If there is a pre-release on the version but the constraint isn't looking
521
- // for them assume that pre-releases are not compatible. See issue 21 for
522
- // more details.
523
- if v .Prerelease () != "" && c .con .Prerelease () == "" {
521
+ func constraintCaret (v * Version , c * constraint , includePre bool ) (bool , error ) {
522
+ // The existence of prereleases is checked at the group level and passed in.
523
+ // Exit early if the version has a prerelease but those are to be ignored.
524
+ if v .Prerelease () != "" && ! includePre {
524
525
return false , fmt .Errorf ("%s is a prerelease version and the constraint is only looking for release versions" , v )
525
526
}
526
527
0 commit comments