haskell-nix icon indicating copy to clipboard operation
haskell-nix copied to clipboard

Recommend using callHackage

Open domenkozar opened this issue 8 years ago • 21 comments

Reasons:

  • no need to keep cabal and generated expressions in sync
  • https://github.com/NixOS/cabal2nix/issues/217

domenkozar avatar Jan 03 '17 16:01 domenkozar

So this is something I'm not yet sure about endorsing, but I might still mention it in the tutorial so that people are aware and can make an informed choice

The issues I have with this are:

  • It leads to non-determinism in the build (since the package name and version do not suffice to fully determine the package, due to hackage permitting post-upload revisions)
  • The build has to do work every time you run the build to compute the derivation
  • "Import from derivation" still has some issues that need to be worked out, such as:
    • https://github.com/NixOS/nix/issues/1148
    • dry-runs doing work and failing (which is a very bad user experience)
    • poor Hydra integration (now the Hydra evaluator needs to perform builds)

I actually prefer the two-phase cabal2nix + nix-build distinction because this forces the user to explicitly opt in to potentially non-deterministic changes at controlled checkpoints (i.e. whenever they run cabal2nix) and then they can trust in determinism for all other points in time

Gabriella439 avatar Jan 03 '17 17:01 Gabriella439

There's an alternative to using callHackage.

I use a bit of code like this https://github.com/expipiplus1/dotfiles/blob/master/nix-haskell-skeleton/default.nix to generate default.nix during evaluation time from the .cabal file.

It still has some of the same drawbacks though, hydra has to build cabal2nix before finishing evaluation (although this is cached, so not a big deal in practice) for example.

expipiplus1 avatar Jan 19 '17 12:01 expipiplus1

So actually I did more digging into callHackage and it now has safeguards to ensure determinism so I would prefer to use it if possible. However, the next issue I ran into was that it just hung when I tried to use it and I haven't had a chance to investigate why yet

Gabriella439 avatar Jan 20 '17 16:01 Gabriella439

