Add nix expressions

pull/8/head
Lennart Spitzner 2020-06-08 15:49:25 +02:00
parent 9d0fb2a268
commit f2f3688149
12 changed files with 535 additions and 0 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
/*.pdf
dist/
dist-newstyle/
ci-out/
.cabal-sandbox/
.stack-work/
cabal.sandbox.config

1
default.nix Normal file
View File

@ -0,0 +1 @@
(import ./nix/all.nix {}).default.multistate

2
nix/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
nixpkgs.nix
local-extra-deps.nix

32
nix/README.md Normal file
View File

@ -0,0 +1,32 @@
This nix setup expects the iohk haskell-nix overlay to be available/included
when importing `<nixpkgs>`. Also, you might need a specific commit if you
want to test against all supported ghcs (8.4 - 8.10, currently).
# Useful commands:
~~~~.sh
# enter a shell for a specific build-plan
# (cabal-solved with ghc-8.4 in this case)
nix-shell nix/all.nix -A '"hackage-8.4".shell'
# run tests against ghcs 8.4 through 8.10, both against hackage and stackage package sets
nix/ci.sh
~~~~
# Files in this directory:
all.nix - main entrypoint into this package's nix world
via-hackage.nix - how to build this via cabal-solved package-set
via-stackage.nix - how to build via stackage-based package set
nixpkgs.nix - optional - if you want to use a custom nixpkgs channel
(the replacement needs to have haskell-nix overlay _and_
the cabal-check feature enabled though!)
local-extra-deps.nix - optional - for defining local addition deps for
dev testing
(plus some currently unused:)
materialized - materializations of cabal-solved build-plans
plan.nix - manual materialization of unsolved build-plan (used with
stackage snapshot to build package set)

99
nix/all.nix Normal file
View File

@ -0,0 +1,99 @@
let
importOrElse = maybePath: otherwise:
if builtins.pathExists maybePath then import maybePath else otherwise;
pkgs = importOrElse ./nixpkgs.nix
( let
haskellNix = import (
builtins.fetchTarball
https://github.com/lspitzner/haskell.nix/archive/4ad436d66d1a553d1a36d89fcab9329f10ae36e9.tar.gz
) { version = 2; };
nixpkgsSrc = haskellNix.sources.nixpkgs-1909;
in
import nixpkgsSrc haskellNix.nixpkgsArgs
);
gitignoreSrc = pkgs.fetchFromGitHub {
# owner = "hercules-ci";
owner = "lspitzner"; # TODO switch back to the above once PR is merged
# see https://github.com/hercules-ci/gitignore.nix/pull/44
repo = "gitignore.nix";
rev = "97d53665298d2b31b79e5fe4b60edb12a6661547";
sha256 = "sha256:1b3z2ikpg32zsfrhv4fb17dqavgg7d4wahslxlm37w68y7adsdav";
};
inherit (import gitignoreSrc { inherit (pkgs) lib; }) gitignoreSource gitignoreFilter;
cleanedSource = pkgs.lib.cleanSourceWith {
name = "butcher";
src = ./..;
filter = p: t:
let baseName = baseNameOf (toString p);
in gitignoreFilter ./.. p t
&& baseName != ".gitignore"
&& baseName != "nix"
&& baseName != "shell.nix"
&& baseName != "default.nix";
};
localExtraDeps = importOrElse ./local-extra-deps.nix (_: []) {inherit pkgs;};
args = {
inherit pkgs;
inherit cleanedSource;
pkg-def-extras = localExtraDeps;
};
inherit (builtins) hasAttr;
in
assert pkgs.lib.assertMsg (hasAttr "haskell-nix" pkgs) "need iohk haskell-nix overlay!";
let
versions = {
# "stack-8.0" = import ./via-stack.nix (args // { resolver = "lts-9.21"; });
# "stack-8.2" = import ./via-stack.nix (args // { resolver = "lts-11.22"; });
"stackage-8.4" = import ./via-stackage.nix (args // {
# resolver = "lts-12.26";
stackFile = "stack-8.4.yaml";
});
"stackage-8.6" = import ./via-stackage.nix (args // {
# resolver = "lts-14.27";
stackFile = "stack-8.6.yaml";
});
"stackage-8.8" = import ./via-stackage.nix (args // {
# resolver = "lts-15.12";
stackFile = "stack-8.8.yaml";
});
"hackage-8.4" = import ./via-hackage.nix (args // {
ghc-ver = "ghc844";
index-state = "2020-05-01T00:00:00Z";
# plan-sha256 = "0s6rfanb6zxhr5zbinp7h25ahwasciwj3ambsr6zdxm1l782b3ap";
# materialized = ./materialized/hackage-8.4;
configureArgs = "--allow-newer multistate:*";
});
"hackage-8.6" = import ./via-hackage.nix (args // {
ghc-ver = "ghc865";
index-state = "2020-05-01T00:00:00Z";
# plan-sha256 = "01m95xirrh00dvdxrpsx8flhcwlwcvgr3diwlnkw7lj5f3i7rfrl";
# materialized = ./materialized/hackage-8.6;
configureArgs = "--allow-newer multistate:*";
});
"hackage-8.8" = import ./via-hackage.nix (args // {
ghc-ver = "ghc883";
index-state = "2020-05-01T00:00:00Z";
# plan-sha256 = "14qs7ynlf7p2qvdk8sf498y87ss5vab3ylnbpc8sacqbpv2hv4pf";
# materialized = ./materialized/hackage-8.8;
configureArgs = "--allow-newer multistate:*";
});
} // (if hasAttr "ghc8101" pkgs.haskell-nix.compiler
then {
"hackage-8.10" = import ./via-hackage.nix (args // {
ghc-ver = "ghc8101";
index-state = "2020-06-06T00:00:00Z";
# index-sha256 = "1h1x65840jl6w2qvyq9csc7b3ivadr933glarnmydk2b23vw2i77";
# plan-sha256 = "1s8a6cb5qgf4ky5s750rzx6aa52slp1skazh8kbx0dbfjd6df7yw";
# materialized = ./materialized/hackage-8.10;
configureArgs = "--allow-newer multistate:* --constraint 'splitmix<0.1'";
});
} else builtins.trace "warn: ghc 8.10 is not avaiable, will not be tested!" {}
);
linkFarmFromDrvs = name: drvs:
let mkEntryFromDrv = drv: { name = drv.name; path = drv; };
in pkgs.linkFarm name (map mkEntryFromDrv drvs);
in
versions // {
inherit cleanedSource;
default = versions."stackage-8.8";
}

50
nix/ci.sh Executable file
View File

@ -0,0 +1,50 @@
OUTDIR="ci-out"
SUMMARY="$OUTDIR/0-summary"
CABAL_CHECK_ATTRPATH="hackage-8.10"
set -x
mkdir -p "$OUTDIR"
echo "# test summary" > "$SUMMARY"
function build-one {
local ATTRPATH=$1
# nix-build --no-out-link nix/all.nix -A "\"$ATTRPATH\".butcher.components.library"\
# 2> >(tee "$OUTDIR/$ATTRPATH-1-build-lib.txt" >&2)
# (($? == 0)) || { echo "$ATTRPATH: build src failed" >> "$SUMMARY"; return 1; }
# nix-build --no-out-link nix/all.nix -A "\"$ATTRPATH\".butcher.components.tests"\
# 2> >(tee "$OUTDIR/$ATTRPATH-2-build-test.txt" >&2)
# (($? == 0)) || { echo "$ATTRPATH: build test failed" >> "$SUMMARY"; return 1; }
OUT=$(nix-build -o "$OUTDIR/$ATTRPATH-test-result.txt" nix/all.nix -A "\"$ATTRPATH\".butcher.checks.tests"\
2> >(tee "$OUTDIR/$ATTRPATH-build.txt" >&2))
(($? == 0)) || { echo "$ATTRPATH: run test failed" >> "$SUMMARY"; return 1; }
echo "$ATTRPATH: $(grep examples "$OUTDIR/$ATTRPATH-test-result.txt")" >> "$SUMMARY"
}
function cabal-check {
nix-build --no-out-link nix/all.nix -A "\"$CABAL_CHECK_ATTRPATH\".checks.cabal-check"\
2> >(tee "$OUTDIR/cabal-check.txt" >&2)
(($? == 0)) || { echo "cabal-check: failed" >> "$SUMMARY"; return 1; }
echo "cabal-check: success" >> "$SUMMARY"
}
find "$OUTDIR" -name "stackage*" -delete
find "$OUTDIR" -name "hackage*" -delete
rm "$OUTDIR/cabal-check.txt"
CLEANEDSOURCE=$(nix-instantiate --eval --read-write-mode nix/all.nix -A "cleanedSource.outPath")
(($? == 0)) || exit 1
( eval "cd $CLEANEDSOURCE; find" ) > "$OUTDIR/1-cleanedSource.txt"
build-one "stackage-8.4"
build-one "stackage-8.6"
build-one "stackage-8.8"
build-one "hackage-8.4"
build-one "hackage-8.6"
build-one "hackage-8.8"
build-one "hackage-8.10"
cabal-check
cat "$SUMMARY"

58
nix/via-hackage.nix Normal file
View File

@ -0,0 +1,58 @@
{ pkgs
, cleanedSource
, pkg-def-extras ? []
, ghc-ver
, index-state
, index-sha256 ? null
, plan-sha256 ? null
, materialized ? null
, configureArgs ? null
}:
let
butcher-plan = pkgs.haskell-nix.importAndFilterProject (pkgs.haskell-nix.callCabalProjectToNix {
src = cleanedSource;
inherit index-state index-sha256 plan-sha256 materialized configureArgs;
# ghc = pkgs.haskell-nix.compiler.${ghc-ver};
compiler-nix-name = ghc-ver;
});
in rec {
inherit butcher-plan pkgs;
hsPkgs =
let
in let pkg-set = pkgs.haskell-nix.mkCabalProjectPkgSet
{ plan-pkgs = butcher-plan.pkgs;
pkg-def-extras = pkg-def-extras;
modules = [
{ ghc.package = pkgs.haskell-nix.compiler.${ghc-ver}; }
];
};
in pkg-set.config.hsPkgs;
inherit (hsPkgs) butcher;
inherit (hsPkgs.butcher) checks;
shell = hsPkgs.shellFor {
# Include only the *local* packages of your project.
packages = ps: with ps; [
butcher
];
# Builds a Hoogle documentation index of all dependencies,
# and provides a "hoogle" command to search the index.
withHoogle = false;
# You might want some extra tools in the shell (optional).
# Some common tools can be added with the `tools` argument
# tools = { cabal = "3.2.0.0"; };
# See overlays/tools.nix for more details
# Some you may need to get some other way.
buildInputs = with pkgs.haskellPackages;
[ pkgs.haskell-nix.cabal-install ghcid bash pkgs.nix ];
# Prevents cabal from choosing alternate plans, so that
# *all* dependencies are provided by Nix.
exactDeps = true;
};
}

89
nix/via-stackage.nix Normal file
View File

@ -0,0 +1,89 @@
{ pkgs
, cleanedSource
, stackFile
, pkg-def-extras ? []
}:
let
# package-desc = import ./plan.nix;
# butcher-plan = {
# inherit resolver;
# extras = hackage:
# { butcher = args: package-desc args // {
# src = pkgs.haskell-nix.cleanSourceHaskell {
# src = pkgs.haskell-nix.haskellLib.cleanGit { src = ./..; name = "butcher"; };
# name = "butcher";
# };
# };
# };
# };
# this does not work at all, does not use local package (!)
# butcher-plan = (pkgs.haskell-nix.importAndFilterProject (
# (pkgs.haskell-nix.callStackToNix {
# name = "butcher-plan";
# src = ./..;
# stackYamlFile = builtins.toFile "stack.yaml" ''
# resolver: ${resolver}
# packages:
# - '.'
# extra-deps: []
# extra-package-dbs: []
# '';
# ignorePackageYaml = true;
# })
# ));
cleanedSource = pkgs.haskell-nix.cleanSourceHaskell { name = "butcher-"+stackFile; src = ./..; };
butcher-nix = pkgs.haskell-nix.callStackToNix {
name = "butcher";
src = cleanedSource;
stackYaml = stackFile;
};
butcher-plan = pkgs.haskell-nix.importAndFilterProject butcher-nix;
# butcher-pkgs = {
# inherit (butcher-plan.pkgs) modules resolver;
# extras = butcher-plan.pkgs.extras ps;
# };
generatedCache = pkgs.haskell-nix.genStackCache {
src = cleanedSource;
stackYaml = stackFile;
};
hsPkgs = (pkgs.haskell-nix.mkStackPkgSet {
stack-pkgs = butcher-plan.pkgs;
pkg-def-extras = pkg-def-extras;
modules = pkgs.lib.singleton (pkgs.haskell-nix.mkCacheModule generatedCache);
}).config.hsPkgs;
in {
inherit butcher-plan hsPkgs pkgs;
inherit (hsPkgs) butcher;
inherit (hsPkgs.butcher) checks;
shell = hsPkgs.shellFor {
# Include only the *local* packages of your project.
packages = ps: with ps; [
butcher
];
# Builds a Hoogle documentation index of all dependencies,
# and provides a "hoogle" command to search the index.
withHoogle = false;
# You might want some extra tools in the shell (optional).
# Some common tools can be added with the `tools` argument
# tools = { cabal = "3.2.0.0"; };
# See overlays/tools.nix for more details
# Some you may need to get some other way.
buildInputs = with pkgs.haskellPackages;
[ cabal-install ghcid bash pkgs.nix ];
# Prevents cabal from choosing alternate plans, so that
# *all* dependencies are provided by Nix.
exactDeps = true;
};
}
# pkgs.haskell-nix.stackProject {
# src = pkgs.haskell-nix.haskellLib.cleanGit { src = ./.; name = "butcher"; };
# pkg-def-extras = pkg-def-extras;
# modules = [
# { doHaddock = false; }
# ];
# }

1
shell.nix Normal file
View File

@ -0,0 +1 @@
(import ./nix/all.nix {}).default.shell

69
stack-8.4.yaml Normal file
View File

@ -0,0 +1,69 @@
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
# A snapshot resolver dictates the compiler version and the set of packages
# to be used for project dependencies. For example:
#
# resolver: lts-3.5
# resolver: nightly-2015-09-21
# resolver: ghc-7.10.2
#
# The location of a snapshot can be provided as a file or url. Stack assumes
# a snapshot provided as a file might change, whereas a url resource does not.
#
# resolver: ./custom-snapshot.yaml
# resolver: https://example.com/snapshots/2018-01-01.yaml
resolver: lts-12.26
# User packages to be built.
# Various formats can be used as shown in the example below.
#
# packages:
# - some-directory
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
# subdirs:
# - auto-update
# - wai
packages:
- .
# The following packages have been ignored due to incompatibility with the
# resolver compiler, dependency conflicts with other packages
# or unsatisfied dependencies.
#- .
# Dependency packages to be pulled from upstream that are not in the resolver.
# These entries can reference officially published versions as well as
# forks / in-progress versions pinned to a git hash. For example:
#
# extra-deps:
# - acme-missiles-0.3
# - git: https://github.com/commercialhaskell/stack.git
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
#
extra-deps:
- deque-0.4.2.3
- extra-1.7.1
- strict-list-0.1.5
- barbies-2.0.1.0
# Override default flag values for local packages and extra-deps
# flags: {}
# Extra package databases containing global packages
# extra-package-dbs: []
# Control whether we use the GHC we find on the path
# system-ghc: true
#
# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: ">=2.1"
#
# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64
#
# Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]
#
# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor

68
stack-8.6.yaml Normal file
View File

@ -0,0 +1,68 @@
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
# A snapshot resolver dictates the compiler version and the set of packages
# to be used for project dependencies. For example:
#
# resolver: lts-3.5
# resolver: nightly-2015-09-21
# resolver: ghc-7.10.2
#
# The location of a snapshot can be provided as a file or url. Stack assumes
# a snapshot provided as a file might change, whereas a url resource does not.
#
# resolver: ./custom-snapshot.yaml
# resolver: https://example.com/snapshots/2018-01-01.yaml
resolver: lts-14.4
# User packages to be built.
# Various formats can be used as shown in the example below.
#
# packages:
# - some-directory
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
# subdirs:
# - auto-update
# - wai
packages:
- .
# Dependency packages to be pulled from upstream that are not in the resolver.
# These entries can reference officially published versions as well as
# forks / in-progress versions pinned to a git hash. For example:
#
# extra-deps:
# - acme-missiles-0.3
# - git: https://github.com/commercialhaskell/stack.git
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
#
# extra-deps: []
extra-deps:
- deque-0.4.2.3@sha256:7cc8ddfc77df351ff9c16e838ccdb4a89f055c80a3111e27eba8d90e8edde7d0,1853
- strict-list-0.1.4@sha256:0fa869e2c21b710b7133e8628169f120fe6299342628edd3d5087ded299bc941,1631
- semigroupoids-5.3.3@sha256:260b62cb8539bb988e7f551f10a45ef1c81421c0d79010e9bde9321bad4982a7,7363
- base-orphans-0.8.1@sha256:defd0057b5db93257528d89b5b01a0fee9738e878c121c686948ac4aa5dded63,2927
- hashable-1.3.0.0
- unordered-containers-0.2.10.0
# Override default flag values for local packages and extra-deps
# flags: {}
# Extra package databases containing global packages
# extra-package-dbs: []
# Control whether we use the GHC we find on the path
# system-ghc: true
#
# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: ">=2.1"
#
# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64
#
# Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]
#
# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor

65
stack-8.8.yaml Normal file
View File

@ -0,0 +1,65 @@
# Resolver to choose a 'specific' stackage snapshot or a compiler version.
# A snapshot resolver dictates the compiler version and the set of packages
# to be used for project dependencies. For example:
#
# resolver: lts-3.5
# resolver: nightly-2015-09-21
# resolver: ghc-7.10.2
#
# The location of a snapshot can be provided as a file or url. Stack assumes
# a snapshot provided as a file might change, whereas a url resource does not.
#
# resolver: ./custom-snapshot.yaml
# resolver: https://example.com/snapshots/2018-01-01.yaml
resolver: lts-15.12
# User packages to be built.
# Various formats can be used as shown in the example below.
#
# packages:
# - some-directory
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
# subdirs:
# - auto-update
# - wai
packages:
- .
# The following packages have been ignored due to incompatibility with the
# resolver compiler, dependency conflicts with other packages
# or unsatisfied dependencies.
#- .
# Dependency packages to be pulled from upstream that are not in the resolver.
# These entries can reference officially published versions as well as
# forks / in-progress versions pinned to a git hash. For example:
#
# extra-deps:
# - acme-missiles-0.3
# - git: https://github.com/commercialhaskell/stack.git
# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
#
# extra-deps: []
# Override default flag values for local packages and extra-deps
# flags: {}
# Extra package databases containing global packages
# extra-package-dbs: []
# Control whether we use the GHC we find on the path
# system-ghc: true
#
# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: ">=2.1"
#
# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64
#
# Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]
#
# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor