# Run with: # nix-build -A tests.trivial-builders.writeShellApplication { writeShellApplication, writeTextFile, runCommand, lib, linkFarm, diffutils, hello, }: let checkShellApplication = args@{ name, expected, ... }: let writeShellApplicationArgs = builtins.removeAttrs args [ "expected" ]; script = writeShellApplication writeShellApplicationArgs; executable = lib.getExe script; expected' = writeTextFile { name = "${name}-expected"; text = expected; }; actual = "${name}-actual"; in runCommand name { } '' echo "Running test executable ${name}" ${executable} > ${actual} echo "Got output from test executable:" cat ${actual} echo "Checking test output against expected output:" ${diffutils}/bin/diff --color --unified ${expected'} ${actual} touch $out ''; in linkFarm "writeShellApplication-tests" { test-meta = let script = writeShellApplication { name = "test-meta"; text = ""; meta.description = "A test for the `writeShellApplication` `meta` argument."; }; in assert script.meta.mainProgram == "test-meta"; assert script.meta.description == "A test for the `writeShellApplication` `meta` argument."; script; test-runtime-inputs = checkShellApplication { name = "test-runtime-inputs"; text = '' hello ''; runtimeInputs = [ hello ]; expected = "Hello, world!\n"; }; test-runtime-env = checkShellApplication { name = "test-runtime-env"; runtimeEnv = { MY_COOL_ENV_VAR = "my-cool-env-value"; MY_OTHER_COOL_ENV_VAR = "my-other-cool-env-value"; # Check that we can serialize a bunch of different types: BOOL = true; INT = 1; LIST = [ 1 2 3 ]; MAP = { a = "a"; b = "b"; }; }; text = '' echo "$MY_COOL_ENV_VAR" echo "$MY_OTHER_COOL_ENV_VAR" ''; expected = '' my-cool-env-value my-other-cool-env-value ''; }; test-check-phase = checkShellApplication { name = "test-check-phase"; text = ""; checkPhase = '' echo "echo -n hello" > $target ''; expected = "hello"; }; test-argument-forwarding = checkShellApplication { name = "test-argument-forwarding"; text = ""; derivationArgs.MY_BUILD_TIME_VARIABLE = "puppy"; derivationArgs.postCheck = '' if [[ "$MY_BUILD_TIME_VARIABLE" != puppy ]]; then echo "\$MY_BUILD_TIME_VARIABLE is not set to 'puppy'!" exit 1 fi ''; meta.description = "A test checking that `writeShellApplication` forwards extra arguments to `stdenv.mkDerivation`."; expected = ""; }; test-exclude-shell-checks = writeShellApplication { name = "test-exclude-shell-checks"; excludeShellChecks = [ "SC2016" ]; text = '' # Triggers SC2016: Expressions don't expand in single quotes, use double # quotes for that. echo '$SHELL' ''; }; test-bash-options-pipefail = checkShellApplication { name = "test-bash-options-pipefail"; text = '' touch my-test-file echo puppy | grep doggy | sed 's/doggy/puppy/g' # ^^^^^^^^^^ This will fail. true ''; # Don't use `pipefail`: bashOptions = [ "errexit" "nounset" ]; expected = ""; }; test-bash-options-nounset = checkShellApplication { name = "test-bash-options-nounset"; text = '' echo -n "$someUndefinedVariable" ''; # Don't use `nounset`: bashOptions = [ ]; # Don't warn about the undefined variable at build time: excludeShellChecks = [ "SC2154" ]; expected = ""; }; }