I would be interested in a example of usage for ´callHackage` or a link to some help that is not nix source code ;-)

PierreR avatar Jan 31 '17 17:01 PierreR

@PierreR Considering callHackage is a nix function I'm not sure how to help without writing nix code. But here's a simple example.

Assume you have a Haskell nix package that needs turtle but the one in nixpkgs is too old. You could do something like this. (Note that for simplicity this does not use the full-blown override mechanism, although that's probably what you'd want to do IRL.)

let
  haskellPackages = (import <nixpkgs> {}).haskellPackages;
  upgradedTurtle = haskellPackages.callHackage "turtle" "1.3.1" {};
in
haskellPackages.callPackage ./my-own-haskell-package.nix {
  turtle = upgradedTurtle;
}

3noch avatar Jan 31 '17 19:01 3noch

@Gabriel439 @expipiplus1 I'm working on getting that into Nixpkgs itself: https://github.com/NixOS/nixpkgs/pull/22191

3noch avatar Jan 31 '17 19:01 3noch

@3noch Thanks (I just meant I would rather understand using the function from an example than from the code source of that function).

I am probably doing something obviously wrong but with this file I have got this error:

building path(s) ‘/nix/store/40w6k81a0yb9db64sv2wv63imra3cw2h-cabal2nix-language-puppet-1.3.5’
installing
sed: can't read /nix/store/aqg3rjr6qbabmb0nh9ph6k9ig6hfivxv-all-cabal-hashes-ee101d34ff8bd59897aa2eb0a124bcd3fb47ceec-src/language-puppet/1.3.5/language-puppet.json: No such file or directory

Any idea ?

PierreR avatar Jan 31 '17 20:01 PierreR

@PierreR I'd wonder what your version of nixpkgs is. Probably should take this to #nixos on IRC.

3noch avatar Jan 31 '17 21:01 3noch

It is pinned with: export NIX_PATH=nixpkgs==https://github.com/NixOS/nixpkgs-channels/archive/9d0a9bc9d61f6e94d720486ddbe972af8547382d.tar.gz

It is from 2016-12-30T23:42:10+01:00. I will try with a more recent ref.

PierreR avatar Jan 31 '17 21:01 PierreR

@PierreR Yah I'd try that first. callHackage is new and when it was first introduced it had some issues (as @Gabriel439 pointed out). I had a discussion with the author and he ended up changing it.

3noch avatar Jan 31 '17 21:01 3noch

As I said on #nixos I did try with another more recent version (2017-01-24) with no luck. But I am wondering, maybe I need to wait for the next automatic Haskell package set update ? The version I want to fetch is fresh from today.

PierreR avatar Jan 31 '17 21:01 PierreR

Yes that's the problem. You'll need to use the trick I'm adding in https://github.com/NixOS/nixpkgs/pull/22191 and get the source directly from GitHub or whathaveyou.

3noch avatar Jan 31 '17 21:01 3noch

@3noch OK.Thanks for your help !

PierreR avatar Jan 31 '17 21:01 PierreR

@Gabriel439 The latest nixpkgs-unstable has haskellPackages.callCabal2nix. With it you can do things like:

turtle = haskellPackages.callCabal2nix "turtle" (fetchFromGitHub {
  owner  = "Gabriel439";
  repo   = "Haskell-Turtle-Library";
  rev    = "f22ad5c35f910b11b833bbbbb08df212d5fde06c";
  sha256 = "...";
}) {};

3noch avatar Feb 02 '17 19:02 3noch

tried using callHackage in the referenced nix-build (postgrest) and it failed, worked with just command line cabal2nix

building path(s) ‘/nix/store/g7gzdj7bwjc0yg4jdg0fxw8gmfz0ckbz-cabal2nix-hasql-transaction-.5’
installing
sed: can't read /nix/store/aqg3rjr6qbabmb0nh9ph6k9ig6hfivxv-all-cabal-hashes-ee101d34ff8bd59897aa2eb0a124bcd3fb47ceec-src/hasql-transaction/.5/hasql-transaction.json: No such file or directory
curl: (3) <url> malformed
error: could not download /nix/store/aqg3rjr6qbabmb0nh9ph6k9ig6hfivxv-all-cabal-hashes-ee101d34ff8bd59897aa2eb0a124bcd3fb47ceec-src/hasql-transaction/.5/hasql-transaction.cabal
cabal2nix: nix-prefetch-url: createProcess: runInteractiveProcess: exec: does not exist (No such file or directory)
builder for ‘/nix/store/ccdz5xnnr4p8dd427wr3sydy7y03qr61-cabal2nix-hasql-transaction-.5.drv’ failed with exit code 1
error: build of ‘/nix/store/ccdz5xnnr4p8dd427wr3sydy7y03qr61-cabal2nix-hasql-transaction-.5.drv’ failed

NotBrianZach avatar Feb 11 '17 05:02 NotBrianZach

@NotBrianZach callHackage relies on all-cabal-hashes which is frozen with a nixpkgs release. Most likely the package you want isn't available in that snapshot. You have two options: Override all-cabal-hashes in your package set to a newer clone of all-cabal-hashes or use something like haskellPackages.callCabal2nix "a-package" (pkgs.fetchFromGitHub {...}) {}.

You also have a third option which may or may not work: Use a newer nixpkgs.

3noch avatar Feb 11 '17 05:02 3noch

@3noch It is not quite clear what the first argument of callCabal2nix is for ?

turtle = hlib.dontCheck(hlib.dontHaddock(hghc.callCabal2nix "turtle" (pkgs.fetchFromGitHub {
...
  }) {};
henv = hghc.ghcWithPackages (p: with p; [turtle]);

What is the purpose of "turtle" ?

I am also asking because I have experienced some weird caching issue where nix is rebuilding the haskell package but ultimately somehow it is still used the old one in ghcWithPackages

pradermecker avatar Mar 01 '17 12:03 pradermecker

@pradermecker It's used to give a better name to the store path.

If you updated links somewhere but did not update the SHA-256 hash, then that might be your problem.

3noch avatar Mar 01 '17 15:03 3noch

@3noch Thanks for the info !

pradermecker avatar Mar 01 '17 16:03 pradermecker

@3noch I don't see why this code fails with:

error: string ‘/nix/store/3ibw2qzxknyjd30zlw0l5yikwla6yivr-language-puppet-22d8fb4ee0ad833ca2f0790e3c473e7e49424232-src’ cannot refer to other paths, at /nix/store/9wx96zrrr6ixgns3k64isk0vdzc4yci8-nixpkgs-fff8cc79df5aa26e935f8ee30c06ef79368ad5dc-src/pkgs/development/haskell-modules/default.nix:92:25

The error points to https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/default.nix#L92

I am using this nixpkgs pointer:

{
  "url": "https://github.com/NixOS/nixpkgs.git",
  "rev": "fff8cc79df5aa26e935f8ee30c06ef79368ad5dc",
  "date": "2017-03-20T19:03:20+01:00",
  "sha256": "0jlnx75zri3gblzxb0jibllqclki0ykwn8d9zsp5p8yzyvn70j44",
  "fetchSubmodules": true
}

Any idea ? Thanks ;-)

PierreR avatar Mar 23 '17 16:03 PierreR

@PierreR Feel free to hop on #haskell or #nixos IRC. I'm eacameron.

3noch avatar Mar 23 '17 16:03 3noch