{ pkgs, src, baseName }: let nixfmt = import (builtins.fetchTarball "https://github.com/serokell/nixfmt/archive/master.tar.gz") { }; in rec { baseTask = pkgs.stdenv.mkDerivation { name = "${baseName}-task"; src = src; buildInputs = [ ]; phases = "unpackPhase buildPhase"; buildPhase = '' echo "ERROR: base task buildPhase not overriden." exit 1 ''; }; shellcheck = ignoredFindPattern: baseTask.overrideAttrs (baseAttrs: rec { name = "${baseAttrs.name}-shellcheck"; buildInputs = baseAttrs.buildInputs ++ [ pkgs.shellcheck ]; ignoredPattern = if ignoredFindPattern == null then "" else ignoredFindPattern; buildPhase = '' find . -type f \( -name '*.sh' -and -regextype egrep ! -regex '${ignoredPattern}' \) -print0 | xargs -0 shellcheck -x touch $out ''; }); formatNix = baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-nixfmt"; buildInputs = baseAttrs.buildInputs ++ [ nixfmt ]; buildPhase = '' format() { nix_file="$1" diff <(nixfmt < "$nix_file") "$nix_file" || { echo "The $nix_file is unformatted. To fix it, run:" echo " nixfmt $nix_file" exit 1 } } export -f format find . -type f -name '*.nix' -print0 | xargs -0 -I{} bash -c "format {}" \; touch $out ''; }); fixme = ignoredFiles: baseTask.overrideAttrs (baseAttrs: rec { name = "${baseAttrs.name}-fixme"; buildInputs = baseAttrs.buildInputs ++ [ pkgs.ag ]; ignoredPattern = pkgs.lib.fold (a: b: " --ignore ${a} ${b}") "" (if ignoredFiles == null then [ "utils.nix" "TODOs.org" ] else ignoredFiles); buildPhase = '' ag FIXME ${ignoredPattern} || { touch $out exit 0 } echo " Found dangling FIXME markers on the project." echo " You should write them down properly on TODOs.org." exit 1 ''; }); readmeOrg = title: baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-readme-docs"; buildInputs = [ pkgs.pandoc ]; buildPhase = '' pandoc README.org -o $out --css docs/README.css --to=html5 --self-contained --metadata title="${title}" ''; }); test = testDerivations: baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-test"; buildPhase = '' echo "Ran tests for:" for d in ${builtins.toString testDerivations}; do echo " $d" done echo "All tests passed!" touch $out ''; }); shellEnvironmentBuild = shellBuildInputs: baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-shell-build-inputs"; buildPhase = '' echo "Can build shell environment for shellBuildInputs!" echo noop > $out ''; }); shellEnvironment = shellBuildInputs: pkgs.mkShell { name = "${baseName}-shell"; buildInputs = shellBuildInputs; }; overwritingPublishScript = { docsDerivation, overwrite ? true }: pkgs.writeShellScriptBin "publish.sh" '' set -euo pipefail OUT_DOCS="${docsDerivation}" ${ if overwrite then "" else "# " }${pkgs.openssh}/bin/ssh -o StrictHostKeyChecking=no "$SERVER_URL" rm -rf "$DOCS_SERVER_PATH/*" ${pkgs.rsync}/bin/rsync -avzP \ --rsh="ssh -o StrictHostKeyChecking=no" \ "$OUT_DOCS/" \ "$SERVER_URL:$DOCS_SERVER_PATH" ''; }