Skip to content

Instantly share code, notes, and snippets.

@shajra
Created January 1, 2020 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shajra/ae0e81539e891060ced0a5681f626acf to your computer and use it in GitHub Desktop.
Save shajra/ae0e81539e891060ced0a5681f626acf to your computer and use it in GitHub Desktop.
Is there a better way to override a library in Haskell.nix?
let
src = import ./sources.nix;
hnSrc = src."haskell.nix";
pinnedNixpkgsSrc = "${hnSrc}/nixpkgs";
hnArgsOrig = import hnSrc;
hnArgs = hnArgsOrig // {
nixpkgs-pin = "release-19.03";
# DESIGN: exposing an alternative "cabal-doctest" library in Nixpkgs.
#
overlays = hnArgsOrig.overlays ++ [(self: super: {
cabal-doctest = cabal-doctest-alt;
})];
};
pkgs = import pinnedNixpkgsSrc hnArgs;
hn = (import pinnedNixpkgsSrc hnArgs).haskell-nix;
# DESIGN: my alternative cabal-doctest Haskell library
#
cabal-doctest-alt = (hn.cabalProject {
name = "cabal-doctest-alt";
src = src.cabal-doctest;
}).cabal-doctest.components.library;
plan = hn.importAndFilterProject
(hn.callCabalProjectToNix {
name = "exceptions-checked";
src = ../.;
index-state = "2019-12-26T01:32:20Z";
index-sha256 = "1b9956ypjb65sigpwqiy6ylbk15mngg61h5a6q3panwalycnsbsg";
});
# DESIGN: I'm removing the reference to "cabal-doctest" from the plan, and
# it then finds it in the Nixpkgs overlay above.
#
modifiedPlan = plan.pkgs // {
pkgs = hackage: {
packages = builtins.removeAttrs (plan.pkgs.pkgs hackage).packages ["cabal-doctest"];
compiler = (plan.pkgs.pkgs hackage).compiler;
};
};
pkgSet = hn.mkCabalProjectPkgSet {
plan-pkgs = modifiedPlan;
modules = [({config, ...}: {
reinstallableLibGhc = true;
packages.exceptions-checked.components.tests.doctests = {
extraSrcFiles = [ "test" ];
preCheck = ''
ghc-pkg init dist/package.conf.inplace
'';
preConfigure = ''
substituteInPlace test/doctests.hs \
--replace "B.flags" "B.flags_exe_doctests" \
--replace "B.pkgs" "B.pkgs_exe_doctests" \
--replace "B.module_sources" "B.module_sources_exe_doctests"
'';
};
})];
};
in { inherit hn pkgs pkgSet plan; }
@shajra
Copy link
Author

shajra commented Jan 1, 2020

This is not terribly different from most Haskell.nix example usages. The main thing I'm trying to do is override a dependency with custom one I'm maintaining outside of Hackage (for a moment).

In Cabal, I'd do this with the following stanza:

source-repository-package
    type: git
    location: https://github.com/shajra/cabal-doctest.git
    tag: 94cf2a01ffd734ab89a041f1ba5073d2d3640d9a 

That's pretty convenient. But I don't think plan-to-nix knows what to do with this stanza. So I got the code above to work, but it feels like an uncomfortable hack. I feel there should a better way with Haskell.nix.

I'm modifying the auto-generated plan to not include cabal-doctest, and then when it's not found, I slip in the alternative library as a Haskell overlay. There's "DESIGN:" comments above in the critical places I do this.

I really appreciate a recommendation on a better way to go. I'd expect that for something as useful as overriding a dependency that there's a better way to do it in Haskell.nix.

@ilyakooo0
Copy link

I made a thing that solves the problem: https://github.com/ilyakooo0/haskell-nix-extra-hackage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment