Skip to content

Commit df0abdf

Browse files
committed
Remove AnyVersion and WildcardVersion constructors
These constructors don't carry any additional semantics. They were used in `cabal check` implementation, but now already parser reports errors so we don't need these redundant constructors anymore. MajorBoundVersion (^>=) has slightly different semantics: we want be able to relax only `^>= x.y.z` upper bounds. Therefore it's preserved.
1 parent b89a1c6 commit df0abdf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+619
-452
lines changed

Cabal/Cabal-quickcheck/src/Test/QuickCheck/Instances/Cabal.hs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ instance Arbitrary Version where
6363
,(1, return 0xfffd)
6464
,(1, return 0xfffe) -- max fitting into packed W64
6565
,(1, return 0xffff)
66+
,(1, return 999999998)
6667
,(1, return 999999999)
6768
,(1, return 0x10000)]
6869
return (mkVersion branch)
@@ -84,7 +85,7 @@ instance Arbitrary VersionRange where
8485
, (1, fmap earlierVersion arbitrary)
8586
, (1, fmap orEarlierVersion arbitrary)
8687
, (1, fmap orEarlierVersion' arbitrary)
87-
, (1, fmap withinVersion arbitrary)
88+
, (1, fmap withinVersion arbitraryV)
8889
, (1, fmap majorBoundVersion arbitrary)
8990
] ++ if n == 0 then [] else
9091
[ (2, liftA2 unionVersionRanges verRangeExp2 verRangeExp2)
@@ -93,18 +94,19 @@ instance Arbitrary VersionRange where
9394
where
9495
verRangeExp2 = verRangeExp (n `div` 2)
9596

97+
arbitraryV :: Gen Version
98+
arbitraryV = arbitrary `suchThat` \v -> all (< 999999999) (versionNumbers v)
99+
96100
orLaterVersion' v =
97101
unionVersionRanges (LaterVersion v) (ThisVersion v)
98102
orEarlierVersion' v =
99103
unionVersionRanges (EarlierVersion v) (ThisVersion v)
100104

101-
shrink AnyVersion = []
102105
shrink (ThisVersion v) = map ThisVersion (shrink v)
103106
shrink (LaterVersion v) = map LaterVersion (shrink v)
104107
shrink (EarlierVersion v) = map EarlierVersion (shrink v)
105108
shrink (OrLaterVersion v) = LaterVersion v : map OrLaterVersion (shrink v)
106109
shrink (OrEarlierVersion v) = EarlierVersion v : map OrEarlierVersion (shrink v)
107-
shrink (WildcardVersion v) = map WildcardVersion ( shrink v)
108110
shrink (MajorBoundVersion v) = map MajorBoundVersion (shrink v)
109111
shrink (UnionVersionRanges a b) = a : b : map (uncurry UnionVersionRanges) (shrink (a, b))
110112
shrink (IntersectVersionRanges a b) = a : b : map (uncurry IntersectVersionRanges) (shrink (a, b))

Cabal/Distribution/Types/Dependency.hs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import Distribution.Compat.Prelude
1515
import Prelude ()
1616

1717
import Distribution.Version
18-
(VersionRange, anyVersion, notThisVersion, simplifyVersionRange, thisVersion)
18+
(VersionRange, anyVersion,notThisVersion, simplifyVersionRange, thisVersion)
19+
import Distribution.Types.VersionRange (isAnyVersionLight)
1920

2021
import Distribution.CabalSpecVersion
2122
import Distribution.Compat.CharParsing (char, spaces)
@@ -76,8 +77,12 @@ instance Structured Dependency
7677
instance NFData Dependency where rnf = genericRnf
7778

7879
instance Pretty Dependency where
79-
pretty (Dependency name ver sublibs) = withSubLibs (pretty name) <+> pretty ver
80+
pretty (Dependency name ver sublibs) = withSubLibs (pretty name) <+> pver
8081
where
82+
-- TODO: change to isAnyVersion after #6736
83+
pver | isAnyVersionLight ver = PP.empty
84+
| otherwise = pretty ver
85+
8186
withSubLibs doc
8287
| sublibs == mainLib = doc
8388
| otherwise = doc <<>> PP.colon <<>> PP.braces prettySublibs
@@ -90,13 +95,13 @@ instance Pretty Dependency where
9095
-- |
9196
--
9297
-- >>> simpleParsec "mylib:sub" :: Maybe Dependency
93-
-- Just (Dependency (PackageName "mylib") AnyVersion (fromList [LSubLibName (UnqualComponentName "sub")]))
98+
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LSubLibName (UnqualComponentName "sub")]))
9499
--
95100
-- >>> simpleParsec "mylib:{sub1,sub2}" :: Maybe Dependency
96-
-- Just (Dependency (PackageName "mylib") AnyVersion (fromList [LSubLibName (UnqualComponentName "sub1"),LSubLibName (UnqualComponentName "sub2")]))
101+
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LSubLibName (UnqualComponentName "sub1"),LSubLibName (UnqualComponentName "sub2")]))
97102
--
98103
-- >>> simpleParsec "mylib:{ sub1 , sub2 }" :: Maybe Dependency
99-
-- Just (Dependency (PackageName "mylib") AnyVersion (fromList [LSubLibName (UnqualComponentName "sub1"),LSubLibName (UnqualComponentName "sub2")]))
104+
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LSubLibName (UnqualComponentName "sub1"),LSubLibName (UnqualComponentName "sub2")]))
100105
--
101106
-- >>> simpleParsec "mylib:{ sub1 , sub2 } ^>= 42" :: Maybe Dependency
102107
-- Just (Dependency (PackageName "mylib") (MajorBoundVersion (mkVersion [42])) (fromList [LSubLibName (UnqualComponentName "sub1"),LSubLibName (UnqualComponentName "sub2")]))
@@ -105,9 +110,9 @@ instance Pretty Dependency where
105110
-- Just (Dependency (PackageName "mylib") (MajorBoundVersion (mkVersion [42])) (fromList []))
106111
--
107112
-- >>> traverse_ print (map simpleParsec ["mylib:mylib", "mylib:{mylib}", "mylib:{mylib,sublib}" ] :: [Maybe Dependency])
108-
-- Just (Dependency (PackageName "mylib") AnyVersion (fromList [LMainLibName]))
109-
-- Just (Dependency (PackageName "mylib") AnyVersion (fromList [LMainLibName]))
110-
-- Just (Dependency (PackageName "mylib") AnyVersion (fromList [LMainLibName,LSubLibName (UnqualComponentName "sublib")]))
113+
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LMainLibName]))
114+
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LMainLibName]))
115+
-- Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LMainLibName,LSubLibName (UnqualComponentName "sublib")]))
111116
--
112117
-- Spaces around colon are not allowed:
113118
--
@@ -117,7 +122,7 @@ instance Pretty Dependency where
117122
-- Sublibrary syntax is accepted since @cabal-version: 3.0@
118123
--
119124
-- >>> map (`simpleParsec'` "mylib:sub") [CabalSpecV2_4, CabalSpecV3_0] :: [Maybe Dependency]
120-
-- [Nothing,Just (Dependency (PackageName "mylib") AnyVersion (fromList [LSubLibName (UnqualComponentName "sub")]))]
125+
-- [Nothing,Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromList [LSubLibName (UnqualComponentName "sub")]))]
121126
--
122127
instance Parsec Dependency where
123128
parsec = do
@@ -157,7 +162,7 @@ mainLib = Set.singleton LMainLibName
157162
instance Described Dependency where
158163
describe _ = REAppend
159164
[ RENamed "pkg-name" (describe (Proxy :: Proxy PackageName))
160-
, REOpt $
165+
, REOpt $
161166
reChar ':'
162167
<> REUnion
163168
[ reUnqualComponent
@@ -168,7 +173,7 @@ instance Described Dependency where
168173
, REMunch reSpacedComma reUnqualComponent
169174
, RESpaces
170175
, reChar '}'
171-
]
176+
]
172177
]
173178
-- TODO: RESpaces1 should be just RESpaces, but we are able
174179
-- to generate non-parseable strings without mandatory space

Cabal/Distribution/Types/ExeDependency.hs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ import Distribution.Pretty
1414
import Distribution.Types.ComponentName
1515
import Distribution.Types.PackageName
1616
import Distribution.Types.UnqualComponentName
17-
import Distribution.Version (VersionRange, anyVersion)
17+
import Distribution.Version (VersionRange, anyVersion, isAnyVersion)
1818

1919
import qualified Distribution.Compat.CharParsing as P
20-
import Text.PrettyPrint (text, (<+>))
20+
import qualified Text.PrettyPrint as PP
2121

2222
-- | Describes a dependency on an executable from a package
2323
--
@@ -33,14 +33,17 @@ instance NFData ExeDependency where rnf = genericRnf
3333

3434
instance Pretty ExeDependency where
3535
pretty (ExeDependency name exe ver) =
36-
(pretty name <<>> text ":" <<>> pretty exe) <+> pretty ver
36+
pretty name <<>> PP.colon <<>> pretty exe PP.<+> pver
37+
where
38+
pver | isAnyVersion ver = PP.empty
39+
| otherwise = pretty ver
3740

3841
-- |
3942
--
4043
-- Examples
4144
--
4245
-- >>> simpleParsec "happy:happy" :: Maybe ExeDependency
43-
-- Just (ExeDependency (PackageName "happy") (UnqualComponentName "happy") AnyVersion)
46+
-- Just (ExeDependency (PackageName "happy") (UnqualComponentName "happy") (OrLaterVersion (mkVersion [0])))
4447
--
4548
-- >>> simpleParsec "happy:happy >= 1.19.12" :: Maybe ExeDependency
4649
-- Just (ExeDependency (PackageName "happy") (UnqualComponentName "happy") (OrLaterVersion (mkVersion [1,19,12])))

Cabal/Distribution/Types/PkgconfigDependency.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ instance Structured PkgconfigDependency
3030
instance NFData PkgconfigDependency where rnf = genericRnf
3131

3232
instance Pretty PkgconfigDependency where
33-
pretty (PkgconfigDependency name ver) =
34-
pretty name <+> pretty ver
33+
pretty (PkgconfigDependency name PcAnyVersion) = pretty name
34+
pretty (PkgconfigDependency name ver) = pretty name <+> pretty ver
3535

3636
instance Parsec PkgconfigDependency where
3737
parsec = do

Cabal/Distribution/Types/PkgconfigVersionRange.hs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Distribution.Parsec
1818
import Distribution.Pretty
1919
import Distribution.Types.PkgconfigVersion
2020
import Distribution.Types.Version
21+
import Distribution.Types.VersionInterval
2122
import Distribution.Types.VersionRange
2223

2324
import qualified Data.ByteString.Char8 as BS8
@@ -142,10 +143,19 @@ versionToPkgconfigVersion :: Version -> PkgconfigVersion
142143
versionToPkgconfigVersion = PkgconfigVersion . BS8.pack . prettyShow
143144

144145
versionRangeToPkgconfigVersionRange :: VersionRange -> PkgconfigVersionRange
145-
versionRangeToPkgconfigVersionRange = foldVersionRange
146-
anyPkgconfigVersion
147-
(PcThisVersion . versionToPkgconfigVersion)
148-
(PcLaterVersion . versionToPkgconfigVersion)
149-
(PcEarlierVersion . versionToPkgconfigVersion)
150-
PcUnionVersionRanges
151-
PcIntersectVersionRanges
146+
versionRangeToPkgconfigVersionRange vr
147+
| isAnyVersion vr
148+
= PcAnyVersion
149+
| otherwise
150+
= case asVersionIntervals vr of
151+
[] -> PcEarlierVersion (PkgconfigVersion (BS8.pack "0"))
152+
(i:is) -> foldl (\r j -> PcUnionVersionRanges r (conv j)) (conv i) is
153+
where
154+
conv (LowerBound v b, NoUpperBound) = convL v b
155+
conv (LowerBound v b, UpperBound u c) = PcIntersectVersionRanges (convL v b) (convU u c)
156+
157+
convL v ExclusiveBound = PcLaterVersion (versionToPkgconfigVersion v)
158+
convL v InclusiveBound = PcOrLaterVersion (versionToPkgconfigVersion v)
159+
160+
convU v ExclusiveBound = PcEarlierVersion (versionToPkgconfigVersion v)
161+
convU v InclusiveBound = PcOrEarlierVersion (versionToPkgconfigVersion v)

