Skip to content

Instantly share code, notes, and snippets.

@nmattia
Last active December 7, 2018 10:27
Show Gist options
  • Save nmattia/117f45a643f885f94420b1d2a8bd166b to your computer and use it in GitHub Desktop.
Save nmattia/117f45a643f885f94420b1d2a8bd166b to your computer and use it in GitHub Desktop.
Ugly nix incremental haskell build
# Store the nix-created `dist` in `localSrc/.nix-cache` after build (whether
# successful or not) and re-injects it for subsequent builds.
#
# `./mask` should contain a haskell project with an `out.nix` file. That file
# should describe a typical cabal derivation with the extra field:
#
# preUnpack = ''
# localSrc=${toString ./.}
# '';
#
# (this is a hack to pass `localSrc`)
# TODO:
# * Restore cache before cabal kicks in so that we don't have to delete files
# * Store .nix-cache is `/nix/cache/<hash>` instead and add support for
# sandbox
# * Try with non-haskell projects like Rust, make-based, etc
#
#
let
pkgs = (import <nixpkgs>) { overlays = [ overlayDirtyDist ]; };
overlayDirtyDist = self: super:
{
haskellPackages = super.haskellPackages.extend (haskellPackagesNew: haskellPackgesOld: rec {
foobar =
pkgs.haskell.lib.overrideCabal
( haskellPackagesNew.callPackage ./mask/out.nix { } )
( oldDerivation:
{
postUnpack = ''
# Restore timestamps from the original source
if [[ -n $localSrc ]]; then
pushd "$sourceRoot"
rm -rf .nix-cache dist
for f in $(find . -type f); do
touch -r "$localSrc/$f" "$f"
done
popd
fi
'';
preBuild = ''
save_cache() {
rm -rf "$localSrc/.nix-cache"
# TODO unpack cache before preBuild to make sure
# we don't overwrite cabal stuff
#
# these files are generated by cabal
# rm -rf ./dist/build ./dist/setup-config
cp -av ./dist/ "$localSrc/.nix-cache/"
}
# Load and save cache state
if [[ -n $localSrc ]]; then
trap "save_cache" EXIT
if [[ -d "$localSrc/.nix-cache" ]]; then
cp -av "$localSrc/.nix-cache"/* ./dist/
fi
fi
'';
}
);
}
);
};
in { foobar = pkgs.haskellPackages.foobar; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment