haskell / cabal

Official upstream development repository for Cabal and cabal-install
https://haskell.org/cabal
Other
1.62k stars 697 forks source link

Version is not separated, VersionIntervals (current and Legacy) machinery doesn't take that into account. #8486

Open phadej opened 2 years ago

phadej commented 2 years ago

By separated I mean that there would be a version between any pair of distinct versions. That is not true.

For example, there is no version between 1 and 1.0, and VersionInterval machinery doesn't take that into account. It fails to simplify:

import Data.Maybe

import Distribution.Pretty
import Distribution.Parsec
import Distribution.Types.VersionRange
import Distribution.Version 
import qualified Distribution.Types.VersionInterval.Legacy as O
import qualified Distribution.Types.VersionInterval as N

unsafeParsec s = either error id (eitherParsec s)

main :: IO ()
main = do
    putStrLn $ prettyShow $ O.fromVersionIntervals . O.toVersionIntervals $ unsafeParsec "<=1 || >=1.0" -- expected >=0 i.e. anyVersion
    putStrLn $ prettyShow $ N.fromVersionIntervals . N.toVersionIntervals $ unsafeParsec "<=1 || >=1.0" -- expected >=0 i.e. anyVersion

    putStrLn $ prettyShow $ O.fromVersionIntervals . O.toVersionIntervals $ unsafeParsec ">0 && <0.0" -- expected <0
    putStrLn $ prettyShow $ N.fromVersionIntervals . N.toVersionIntervals $ unsafeParsec ">0 && <0.0" -- expected <0
phadej commented 2 years ago

And because of existence of

succVersion :: Version -> Version
succVersion v = mkVersion (versionNumbers v ++ [0])

The VersionInterval implementation can be simplified.

>x.y.z   -->  >=x.y.z.0
<=x.y.z ---> <x.y.z.0

This would cause some "ugly" versions, but that is not an issue as most version intervals are >=x && <y, i.e. inclusive lower bound and exclusive upper bound.

The only downside is that excluded version will look "funny": <3.1.4 || >3.1.4 normalized to <3.1.4 || >=3.1.4.0