@@ -0,0 +1,62 @@
1+{ mkHackageIndex, pkgs, runCommand, nix-tools, cabal-install, ghc, hpack, symlinkJoin }:
2+let defaultGhc = ghc;
3+ defaultCabalInstall = cabal-install;
4+in { hackageIndexState, src, ghc ? defaultGhc, cabal-install ? defaultCabalInstall }:
5+let
6+ cabalFiles =
7+ pkgs.lib.cleanSourceWith {
8+ inherit src;
9+ filter = path: type:
10+ type == "directory" ||
11+ pkgs.lib.any (i: (pkgs.lib.hasSuffix i path)) [ ".project" ".cabal" "package.yaml" ];
12+ };
13+ plan = if (builtins.compareVersions cabal-install.version "2.4.0.0") < 0
14+ # cabal-install versions before 2.4 will generate insufficient plan information.
15+ then throw "cabal-install (current version: ${cabal-install.version}) needs to be at least 2.4 for plan-to-nix to work without cabal-to-nix"
16+ else runCommand "plan" {
17+ nativeBuildInputs = [ nix-tools ghc hpack cabal-install pkgs.rsync ];
18+ } ''
19+ tmp=$(mktemp -d)
20+ cd $tmp
21+ cp -r ${cabalFiles}/* .
22+ chmod +w -R .
23+ # warning: this may not generate the proper cabal file.
24+ # hpack allows globbing, and turns that into module lists
25+ # without the source available (we cleaneSourceWith'd it),
26+ # this may not produce the right result.
27+ find . -name package.yaml -exec hpack "{}" \;
28+ HOME=${mkHackageIndex hackageIndexState} cabal new-configure
29+
30+ export LANG=C.utf8 # Needed or stack-to-nix will die on unicode inputs
31+ mkdir -p $out
32+
33+ # ensure we have all our .cabal files (also those generated from package.yaml) files.
34+ # otherwise we'd need to be careful about putting the `cabal-generator = hpack` into
35+ # the nix expression. As we already called `hpack` on all `package.yaml` files we can
36+ # skip that step and just package the .cabal files up as well.
37+ #
38+ # This is also important as `plan-to-nix` will look for the .cabal files when generating
39+ # the relevant `pkgs.nix` file with the local .cabal expressions.
40+ rsync -a --prune-empty-dirs \
41+ --include '*/' --include '*.cabal' --include 'package.yaml' \
42+ --exclude '*' \
43+ $tmp/ $out/
44+
45+ # make sure the path's in the plan.json are relative to $out instead of $tmp
46+ # this is necessary so that plan-to-nix relative path logic can work.
47+ substituteInPlace $tmp/dist-newstyle/cache/plan.json --replace "$tmp" "$out"
48+
49+ # run `plan-to-nix` in $out. This should produce files right there with the
50+ # proper relative paths.
51+ (cd $out && plan-to-nix --plan-json $tmp/dist-newstyle/cache/plan.json -o .)
52+
53+ # move pkgs.nix to default.nix ensure we can just nix `import` the result.
54+ mv $out/pkgs.nix $out/default.nix
55+ '';
56+in
57+ runCommand "plan-and-src" { nativeBuildInputs = [ pkgs.xorg.lndir pkgs.rsync ]; } ''
58+ mkdir $out
59+ # todo: should we clean `src` to drop any .git, .nix, ... other irelevant files?
60+ lndir -silent "${src}" "$out"
61+ rsync -a ${plan}/ $out/
62+ ''