mirror of
https://github.com/ilyakooo0/haskell.nix.git
synced 2024-09-11 06:55:40 +03:00
[ifd] cabalProjectToNix (#122)
This commit is contained in:
parent
66bf69ec9e
commit
52280f2324
19
default.nix
19
default.nix
@ -38,6 +38,11 @@ let
|
||||
# overridden with NIX_PATH.
|
||||
fetchExternal = import ./lib/fetch-external.nix;
|
||||
|
||||
mkHackageIndex = indexState: import ./lib/hackageIndex.nix {
|
||||
inherit (pkgs) runCommand cabal-install;
|
||||
inherit indexState;
|
||||
};
|
||||
|
||||
# All packages from Hackage as Nix expressions
|
||||
hackage = import (fetchExternal {
|
||||
name = "hackage-exprs-source";
|
||||
@ -123,6 +128,20 @@ let
|
||||
update-stackage = self.callPackage ./scripts/update-stackage.nix {};
|
||||
update-pins = self.callPackage ./scripts/update-pins.nix {};
|
||||
};
|
||||
|
||||
# Make this handy overridable fetch function available.
|
||||
inherit fetchExternal;
|
||||
|
||||
# Takes a haskell src directory runs cabal new-configure and plan-to-nix.
|
||||
# Resulting nix files are added to nix-plan subdirectory.
|
||||
callCabalProjectToNix = import ./lib/cabalProjectToNix.nix {
|
||||
inherit mkHackageIndex;
|
||||
inherit pkgs;
|
||||
inherit (pkgs) runCommand cabal-install ghc;
|
||||
inherit (pkgs.haskellPackages) hpack;
|
||||
inherit (self) nix-tools;
|
||||
inherit (pkgs) symlinkJoin;
|
||||
};
|
||||
});
|
||||
|
||||
in
|
||||
|
62
lib/cabalProjectToNix.nix
Normal file
62
lib/cabalProjectToNix.nix
Normal file
@ -0,0 +1,62 @@
|
||||
{ mkHackageIndex, pkgs, runCommand, nix-tools, cabal-install, ghc, hpack, symlinkJoin }:
|
||||
let defaultGhc = ghc;
|
||||
defaultCabalInstall = cabal-install;
|
||||
in { hackageIndexState, src, ghc ? defaultGhc, cabal-install ? defaultCabalInstall }:
|
||||
let
|
||||
cabalFiles =
|
||||
pkgs.lib.cleanSourceWith {
|
||||
inherit src;
|
||||
filter = path: type:
|
||||
type == "directory" ||
|
||||
pkgs.lib.any (i: (pkgs.lib.hasSuffix i path)) [ ".project" ".cabal" "package.yaml" ];
|
||||
};
|
||||
plan = if (builtins.compareVersions cabal-install.version "2.4.0.0") < 0
|
||||
# cabal-install versions before 2.4 will generate insufficient plan information.
|
||||
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"
|
||||
else runCommand "plan" {
|
||||
nativeBuildInputs = [ nix-tools ghc hpack cabal-install pkgs.rsync ];
|
||||
} ''
|
||||
tmp=$(mktemp -d)
|
||||
cd $tmp
|
||||
cp -r ${cabalFiles}/* .
|
||||
chmod +w -R .
|
||||
# warning: this may not generate the proper cabal file.
|
||||
# hpack allows globbing, and turns that into module lists
|
||||
# without the source available (we cleaneSourceWith'd it),
|
||||
# this may not produce the right result.
|
||||
find . -name package.yaml -exec hpack "{}" \;
|
||||
HOME=${mkHackageIndex hackageIndexState} cabal new-configure
|
||||
|
||||
export LANG=C.utf8 # Needed or stack-to-nix will die on unicode inputs
|
||||
mkdir -p $out
|
||||
|
||||
# ensure we have all our .cabal files (also those generated from package.yaml) files.
|
||||
# otherwise we'd need to be careful about putting the `cabal-generator = hpack` into
|
||||
# the nix expression. As we already called `hpack` on all `package.yaml` files we can
|
||||
# skip that step and just package the .cabal files up as well.
|
||||
#
|
||||
# This is also important as `plan-to-nix` will look for the .cabal files when generating
|
||||
# the relevant `pkgs.nix` file with the local .cabal expressions.
|
||||
rsync -a --prune-empty-dirs \
|
||||
--include '*/' --include '*.cabal' --include 'package.yaml' \
|
||||
--exclude '*' \
|
||||
$tmp/ $out/
|
||||
|
||||
# make sure the path's in the plan.json are relative to $out instead of $tmp
|
||||
# this is necessary so that plan-to-nix relative path logic can work.
|
||||
substituteInPlace $tmp/dist-newstyle/cache/plan.json --replace "$tmp" "$out"
|
||||
|
||||
# run `plan-to-nix` in $out. This should produce files right there with the
|
||||
# proper relative paths.
|
||||
(cd $out && plan-to-nix --plan-json $tmp/dist-newstyle/cache/plan.json -o .)
|
||||
|
||||
# move pkgs.nix to default.nix ensure we can just nix `import` the result.
|
||||
mv $out/pkgs.nix $out/default.nix
|
||||
'';
|
||||
in
|
||||
runCommand "plan-and-src" { nativeBuildInputs = [ pkgs.xorg.lndir pkgs.rsync ]; } ''
|
||||
mkdir $out
|
||||
# todo: should we clean `src` to drop any .git, .nix, ... other irelevant files?
|
||||
lndir -silent "${src}" "$out"
|
||||
rsync -a ${plan}/ $out/
|
||||
''
|
16
lib/hackageIndex.nix
Normal file
16
lib/hackageIndex.nix
Normal file
@ -0,0 +1,16 @@
|
||||
{ runCommand, cabal-install
|
||||
, indexState ? "2019-04-24T21:34:04Z"
|
||||
} :
|
||||
let
|
||||
# To avoid downloading more data than necessary this will provide a base.
|
||||
cachedState = runCommand "hackage-${builtins.substring 0 4 indexState}" {} ''
|
||||
mkdir -p $out
|
||||
HOME=$out ${cabal-install}/bin/cabal update --index-state='${builtins.substring 0 4 indexState}-01-01T00:00:00Z'
|
||||
'';
|
||||
in runCommand "hackage-${builtins.replaceStrings [":"] [""] indexState}" {} ''
|
||||
mkdir -p $out
|
||||
cp -r ${cachedState}/.cabal $out
|
||||
chmod +w -R $out/.cabal
|
||||
sed -i.back -e "s|${cachedState}|$out|g" $out/.cabal/config
|
||||
HOME=$out ${cabal-install}/bin/cabal update --index-state='${indexState}'
|
||||
''
|
33
test/call-cabal-project-to-nix/default.nix
Normal file
33
test/call-cabal-project-to-nix/default.nix
Normal file
@ -0,0 +1,33 @@
|
||||
{ stdenv, mkCabalProjectPkgSet, callCabalProjectToNix }:
|
||||
|
||||
with stdenv.lib;
|
||||
|
||||
let
|
||||
pkgSet = mkCabalProjectPkgSet {
|
||||
plan-pkgs = import (callCabalProjectToNix {
|
||||
hackageIndexState = "2019-04-24T21:34:04Z";
|
||||
# reuse the cabal-simple test project
|
||||
src = ../cabal-simple;
|
||||
});
|
||||
};
|
||||
packages = pkgSet.config.hsPkgs;
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
name = "callStackToNix-test";
|
||||
|
||||
buildCommand = ''
|
||||
exe="${packages.cabal-simple.components.exes.cabal-simple}/bin/cabal-simple"
|
||||
|
||||
printf "checking whether executable runs... " >& 2
|
||||
$exe
|
||||
|
||||
touch $out
|
||||
'';
|
||||
|
||||
meta.platforms = platforms.all;
|
||||
|
||||
passthru = {
|
||||
# Attributes used for debugging with nix repl
|
||||
inherit pkgSet packages;
|
||||
};
|
||||
}
|
@ -16,6 +16,7 @@ in {
|
||||
builder-haddock = haskell.callPackage ./builder-haddock {};
|
||||
stack-simple = haskell.callPackage ./stack-simple {};
|
||||
callStackToNix = haskell.callPackage ./callStackToNix {};
|
||||
callCabalProjectToNix = haskell.callPackage ./call-cabal-project-to-nix {};
|
||||
|
||||
# Run unit tests with: nix-instantiate --eval --strict -A unit
|
||||
# An empty list means success.
|
||||
|
Loading…
Reference in New Issue
Block a user