1{ resholve
2, lib
3, stdenv
4, fetchFromGitHub
5, bash
6, coreutils
7, gnugrep
8, ncurses
9, findutils
10, hostname
11, parallel
12, flock
13, procps
14, bats
15, lsof
16, callPackages
17, symlinkJoin
18, makeWrapper
19, runCommand
20, doInstallCheck ? true
21}:
22
23resholve.mkDerivation rec {
24 pname = "bats";
25 version = "1.10.0";
26
27 src = fetchFromGitHub {
28 owner = "bats-core";
29 repo = "bats-core";
30 rev = "v${version}";
31 sha256 = "sha256-gy4dyoKRlf2WFmH1/mSNwhVR3df92BgpT4TjTpV4FyQ=";
32 };
33
34 patchPhase = ''
35 patchShebangs .
36 '';
37
38 installPhase = ''
39 ./install.sh $out
40 '';
41
42 solutions = {
43 bats = {
44 scripts = [
45 "bin/bats"
46 "libexec/bats-core/*"
47 "lib/bats-core/*"
48 ];
49 interpreter = "${bash}/bin/bash";
50 inputs = [
51 bash
52 coreutils
53 gnugrep
54 ncurses
55 findutils
56 hostname
57 parallel
58 flock
59 "lib/bats-core"
60 "libexec/bats-core"
61 procps
62 ];
63 fake = {
64 external = [
65 "greadlink"
66 "shlock"
67 "pkill" # procps doesn't supply this on darwin
68 ];
69 };
70 fix = {
71 "$BATS_ROOT" = [ "${placeholder "out"}" ];
72 "$BATS_LIBEXEC" = [ "${placeholder "out"}/libexec/bats-core" ];
73 };
74 keep = {
75 "${placeholder "out"}/libexec/bats-core/bats" = true;
76 source = [
77 "${placeholder "out"}/lib/bats-core/validator.bash"
78 "${placeholder "out"}/lib/bats-core/preprocessing.bash"
79 "$BATS_TEST_SOURCE"
80 "${placeholder "out"}/lib/bats-core/tracing.bash"
81 "${placeholder "out"}/lib/bats-core/test_functions.bash"
82 "$library_load_path"
83 "${placeholder "out"}/lib/bats-core/common.bash"
84 "${placeholder "out"}/lib/bats-core/semaphore.bash"
85 "${placeholder "out"}/lib/bats-core/formatter.bash"
86 "${placeholder "out"}/lib/bats-core/warnings.bash"
87 "$setup_suite_file" # via cli arg
88 ];
89 "$interpolated_report_formatter" = true;
90 "$interpolated_formatter" = true;
91 "$pre_command" = true;
92 "$BATS_TEST_NAME" = true;
93 "${placeholder "out"}/libexec/bats-core/bats-exec-test" = true;
94 "$BATS_LINE_REFERENCE_FORMAT" = "comma_line";
95 "$BATS_LOCKING_IMPLEMENTATION" = "${flock}/bin/flock";
96 "$parallel_binary_name" = "${parallel}/bin/parallel";
97 };
98 execer = [
99 /*
100 both blatant lies for expedience; these can certainly exec args
101 they may be safe here, because they may always run things that
102 are ultimately in libexec?
103 TODO: handle parallel and flock in binlore/resholve
104 */
105 "cannot:${parallel}/bin/parallel"
106 "cannot:${flock}/bin/flock"
107
108 "cannot:libexec/bats-core/bats-preprocess"
109
110 # these do exec, but other internal files
111 "cannot:libexec/bats-core/bats-exec-file"
112 "cannot:libexec/bats-core/bats-exec-suite"
113 ];
114 };
115 };
116
117 passthru.libraries = callPackages ./libraries.nix {};
118
119 passthru.withLibraries = selector:
120 symlinkJoin {
121 name = "bats-with-libraries-${bats.version}";
122
123 paths = [
124 bats
125 ] ++ selector bats.libraries;
126
127 nativeBuildInputs = [
128 makeWrapper
129 ];
130
131 postBuild = ''
132 wrapProgram "$out/bin/bats" \
133 --suffix BATS_LIB_PATH : "$out/share/bats"
134 '';
135 };
136
137 passthru.tests.libraries = runCommand "${bats.name}-with-libraries-test" {
138 testScript = ''
139 setup() {
140 bats_load_library bats-support
141 bats_load_library bats-assert
142 bats_load_library bats-file
143
144 bats_require_minimum_version 1.5.0
145
146 TEST_TEMP_DIR="$(temp_make --prefix 'nixpkgs-bats-test')"
147 }
148
149 teardown() {
150 temp_del "$TEST_TEMP_DIR"
151 }
152
153 @test echo_hi {
154 run -0 echo hi
155 assert_output "hi"
156 }
157
158 @test cp_failure {
159 run ! cp
160 assert_line --index 0 "cp: missing file operand"
161 assert_line --index 1 "Try 'cp --help' for more information."
162 }
163
164 @test file_exists {
165 echo "hi" > "$TEST_TEMP_DIR/hello.txt"
166 assert_file_exist "$TEST_TEMP_DIR/hello.txt"
167 run cat "$TEST_TEMP_DIR/hello.txt"
168 assert_output "hi"
169 }
170 '';
171 passAsFile = [ "testScript" ];
172 } ''
173 ${bats.withLibraries (p: [ p.bats-support p.bats-assert p.bats-file ])}/bin/bats "$testScriptPath"
174 touch "$out"
175 '';
176
177 passthru.tests.upstream = bats.unresholved.overrideAttrs (old: {
178 name = "${bats.name}-tests";
179 dontInstall = true; # just need the build directory
180 nativeInstallCheckInputs = [
181 ncurses
182 parallel # skips some tests if it can't detect
183 flock # skips some tests if it can't detect
184 procps
185 ] ++ lib.optionals stdenv.isDarwin [ lsof ];
186 inherit doInstallCheck;
187 installCheckPhase = ''
188 # TODO: cut if https://github.com/bats-core/bats-core/issues/418 allows
189 sed -i '/test works even if PATH is reset/a skip "disabled for nix build"' test/bats.bats
190
191 # skip tests that assume bats `install.sh` will be in BATS_ROOT
192 rm test/root.bats
193
194 '' + (lib.optionalString stdenv.hostPlatform.isDarwin ''
195 # skip new timeout tests which are failing on macOS for unclear reasons
196 # This might relate to procps not having a pkill?
197 rm test/timeout.bats
198 '') + ''
199
200 # test generates file with absolute shebang dynamically
201 substituteInPlace test/install.bats --replace \
202 "/usr/bin/env bash" "${bash}/bin/bash"
203
204 ${bats}/bin/bats test
205 touch $out
206 '';
207 });
208
209 meta = with lib; {
210 homepage = "https://github.com/bats-core/bats-core";
211 description = "Bash Automated Testing System";
212 maintainers = with maintainers; [ abathur ];
213 license = licenses.mit;
214 platforms = platforms.unix;
215 };
216}