Is there a recommended way to update version bounds on cabal packages? - haskell

With the release of GHC 7.10 and the accompanying version bump on the base package I found myself in the situation that I needed to fix my library dependencies.
For the moment I have run cabal install --allow-newer which found a set of working versions and installed fine.
Now I am in the process of manually searching through the installed libraries and updating the cabal files version bounds by hand.
Is there an easier/automatic way to do this?

I regularly use packdeps to check on my dependencies and bump any that are too restrictive. As well as the website, there's a hackage package so you can run it locally.
Once I bump a dependency, e.g. by bumping foo < 1.5 to foo < 1.6, I build and test locally using the --constraint 'foo>=1.5' argument to cabal, to check that the new version does indeed work.

You might like the tool cabal-bounds.

Related

Reinstalling the same version of a package with cabal new-install

I am working on a Haskell package. I have not yet uploaded it to Hackage and the version number is 0.1.0.0. I am using new style Cabal commands.
In order to test the package while I'm working on it (to make the library available to the test project), I run cabal new-install --lib after building the package.
However, I noticed that bug fixes were not having any effect and my test project (which is not itself a Cabal project and consists of a single Haskell file) continues to behave the same way even when I build and install the library.
So, I've tried modifying the cabal new-install --lib command with various combinations of flags like --force, --force-reinstalls and --reinstall. This did not have any effect.
Neither did deleting all generated files in both the library and the test project and re-building the library before recompiling the test project.
One possible solution might be to increase the version number. However, since the package is not released yet, I do not want to start using up version numbers before I upload it to Hackage. Even after I release it, I would like to change the version number only when I actually upload the new version to Hackage, not every time I test out a minor change on my own PC.
The old Cabal commands behave just fine. However, is there any way to get new-install to reinstall the package whenever I fix a bug without changing the version number?
I found a bug report from 2012 that might be relevant but I must admit that I do not understand it very well since I'm completely new to Cabal. https://github.com/haskell/cabal/issues/294

Stackage inclusive or exclusive usage

I'm attempting to start a new project using the Snap web framework. I used snap init to get my basic skeleton working. I also put http://www.stackage.org/lts/cabal.config next to my .cabal file. I didn't uncomment the line to use Stackage exclusively. So I tried to build and it failed and couldn't find the version of lens required by my .cabal file. The cabal.config file from Stackage specifies a version of lens that is not the same as the one in my .cabal file. So I deleted every constraint from my package list and did the usual cabal install --only-dep -j8 --enable-test and it worked!
However, I have always been told that package versions should be constrained. So when working with Stackage is it okay to leave package versions unconstrained? Should I downgrade my packages to the ones available in Stackage instead?
As far as I understand a cabal.config file specifies a set of dependencies with the specific versions that satisfy dependencies, so how does Stackage work? Is it just a subset of packages from Hackage that are proven to be compatible? Do they host their own packages or rely on Hackage for downloads?
Thanks in advance :)
Both options are available. The default option is what you did, and still goes to hackage to get the packages. You just added a filter to your cabal that prevents you from using any version of a package included in Stackage that was not tested to work together with all of the other packages.
The other option is to simply point your cabal repo to a Stackage url, and then you will download packages directly from the Stackage server. That server will only serve packages that are known to work together, so there is no need for additional constraints in your cabal file. I actually prefer this way of working.
In both cases, if you have additional constraints in your cabal file that are incompatible with the Stackage restrictions, your build will fail. If you use the first option, you will get dependency conflicts. When using the second option, the Stackage server will simply report that it does not have that specific package/version.

What to do if libraries require a different version of `base`?

I'm trying to install packages which require a different version of base than the one I have installed (I have 4.6.0.0, they require < 4.6). How can I install these on my system?
Edit: These packages actually require older packages in order to build, not just as a .cabal constraint.
Since you can't reinstall base, the only way to get these packages installed before they are updated is to grab the source,
cabal unpack foo
and then edit foo.cabal, changing the upper bound for base there, bump the package version (append a .1) so that when installing other packages cabal doesn't think it is broken, since the .cabal file it knows (from the package index) says it requires a different version of base, and
cabal install
from the directory you unpacked to.
Since there were a few significant changes in base-4.6; the Eq and Show superclasses have been removed from Num, and Bits no longer has Num as a superclass, it may be necessary to fix the code by adding Eq, Show or Num to the constraints of some functions to make the packages compile.
That's inconvenient, but the price for being up-to-date yourself with the newest GHC version for a few weeks.
If you just want one of your programs to depend on these packages, you can use cabal-dev as a drop-in replacement for cabal. The former installs local copies of packages in a cabal-dev path in the current directory. To install it, just run:
cabal install cabal-dev
For portability, you may add something like this to a makefile:
CABAL ?= cabal
build :
$(CABAL) build --builddir=$(BUILD_PATH)
Then in your Bash settings:
CABAL=cabal-dev
export CABAL
If a package isn't compatible with the base you currently have (i.e. just changing the constraint is insufficient), your only options are to port the package yourself or use an older ghc that provides the correct version of base.
You might want to check with the package maintainer first though. A development branch may already support what you need, and they just need a little prodding to release it.

How can I resolve zlib-enum, zlib-binding, zlib-conduit conflict when installing Yesod

I am trying to install my Yesod web app on another machine.
I have it installed fine on my current machine and can cabal install it on there without any problems.
I seem to run into trouble with it on the other machine though (which is a fresh Ubuntu VM - e.g., no cabal packages where installed on it prior.
Note that I changed nothing about my setup (e.g. cabal files are exactly the same).
This is the error I keep getting:
cabal: cannot configure zlib-enum-0.2.2. It requires zlib-bindings ==0.1.*
For the dependency on zlib-bindings ==0.1.* there are these packages:
zlib-bindings-0.1.0 and zlib-bindings-0.1.0.1. However none of them are available.
zlib-bindings-0.1.0 was excluded because zlib-conduit-0.2.0.1 requires zlib-bindings >=0.0.3 && <0.1
zlib-bindings-0.1.0 was excluded because zlib-bindings-0.0.3.2 was selected instead
zlib-bindings-0.1.0 was excluded because of the top level dependency zlib-bindings ==0.0.3.2
zlib-bindings-0.1.0.1 was excluded because zlib-conduit-0.2.0.1 requires zlib-bindings >=0.0.3 && <0.1
zlib-bindings-0.1.0.1 was excluded because zlib-bindings-0.0.3.2 was selected instead
zlib-bindings-0.1.0.1 was excluded because of the top level dependency zlib-bindings ==0.0.3.2
I have tried all kind of ways to resolve this, but keep running into this same problem, no matter what path I take.
My guess is, that theses packages' versions are conflicting at this point.
How can I resolve this until it gets fixed?
This is a prime example of cabal dependency hell. Theoretically, the fault lies with zlib-enum, since it should have had a major version bump to reflect the major version bump with zlib-bindings. But really, the problem is cabal's dependency analyzer. The new one will hopefully be ready soon.
In the meanwhile, depending on zlib-enum <= 0.2.1 should work.
Also, #ehird's answer should be helpful too, though it may not entirely solve the problem.
You might want to try installing the new Yesod Platform (Hackage page):
cabal install yesod-platform
It's a metapackage that depends on specific versions of Yesod and all its dependencies, designed to avoid versioning conflicts like this.
You could also try the in-development version of cabal-install, which has the modular dependency solver Michael mentioned. If you darcs get --lazy http://darcs.haskell.org/cabal/, you should be able to run bootstrap.sh in cabal/cabal-install to install it (but you should probably wipe ~/.cabal and ~/.ghc first).1 You still have to explicitly request the modular solver by passing --solver=modular to cabal, though.
Note that, even though it's a development version, it's actually pretty stable; lots of people on GHC 7.4.1 (including me) use it, since the version on Hackage doesn't compile. I haven't had any issues so far.
1 This is for Linux; I think the relevant directory is ~/Library/Haskell on OS X. I have no idea what to do on Windows, especially since the shell script won't run there.

Haskell: Testing a package against multiple versions of base for Hackage

I'm trying to upload my first package to Hackage (yay!), and I got this error:
The dependency 'build-depends: base' does not specify an upper bound on the version number. Each major release of the 'base' package changes the API in various ways and most packages will need some changes to compile with it. The recommended practise is to specify an upper bound on the version of the 'base' package. This ensures your package will continue to build when a new major version of the 'base' package is released. If you are not sure what upper bound to use then use the next major version. For example if you have tested your package with 'base' version 2 and 3 then use 'build-depends: base >= 2 && < 4'.
Which seems like a perfectly acceptable reason to decline my package.
Is there a good tool to test my package against various versions of base so I can see what the bounds are (rather than just guessing)? The best I can think of is to use some shell scripting to do something like:
% for v in $BASE_VERSIONS
do
cabal install base-$v &&\
cabal configure --enable-tests &&\
cabal build &&\
cabal test && echo "$v ok" || echo "$v fail"
done
But I feel like there should be something better.
This is a very bad idea! You must not upgrade base or any other packages that come with GHC (the ones with - in the tag column), or everything will break horribly.
The only way to test with an older version of base is to install an older GHC and test with that. I would suggest just trying it on 7.0.4 and 7.2.2; supporting older versions is probably a waste of time these days.
Failing that, just specify base >= VERSION && < 5, where VERSION is the version your GHC has. Or base == 4.* and hope for the best :)
In all seriousness, base's API doesn't really change all that much, so you're unlikely to run into many problems with this.
For testing your program with various versions of packages in general without disturbing your main ~/.cabal repository, I strongly recommend cabal-dev; something like
$ cabal-dev install 'pkg==VERSION'
$ cabal-dev install
$ cabal-dev test
should do it.
By the way, you can do cabal check to get warned about problems like this before uploading your package to Hackage.

Resources