haskell-nix-weeder/weeder-script.nix
2020-06-23 07:44:53 +03:00

65 lines
2.4 KiB
Nix

{ pkgs, # nixpkgs package set
local-packages, # list of local haskell packages in the project and their subdirectories
hs-pkgs, # package set returned by `haskell-nix.stackProject`
weeder # weeder package
}:
with rec {
# returns a list of all components (library + exes + tests + benchmarks) for a package
get-package-components = pkg: with pkgs.lib;
optional (pkg ? library) pkg.library
++ attrValues pkg.exes
++ attrValues pkg.tests
++ attrValues pkg.benchmarks;
# script code that collects 'dist-hi' directories from the listed components and puts them to ${dir}/dist-hi
get-package-dist-hi = components: dir: pkgs.lib.concatStringsSep "\n" (
[ "mkdir -p ${dir}/dist-hi" ]
++ builtins.map (cmp: ''
cp -r ${cmp}/dist-hi/. ${dir}/dist-hi/
chmod -R u+w ${dir}/dist-hi/ # make directories writeable because subsequent components may copy to the same directories
'') components
);
# a script that collects 'dist-hi' directories from all local packages
# and puts them into corresponding subdirectories
get-project-dist-hi = pkgs.lib.concatStringsSep "\n" (
map ({ name, subdirectory }:
get-package-dist-hi (get-package-components hs-pkgs.${name}.components) subdirectory
) local-packages
);
# local package list mimicking the output of `stack query locals`
local-packages-list = pkgs.writeText "locals" (builtins.toJSON (pkgs.lib.listToAttrs (
map ({ name, subdirectory }:
{ name = name; value = { path = subdirectory; }; }
) local-packages
)));
# fake stack binary to be used be weeder, which gives `stack query locals` output.
# real stack would also start fetching indexes and dependencies, we use this script to avoid that
fake-stack = pkgs.writeShellScriptBin "stack" ''
if [ "$1" != "query" -o "$2" != "locals" ]; then
echo "error: fake stack called with unexpected arguments:" "$@" > /dev/stderr
exit 1
fi
cat ${local-packages-list}
'';
# derivation which generates the final script for running weeder
weeder-script = pkgs.writeScript "run-weeder.sh" ''
# copy directories with '*.dump-hi' files to the package subdirectories
${get-project-dist-hi}
# add fake stack to the path, it will be called by weeder to get local package list
export PATH="${fake-stack}/bin:$PATH"
# run weeder
${weeder}/bin/weeder stack.yaml --dist dist-hi
'';
};
weeder-script