PROPOSAL: Extended syntax for package version range specifications

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Mon Jan 21 19:45:31 EST 2008


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 && <dev-lang/ghc-6.9
(it is a well acknowledged mistake that it is actually interpreted as a
string so would also match dev-lang/ghc-6.80)

> 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



More information about the cabal-devel mailing list