PROPOSAL: Extended syntax for package version range specifications

In order to make it easy for package package authors to describe correct and robust dependencies we (Duncan Coutts and I) propose the following syntactical extension to version range specifications in package files. (1) Wildcards ~ 1.2.* ~~> >= 1.2 && < 1.3 in general ~ x.y.* ~~> >= x.y && < x.(y+1) The "~" operator should be read as "in the range of". Another option would have been "-", but this is used to specify exact versions in other parts of the Cabal infrastructure , e.g., "cabal install xmonad-0.5". This is the most common specification of package dependencies. The assumption is that changes in the last version number indicate only backwards compatible changes, as is suggested in the new package versioning policy [1]. The use of "*" matches the common usage as a wildcard character. (2) Upward Ranges ~ 1.2.1+ ~~> >= 1.2.1 && < 1.3 in general ~ x.y.z+ ~~> >= x.y.z && < x.(y+1) The idea here is that sometimes packages need a certain patch level or, as in Cabal's case, a stable release and possible further bugfixes. In those cases the wildcard notation is too liberal, however the explicit range description would be too noisy (and possibly error prone). (Also, using "+" instead of "*" serves as better visual distinction.) We believe, that these kinds of ranges will become very common, thus justifying a syntactic extension. It also encourages specifying correct dependency descriptions, thus could increase the quality of packages on Hackage overall. It could be argued that 1.2.3+ could be misunderstood as > 1.2.3. However, if package authors start to adopt the new package versioning policy, this would actually Do The Right Thing (tm). / Thomas (& Duncan) [1] .. http://haskell.org/haskellwiki/Package_versioning_policy

On Mon, 2008-01-21 at 23:26 +0100, Thomas Schilling wrote:
In order to make it easy for package package authors to describe correct and robust dependencies we (Duncan Coutts and I) propose the following syntactical extension to version range specifications in package files.
(1) Wildcards
~ 1.2.* ~~> >= 1.2 && < 1.3
in general
~ x.y.* ~~> >= x.y && < x.(y+1)
Another data point in support of this is that other package systems use variations on this idea: Ruby's "gems" package system[1] has a "pessimistic" dependency relation: foo ~> 1.2 which means foo >= 1.2 && < 1.3 This is to make it convenient for packages to follow the gems package version policy[2] which is in the same spirit as our own[3]. [1] http://hackage.haskell.org/trac/hackage/wiki/RubyGems [2] http://rubygems.org/read/chapter/7 [3] http://haskell.org/haskellwiki/Package_versioning_policy Gentoo has a couple specialised version range constructs. These are used because the situations they describe are so common. One is a form of wildcard: ~dev-haskell/foo-1.0 which means =dev-haskell/foo-1.0 || =dev-haskell/foo-1.0-rN (for any N) (The -rN version component denotes the revision of the ebuild itself rather than the version of the upstream package.) The other is also a wildcard =dev-lang/ghc-6.8* which (should) mean
=dev-lang/ghc-6.8 &&
Also, using "+" instead of "*" serves as better visual distinction.
It also provides a little bit of redundancy which makes for better error checking. For example, there if we used only one of the chars '*'/'+' for both forms of range we are proposing we would get: foo ~ 1.2* foo ~ 1.2.* and these two mean rather different things but are rather close visually. They would mean of course: foo ~ 1.2* = foo >= 1.2 && < 2 foo ~ 1.2.* = foo >= 1.2 && < 1.3 where as if you have to say: foo ~ 1.2+ foo ~ 1.2.* then there is less chance of a mistake. The character has to agree with the position it is in, so we can catch some mistakes. If we are serious about the package version policy - and I think we should be - then we should make it easy to follow. Adding specialised dependency forms should help. So we'd be suggesting to everyone that instead of using: build-depends: foo >=1.2 they should use: build-depends: foo ~1.2.* We should also allow packages to declare that they intend to follow the PVP and should develop a tool to check conformance. Cabal could even suggest or automatically fill in dependencies for developers much of the time. If it builds your project using the currently installed packages, it could work out which ones were used. For example if it found the package was using foo-1.2.1 and that foo follows the PVP then it could add or suggest build-depends: foo ~1.2.1+ Duncan
participants (2)
-
Duncan Coutts
-
Thomas Schilling