Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cabal build resolution picks very old packages #7

Closed
tel opened this issue Dec 5, 2013 · 9 comments
Closed

Cabal build resolution picks very old packages #7

tel opened this issue Dec 5, 2013 · 9 comments

Comments

@tel
Copy link

tel commented Dec 5, 2013

In trying to build a bare-bones Happstack example using this buildpack I ran into an issue where during dependency installation Cabal would pick outrageously old packages. This is legal as I wasn't specifying any versions explicitly in my .cabal file, but it's divergent behavior from my local cabal install --only-dependencies.

The behavior is all captured in some commits at tel/happstack-heroku-test. In particular, my initial .cabal file was

https://github.com/tel/happstack-heroku-test/blob/a17d56baf4a03b9fd5b7ee8f21e582dc23ec667e/hktest.cabal

  build-depends:       base >=4.6 && <4.7
                     , blaze-html
                     , bytestring
                     , cmdargs
                     , happstack-server
                     , text

and the build failed due to trying to install happstack-server-0.5.0.5 which depends on an old version of HaXml that failed to build. I then added an explicit happstack-server constraint

https://github.com/tel/happstack-heroku-test/blob/01ce7ebf07f0b2acf34b2e5dd56c0801c55365e5/hktest.cabal

  build-depends:       base                >= 4.6 && <4.7
                     , blaze-html
                     , bytestring
                     , cmdargs
                     , happstack-server    >= 7.3
                     , text

which caused a modern happstack to be build (avoiding the HaXml dep) but failed due to an older mtl-2.0.1.0. I then constrained mtl as well

https://github.com/tel/happstack-heroku-test/blob/e26170a526d446ebba91b7c2305a90601eb5ea59/hktest.cabal

  build-depends:       base                >= 4.6    && <4.7
                     , blaze-html
                     , bytestring
                     , cmdargs
                     , happstack-server    >= 7.3
                     , text

                     -- I don't use this dependency in the code yet, 
                     -- but it must be specified in order to get the
                     -- buildpack to choose the modern mtl dependency.
                     , mtl                 >= 2.1.2

which built successfully.

@begriffs
Copy link
Owner

begriffs commented Dec 6, 2013

Thanks for the thorough bug report! It has helped me reproduce the problem.

It's a really weird bug and I haven't solved it yet. I did create another branch of the buildpack that helps for debugging because it preserves ~/.cabal in the slug so you can look at what packages are known.

What's confusing is that all the new stuff is in there, so I don't know why it tries to install the old stuff.

If you want to examine the output as well, create your app like this
heroku create --stack=cedar --buildpack https://github.com/begriffs/heroku-buildpack-ghc.git#updatecabal

@tel
Copy link
Author

tel commented Dec 6, 2013

It may be worth bringing someone from the Cabal team in here. I don't know that it's a bug that the dependencies were solved this way, but it's certainly strange behavior.

@samstokes
Copy link
Contributor

I saw this behaviour too, albeit with an older version of the buildpack before @begriffs cleaned it up. I was deploying a nontrivial Yesod app and had to add a lot of explicit version constraints before it would work. (Then I hit the 15 minute limit and gave up :))

Unfortunately this was a while ago so I don't have much of diagnostic use, but given the Heisenbuggy nature of this issue, I thought even a "me too" would help to understand just how edgy an edge case this is.

@benarmston
Copy link

A workaround to this problem, or perhaps even a compelling solution would be to freeze all of the dependencies for a project to the exact versions that have been selected locally.

As this build pack requires at least cabal-install 1.18, this can be done by providing a complete and exact set of dependencies in the cabal.config file. Which would ensure that all build use the same versions as your local build.

Determining the complete and exact set of dependencies manually would be at best tiresome and frustrating. However, I've just uploaded cabal-constraints to hackage which can be used to determine the exact dependencies your local build used and then populate the cabal.config with that information.

Details of how to use it can be found on its hackage page and on its Github repo page.

Hopefully, this will help resolve this issue for you. I'd love to hear any feedback from its use. And of course if you have any issues with it please open an issue on the cabal-constraints github repo.

@begriffs
Copy link
Owner

begriffs commented Dec 9, 2013

Thanks @benarmston this is ingenious!

I am having trouble using it, however. Here's what happens:

$ cabal-constraints dist/dist-sandbox-e94ad5c0/setup-config
You need to re-run the 'configure' command. The version of Cabal being used has changed (was Cabal-1.18.0, now Cabal-1.18.1.2).

$ cabal --version
cabal-install version 1.18.0.2
using version 1.18.0 of the Cabal library

@benarmston
Copy link

The version of Cabal used by cabal-constraints needs to match the
version being used by cabal-install. In your case cabal-constraints is
using a slightly later version. There are two solutions to this, reinstall
cabal-constraint to use Cabal 1.18.0 our reinstall cabal-install to use
Cabal 1.18.1.2.

For the first option, cabal install --constraint "Cabal == 1.18.0" cabal-constraints should do the trick. You may have to remove our un
register cabal-constraints first.
On Dec 9, 2013 6:07 AM, "Joe Nelson" notifications@github.com wrote:

Thanks @benarmston https://github.com/benarmston this is ingenious!

I am having trouble using it, however. Here's what happens:

$ cabal-constraints dist/dist-sandbox-e94ad5c0/setup-config
You need to re-run the 'configure' command. The version of Cabal being used has changed (was Cabal-1.18.0, now Cabal-1.18.1.2).
$ cabal --version
cabal-install version 1.18.0.2
using version 1.18.0 of the Cabal library


Reply to this email directly or view it on GitHubhttps://github.com//issues/7#issuecomment-30107499
.

@begriffs
Copy link
Owner

begriffs commented Dec 9, 2013

Problem solved!

I installed the newest cabal in my sandbox then put .cabal-sandbox/bin earlier in my path and cabal-constraints worked. I saved its results to cabal.config, committed that file, pushed to Heroku and the original problem repo built successfully on Heroku.

I'll add a section to the README to describe this process for other people. Is there a way to relax the exact cabal version matching? I feel like that might be a complicated thing to explain.

@benarmston
Copy link

Glad to hear your problems solved!

There may be a way to relax the exact Cabal version matching, but Cabal doesn't export an API to do so. I was previously using a different method, but that was brittle in other ways.

I had also been working on adding a freeze command to cabal-install, and have been trying to find the time to continue with that. When that is completed and released, hopefully in Cabal 1.20, cabal-constaints can be deprecated, and all of its limitations will be no more.

As such I'm rather reluctant to invest too much time in trying to fix the UX problems with cabal-constaints, and prefer to spend my time on providing the support for using it and completing the cabal freeze command.

Of course an updated README better explaining how to use the tool would be much appreciated. Perhaps a paragraph in the install section detailing 1) how to find the version of Cabal used by cabal-install and 2) how to add a suitable constraint on Cabal when installing cabal-constaints. Though if you think your method of using a per-project installation of Cabal is preferable, I'd accept a PR detailing that instead.

@begriffs
Copy link
Owner

begriffs commented Dec 9, 2013

Thanks @benarmston, you really saved the day. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants