Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run shellcheck on installation hook tests #528

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 27 additions & 53 deletions modules/pre-commit.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
let
inherit (lib)
boolToString
concatMapStrings
concatStringsSep
compare
filterAttrs
literalExample
mapAttrsToList
mkOption
optionalString
types
remove
;
Expand Down Expand Up @@ -62,28 +63,26 @@ let
nativeBuildInputs = enabledExtraPackages
++ lib.optional (config.settings.rust.check.cargoDeps != null) cargoSetupHook;
cargoDeps = config.settings.rust.check.cargoDeps;
buildPhase = ''
set +e
HOME=$PWD
ln -fs ${configFile} .pre-commit-config.yaml
git init -q
git add .
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
git commit -m "init" -q
if [[ ${toString (compare install_stages [ "manual" ])} -eq 0 ]]
then
echo "Running: $ pre-commit run --hook-stage manual --all-files"
${cfg.package}/bin/pre-commit run --hook-stage manual --all-files
else
echo "Running: $ pre-commit run --all-files"
${cfg.package}/bin/pre-commit run --all-files
fi
exitcode=$?
git --no-pager diff --color
mkdir $out
[ $? -eq 0 ] && exit $exitcode
'';
buildPhase =
let
cmd = "pre-commit run${optionalString (install_stages == [ "manual" ]) " --hook-stage manual"} --all-files";
in
''
set +e
HOME=$PWD
ln -fs ${configFile} .pre-commit-config.yaml
git init -q
git add .
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
git commit -m "init" -q
echo "Running: $ ${cmd}"
${cfg.package}/bin/${cmd}
exitcode=$?
git --no-pager diff --color
mkdir $out
[ $? -eq 0 ] && exit $exitcode
'';
};

failedAssertions = builtins.map (x: x.message) (builtins.filter (x: !x.assertion) config.assertions);
Expand Down Expand Up @@ -361,7 +360,7 @@ in
elif ! ${cfg.gitPackage}/bin/git rev-parse --git-dir &> /dev/null; then
echo 1>&2 "WARNING: git-hooks.nix: .git not found; skipping installation."
else
GIT_WC=`${cfg.gitPackage}/bin/git rev-parse --show-toplevel`
GIT_WC=$(${cfg.gitPackage}/bin/git rev-parse --show-toplevel)

# These update procedures compare before they write, to avoid
# filesystem churn. This improves performance with watch tools like lorri
Expand All @@ -385,41 +384,16 @@ in
ln -fs ${configFile} "''${GIT_WC}/.pre-commit-config.yaml"
fi
# Remove any previously installed hooks (since pre-commit itself has no convergent design)
hooks="${concatStringsSep " " (remove "manual" supportedHooksLib.supportedHooks )}"
for hook in $hooks; do
pre-commit uninstall -t $hook
done
pre-commit uninstall${concatMapStrings (hook: " --hook-type ${hook}") (remove "manual" supportedHooksLib.supportedHooks)}
${cfg.gitPackage}/bin/git config --local core.hooksPath ""
# Add hooks for configured stages (only) ...
if [ ! -z "${concatStringsSep " " install_stages}" ]; then
for stage in ${concatStringsSep " " install_stages}; do
case $stage in
manual)
;;
# if you amend these switches please also review $hooks above
commit | merge-commit | push)
stage="pre-"$stage
pre-commit install -t $stage
;;
${concatStringsSep "|" supportedHooksLib.supportedHooks})
pre-commit install -t $stage
;;
*)
echo 1>&2 "ERROR: git-hooks.nix: either $stage is not a valid stage or git-hooks.nix doesn't yet support it."
exit 1
;;
esac
done
# ... or default 'pre-commit' hook
else
pre-commit install
fi
# Add hooks for configured stages
pre-commit install${concatMapStrings (stage: " --hook-type ${if builtins.elem stage [ "commit" "merge-commit" "push" ] then "pre-${stage}" else stage}") (remove "manual" install_stages)}

# Fetch the absolute path to the git common directory. This will normally point to $GIT_WC/.git.
common_dir=''$(${cfg.gitPackage}/bin/git rev-parse --path-format=absolute --git-common-dir)

# Convert the absolute path to a path relative to the toplevel working directory.
common_dir=''${common_dir#''$GIT_WC/}
common_dir=''${common_dir#"''$GIT_WC"/}

${cfg.gitPackage}/bin/git config --local core.hooksPath "''$common_dir/hooks"
fi
Expand Down
51 changes: 29 additions & 22 deletions nix/installation-test.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Test that checks whether the correct hooks are created in the hooks folder.
{ git, perl, coreutils, runCommand, run, lib, mktemp }:
{ git, perl, coreutils, runCommand, run, lib, mktemp, writeShellApplication }:
let
tests = {
basic-test = {
Expand Down Expand Up @@ -65,35 +65,42 @@ let
in ''
rm -f ~/.git/hooks/*
${runDerivation.shellHook}
actualHooks=(`find ~/.git/hooks -type f -printf "%f "`)
read -a expectedHooks <<< "${builtins.toString test.expectedHooks}"
read -r -a actualHooks <<< "$(find ~/.git/hooks -type f -printf "%f ")"
expectedHooks=(${builtins.toString test.expectedHooks})
if ! assertArraysEqual actualHooks expectedHooks; then
echo "${name} failed: Expected hooks '${builtins.toString test.expectedHooks}' but found '$actualHooks'."
echo "${name} failed: Expected hooks \"''${expectedHooks[*]}\" but found \"''${actualHooks[*]}\"."
return 1
fi
'')
tests;
in
runCommand "installation-test" { nativeBuildInputs = [ git perl coreutils mktemp ]; } ''
set -eoux

HOME=$(mktemp -d)
cd $HOME
git init
testScript = writeShellApplication {
name = "installation-test";
runtimeInputs = [ git perl coreutils mktemp ];
bashOptions = [ "errexit" "nounset" "xtrace" ];
text = ''
HOME=$(mktemp -d)
cd "$HOME"
git init

assertArraysEqual() {
local -n _array_one=$1
local -n _array_two=$2
diffArray=(`echo ''${_array_one[@]} ''${_array_two[@]} | tr ' ' '\n' | sort | uniq -u`)
if [ ''${#diffArray[@]} -eq 0 ]
then
return 0
else
return 1
fi
}
assertArraysEqual() {
local -n _array_one=$1
local -n _array_two=$2
read -r -a diffArray <<< "$( echo "''${_array_one[*]} ''${_array_two[*]}" | tr ' ' '\n' | sort | uniq -u )"
if [ ''${#diffArray[@]} -eq 0 ]
then
return 0
else
return 1
fi
}

${lib.concatStrings executeTest}
${lib.concatStrings executeTest}
'';
};
in
runCommand "run-installation-test" { } ''
${lib.getExe testScript}

echo "success" > $out
''