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

Patching package.yaml does not update dependencies #548

Closed
m4dc4p opened this issue Apr 27, 2022 · 6 comments
Closed

Patching package.yaml does not update dependencies #548

m4dc4p opened this issue Apr 27, 2022 · 6 comments

Comments

@m4dc4p
Copy link

m4dc4p commented Apr 27, 2022

I have a package that, in order to support GHC 9, needs a dependency on singletons-th. When I use appendPatch to patch package.yml, the resulting build fails because the dependency on singletons-th isn't seen.

This the patch file:

diff --git a/package.yaml b/package.yaml
index 657fcb8..c1829f1 100644
--- a/package.yaml
+++ b/package.yaml
@@ -43,6 +43,7 @@ dependencies:
   - uuid
   - conduit
   - singletons >= 2.5.1
+  - singletons-th
   - tagged
   - primitive

And I've added it to the list of patches using appendPatch (where xxx-gogol is sources for the package managed by niv):

appendPatch (hfinal.callCabal2nix "xxx-gogol" sources.xxx-gogol { }) [./xxx-gogol.patch]

Here's the output I get. Notice that generated xxx-gogol.cabal appears before patching:

building '/nix/store/jrsgcvl9bj86gvpsh1yb6gq0zvv7zxnc-xxx-gogol-0.0.1.drv'...
setupCompilerEnvironmentPhase
Build with /nix/store/z5diiqwzjzv1wyrdkmw5wwjxgy33m4hc-ghc-9.0.2.
unpacking sources
unpacking source archive /nix/store/94dgxjrkkxiydkxd5wycwfk85hnnqm5i-source
source root is source
patching sources
generated xxx-gogol.cabal
applying patch /nix/store/3wmxqys0g3bczw320dwx1d08zwkhskkl-xxx-gogol.patch

When I cat package.yaml (using overrideCabal to add commands to various phases), I see the dependency as expected. However, the xxx-gogol.cabal file does not contain the singletons-th dependency.

Am I just on an old version of cabal2nix with a bug, or is this new?

Thanks for any help!

@cdepillabout
Copy link
Member

My guess is that you are calling appendPatch and callCabal2nix in the wrong order.

For instance, calling cabal2nix cabal://lua-1.0.0 is going to give an output like this:

{ mkDerivation, base, bytestring, lib, tasty, tasty-hunit }:
mkDerivation {
  pname = "lua";
  version = "1.0.0";
  sha256 = "289d4ebb54e92d7c3955a56b1671872343d3f841c2b91abba26ad39ebc06c153";
  libraryHaskellDepends = [ base bytestring ];
  testHaskellDepends = [ base bytestring tasty tasty-hunit ];
  homepage = "https://hslua.github.io/";
  description = "Lua, an embeddable scripting language";
  license = lib.licenses.mit;
}

This cabal2nix call has already called hpack, and read the resulting lua.cabal file to turn it into the above Nix derivation. Your call to appendPatch happens after this, but it is already too late. The Nix derivation has already been produced.

I think your two choices here are either to patch sources.xxx-gogol before calling cabal2nix, or just add the singletons-th dependency after calling cabal2nix. In Nixpkgs, we generally take the second approach. Here's a random example:

https://github.com/NixOS/nixpkgs/blob/9d23b4c6c949947902d599a0fdc711f35f31310c/pkgs/development/haskell-modules/configuration-common.nix#L1771

@m4dc4p
Copy link
Author

m4dc4p commented Apr 27, 2022

Thanks for the help! How would I patch the sources before calling cabal2nix? I suppose I'd have to create a derivation with just the sources for xxx-gogol, patch those, then call cabal2nix over that? Sounds much cleaner than below but also harder!

Regardless, addBuildDepend pretty much did the trick. However, the cabal file still needed to get regenerated, and somehow libraryHaskellDepends didn't have singletons-th in it. But I was able to add the library by hand, and updated postPatch so it would run hpack again.

This is what I ended up with:

addBuildDepend singletons-th (overrideCabal (
      appendPatch (
        hfinal.callCabal2nix "xxx-gogol" sources.xxx-gogol { }
      ) [./xxx-gogol.patch]
    ) (drv: {
      libraryHaskellDepends = drv.libraryHaskellDepends ++ [ singletons-th ];
      postPatch = ''
        hpack
        '';
    }));

@m4dc4p m4dc4p closed this as completed Apr 27, 2022
@cdepillabout
Copy link
Member

Without a fully reproducible example, it is hard to help you, but I thought that all you'd need would be something like this:

addBuildDepend singletons-th (hfinal.callCabal2nix "xxx-gogol" sources.xxx-gogol { })

Although I'm not sure if you have some specific hpack-related problems to work around. You should probably be checking the xxx.gogol.cabal file into your repo as well if you're not already: https://www.fpcomplete.com/blog/storing-generated-cabal-files/.

@m4dc4p
Copy link
Author

m4dc4p commented Apr 27, 2022

Totally get it, and I appreciate your help. This is unfortunately in the middle of a large commercial project and I don't have the time/energy to cut that down to a manageable chunk.

For posterity, note that I essentially can't modify the source repository here (xxx-gogol), so checking in a cabal file isn't really an option. I have to make changes to the downloaded sources for GHC 9 compatability, thus the additional dependency I'm trying to add.

I was able to implement a solution that patches the sources first, then uses those patched sources as input to cabal2nix. It looks something like this:

  xxx-gogol-patch = stdenv.mkDerivation {
    patches = ./xxx-gogol.patch;
    src = sources.xxx-gogol;
    name = "xxx-gogol-patch";
    dontConfigure = true;
    dontBuild = true;
    dontInstall= true;
    postPatch = ''
      mkdir $out
      cp -R . $out
    '';
  };


  # Use the patched sources from above to generate nix expression for xxx-gogol,
  # rather than raw sources downloade by niv. If we instead applied the ./xxx-gogol.patch
  # file here (via `appendPatch` or any other mechanism), it won't have any effect, because
  # cabal2nix always runs before any patching is done, and the nix expression it generates does
  # not show the dependency on singletons-th.
  xxx-gogol = hfinal.callCabal2nix "xxx-gogol" "${xxx-gogol-patch.out}" { };

@m4dc4p m4dc4p reopened this Apr 27, 2022
@sternenseemann
Copy link
Member

How would I patch the sources before calling cabal2nix?

nixpkgs has a simpler function for this, called applyPatches.

I don't see how this is a cabal2nix issue really, it behaves correctly in this example in my opinion. Can you state what you would like to change?

@m4dc4p
Copy link
Author

m4dc4p commented Apr 28, 2022

Accidently re-opened - nothing needs to change. Thanks for the tip about applyPatches, I will look into that!

@m4dc4p m4dc4p closed this as completed Apr 28, 2022
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

3 participants