Cabal/Distribution/Types/VersionInterval.hs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import Distribution.Compat.Prelude
2626
import Control.Exception (assert)
2727

2828
import Distribution.Types.Version
29-
import Distribution.Types.VersionRange
29+
import Distribution.Types.VersionRange.Internal
3030

3131
-- NonEmpty
3232
import qualified Prelude (foldr1)
@@ -200,15 +200,18 @@ withinIntervals v (VersionIntervals intervals) = any withinInterval intervals
200200
-- | Convert a 'VersionRange' to a sequence of version intervals.
201201
--
202202
toVersionIntervals :: VersionRange -> VersionIntervals
203-
toVersionIntervals = foldVersionRange
204-
( chkIvl (minLowerBound, NoUpperBound))
205-
(\v -> chkIvl (LowerBound v InclusiveBound, UpperBound v InclusiveBound))
206-
(\v -> chkIvl (LowerBound v ExclusiveBound, NoUpperBound))
207-
(\v -> if isVersion0 v then VersionIntervals [] else
208-
chkIvl (minLowerBound, UpperBound v ExclusiveBound))
209-
unionVersionIntervals
210-
intersectVersionIntervals
211-
where
203+
toVersionIntervals = cataVersionRange alg where
204+
alg (ThisVersionF v) = chkIvl (LowerBound v InclusiveBound, UpperBound v InclusiveBound)
205+
alg (LaterVersionF v) = chkIvl (LowerBound v ExclusiveBound, NoUpperBound)
206+
alg (OrLaterVersionF v) = chkIvl (LowerBound v InclusiveBound, NoUpperBound)
207+
alg (EarlierVersionF v)
208+
| isVersion0 v = VersionIntervals []
209+
| otherwise = chkIvl (minLowerBound, UpperBound v ExclusiveBound)
210+
alg (OrEarlierVersionF v) = chkIvl (minLowerBound, UpperBound v InclusiveBound)
211+
alg (MajorBoundVersionF v) = chkIvl (LowerBound v InclusiveBound, UpperBound (majorUpperBound v) ExclusiveBound)
212+
alg (UnionVersionRangesF v1 v2) = unionVersionIntervals v1 v2
213+
alg (IntersectVersionRangesF v1 v2) = intersectVersionIntervals v1 v2
214+
212215
chkIvl interval = checkInvariant (VersionIntervals [interval])
213216

214217
-- | Convert a 'VersionIntervals' value back into a 'VersionRange' expression
@@ -223,9 +226,6 @@ fromVersionIntervals (VersionIntervals intervals) =
223226
interval (LowerBound v InclusiveBound)
224227
(UpperBound v' InclusiveBound) | v == v'
225228
= thisVersion v
226-
interval (LowerBound v InclusiveBound)
227-
(UpperBound v' ExclusiveBound) | isWildcardRange v v'
228-
= withinVersion v
229229
interval l u = lowerBound l `intersectVersionRanges'` upperBound u
230230

231231
lowerBound (LowerBound v InclusiveBound)

Cabal/Distribution/Types/VersionRange.hs

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ module Distribution.Types.VersionRange (
3030
embedVersionRange,
3131

3232
-- ** Utilities
33+
isAnyVersion,
34+
isAnyVersionLight,
3335
wildcardUpperBound,
3436
majorUpperBound,
3537
isWildcardRange,
@@ -38,8 +40,8 @@ module Distribution.Types.VersionRange (
3840

3941
import Distribution.Compat.Prelude
4042
import Distribution.Types.Version
43+
import Distribution.Types.VersionInterval
4144
import Distribution.Types.VersionRange.Internal
42-
import Distribution.Utils.Generic
4345
import Prelude ()
4446

4547
-- | Fold over the basic syntactic structure of a 'VersionRange'.
@@ -57,25 +59,19 @@ foldVersionRange :: a -- ^ @\"-any\"@ version
5759
-> (a -> a -> a) -- ^ @\"_ || _\"@ union
5860
-> (a -> a -> a) -- ^ @\"_ && _\"@ intersection
5961
-> VersionRange -> a
60-
foldVersionRange anyv this later earlier union intersect = fold
62+
foldVersionRange _any this later earlier union intersect = fold
6163
where
6264
fold = cataVersionRange alg
6365

64-
alg AnyVersionF = anyv
6566
alg (ThisVersionF v) = this v
6667
alg (LaterVersionF v) = later v
6768
alg (OrLaterVersionF v) = union (this v) (later v)
6869
alg (EarlierVersionF v) = earlier v
6970
alg (OrEarlierVersionF v) = union (this v) (earlier v)
70-
alg (WildcardVersionF v) = fold (wildcard v)
7171
alg (MajorBoundVersionF v) = fold (majorBound v)
7272
alg (UnionVersionRangesF v1 v2) = union v1 v2
7373
alg (IntersectVersionRangesF v1 v2) = intersect v1 v2
7474

75-
wildcard v = intersectVersionRanges
76-
(orLaterVersion v)
77-
(earlierVersion (wildcardUpperBound v))
78-
7975
majorBound v = intersectVersionRanges
8076
(orLaterVersion v)
8177
(earlierVersion (majorUpperBound v))
@@ -122,16 +118,35 @@ withinRange v = foldVersionRange
122118
(||)
123119
(&&)
124120

121+
-- | Does this 'VersionRange' place any restriction on the 'Version' or is it
122+
-- in fact equivalent to 'AnyVersion'.
123+
--
124+
-- Note this is a semantic check, not simply a syntactic check. So for example
125+
-- the following is @True@ (for all @v@).
126+
--
127+
-- > isAnyVersion (EarlierVersion v `UnionVersionRanges` orLaterVersion v)
128+
--
129+
isAnyVersion :: VersionRange -> Bool
130+
isAnyVersion vr = case asVersionIntervals vr of
131+
[(LowerBound v InclusiveBound, NoUpperBound)] -> v == version0
132+
_ -> False
133+
134+
-- A fast and non-precise version of 'isAnyVersion',
135+
-- returns 'True' only for @>= 0@ 'VersionRange's.
136+
--
137+
-- /Do not use/. The "VersionIntervals don't destroy MajorBoundVersion"
138+
-- https://github.com/haskell/cabal/pull/6736 pull-request
139+
-- will change 'simplifyVersionRange' to properly preserve semantics.
140+
-- Then we can use it to normalise 'VersionRange's in tests.
141+
--
142+
isAnyVersionLight :: VersionRange -> Bool
143+
isAnyVersionLight (OrLaterVersion v) = v == version0
144+
isAnyVersionLight _vr = False
145+
125146
----------------------------
126147
-- Wildcard range utilities
127148
--
128149

129-
-- | @since 2.2
130-
wildcardUpperBound :: Version -> Version
131-
wildcardUpperBound = alterVersion $
132-
\lowerBound -> case unsnoc lowerBound of
133-
Nothing -> []
134-
Just (xs, x) -> xs ++ [x + 1]
135150

136151
isWildcardRange :: Version -> Version -> Bool
137152
isWildcardRange ver1 ver2 = check (versionNumbers ver1) (versionNumbers ver2)

0 commit comments

Comments
 (0)