nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at python-updates 322 lines 9.5 kB view raw
1{ 2 lib, 3 stdenv, 4 pkgs, 5}: 6 7# since the tests are using a early stdenv, the stdenv will have dontPatchShebangs=1, so it has to be unset 8# https://github.com/NixOS/nixpkgs/blob/768a982bfc9d29a6bd3beb963ed4b054451ce3d0/pkgs/stdenv/linux/default.nix#L148-L153 9 10# strictDeps has to be disabled because the shell isn't in buildInputs 11 12let 13 earlyBash = 14 stdenv.__bootPackages.stdenv.__bootPackages.bashNonInteractive or pkgs.bashNonInteractive; 15 earlyCoreutils = stdenv.__bootPackages.stdenv.__bootPackages.coreutils or pkgs.coreutils; 16 earlyDiffutils = stdenv.__bootPackages.stdenv.__bootPackages.diffutils or pkgs.diffutils; 17 earlyFindutils = stdenv.__bootPackages.stdenv.__bootPackages.findutils or pkgs.findutils; 18 earlySed = stdenv.__bootPackages.stdenv.__bootPackages.gnused or pkgs.gnused; 19 20 tests = { 21 bad-shebang = stdenv.mkDerivation { 22 name = "bad-shebang"; 23 strictDeps = false; 24 dontUnpack = true; 25 installPhase = '' 26 mkdir -p $out/bin 27 echo "#!/bin/bash" > $out/bin/test 28 echo "echo -n hello" >> $out/bin/test 29 chmod +x $out/bin/test 30 dontPatchShebangs= 31 ''; 32 passthru = { 33 assertion = "grep '^#!${stdenv.shell}' $out/bin/test > /dev/null"; 34 }; 35 }; 36 37 ignores-nix-store = stdenv.mkDerivation { 38 name = "ignores-nix-store"; 39 strictDeps = false; 40 dontUnpack = true; 41 installPhase = '' 42 mkdir -p $out/bin 43 echo "#!$NIX_STORE/path/to/bash" > $out/bin/test 44 echo "echo -n hello" >> $out/bin/test 45 chmod +x $out/bin/test 46 dontPatchShebangs= 47 ''; 48 passthru = { 49 assertion = "grep \"^#!$NIX_STORE/path/to/bash\" $out/bin/test > /dev/null"; 50 }; 51 }; 52 53 updates-nix-store = stdenv.mkDerivation { 54 name = "updates-nix-store"; 55 strictDeps = false; 56 dontUnpack = true; 57 installPhase = '' 58 mkdir -p $out/bin 59 echo "#!$NIX_STORE/path/to/bash" > $out/bin/test 60 echo "echo -n hello" >> $out/bin/test 61 chmod +x $out/bin/test 62 patchShebangs --update $out/bin/test 63 dontPatchShebangs=1 64 ''; 65 passthru = { 66 assertion = "grep '^#!${stdenv.shell}' $out/bin/test > /dev/null"; 67 }; 68 }; 69 70 split-string = stdenv.mkDerivation { 71 name = "split-string"; 72 strictDeps = false; 73 dontUnpack = true; 74 installPhase = '' 75 mkdir -p $out/bin 76 echo "#!/usr/bin/env -S bash --posix" > $out/bin/test 77 echo "echo -n hello" >> $out/bin/test 78 chmod +x $out/bin/test 79 dontPatchShebangs= 80 ''; 81 passthru = { 82 assertion = "grep -v '^#!${pkgs.coreutils}/bin/env -S ${stdenv.shell} --posix' $out/bin/test > /dev/null"; 83 }; 84 }; 85 86 without-trailing-newline = stdenv.mkDerivation { 87 name = "without-trailing-newline"; 88 strictDeps = false; 89 dontUnpack = true; 90 installPhase = '' 91 mkdir -p $out/bin 92 printf "#!/bin/bash" > $out/bin/test 93 chmod +x $out/bin/test 94 dontPatchShebangs= 95 ''; 96 passthru = { 97 assertion = "grep '^#!${stdenv.shell}' $out/bin/test > /dev/null"; 98 }; 99 }; 100 101 dont-patch-builtins = stdenv.mkDerivation { 102 name = "dont-patch-builtins"; 103 strictDeps = false; 104 dontUnpack = true; 105 installPhase = '' 106 mkdir -p $out/bin 107 echo "#!/usr/bin/builtin" > $out/bin/test 108 chmod +x $out/bin/test 109 dontPatchShebangs= 110 ''; 111 passthru = { 112 assertion = "grep '^#!/usr/bin/builtin' $out/bin/test > /dev/null"; 113 }; 114 }; 115 116 read-only-script = 117 (derivation { 118 name = "read-only-script"; 119 system = stdenv.buildPlatform.system; 120 builder = lib.getExe earlyBash; 121 initialPath = [ 122 earlyBash 123 earlyCoreutils 124 earlyDiffutils 125 earlyFindutils 126 earlySed 127 ]; 128 strictDeps = false; 129 args = [ 130 "-c" 131 '' 132 set -euo pipefail 133 . ${../../stdenv/generic/setup.sh} 134 . ${../../build-support/setup-hooks/patch-shebangs.sh} 135 mkdir -p $out/bin 136 echo "#!/bin/bash" > $out/bin/test 137 echo "echo -n hello" >> $out/bin/test 138 chmod 555 $out/bin/test 139 patchShebangs $out/bin/test 140 '' 141 ]; 142 assertion = "grep '^#!${lib.getExe earlyBash}' $out/bin/test > /dev/null"; 143 }) 144 // { 145 meta = { }; 146 }; 147 148 preserves-read-only = 149 (derivation { 150 name = "preserves-read-only"; 151 system = stdenv.buildPlatform.system; 152 builder = lib.getExe earlyBash; 153 initialPath = [ 154 earlyBash 155 earlyCoreutils 156 earlyFindutils 157 earlySed 158 ]; 159 strictDeps = false; 160 args = [ 161 "-c" 162 '' 163 set -euo pipefail 164 . ${../../stdenv/generic/setup.sh} 165 . ${../../build-support/setup-hooks/patch-shebangs.sh} 166 mkdir -p $out/bin 167 echo "#!/bin/bash" > $out/bin/test 168 echo "echo -n hello" >> $out/bin/test 169 chmod 555 $out/bin/test 170 original_perms=$(stat -c %a $out/bin/test) 171 patchShebangs $out/bin/test 172 new_perms=$(stat -c %a $out/bin/test) 173 if ! [ "$original_perms" = "$new_perms" ]; then 174 echo "Permissions changed from $original_perms to $new_perms" 175 exit 1 176 fi 177 '' 178 ]; 179 assertion = "grep '^#!${lib.getExe earlyBash}' $out/bin/test > /dev/null"; 180 }) 181 // { 182 meta = { }; 183 }; 184 185 # Preserve times, see: https://github.com/NixOS/nixpkgs/pull/33281 186 preserves-timestamp = 187 (derivation { 188 name = "preserves-timestamp"; 189 system = stdenv.buildPlatform.system; 190 builder = lib.getExe earlyBash; 191 initialPath = [ 192 earlyBash 193 earlyCoreutils 194 earlyDiffutils 195 earlyFindutils 196 earlySed 197 ]; 198 strictDeps = false; 199 args = [ 200 "-c" 201 '' 202 set -euo pipefail 203 . ${../../stdenv/generic/setup.sh} 204 . ${../../build-support/setup-hooks/patch-shebangs.sh} 205 mkdir -p $out/bin 206 echo "#!/bin/bash" > $out/bin/test 207 echo "echo -n hello" >> $out/bin/test 208 chmod +x $out/bin/test 209 # Set a specific timestamp (2000-01-01 00:00:00) 210 touch -t 200001010000 $out/bin/test 211 original_timestamp=$(stat -c %Y $out/bin/test) 212 patchShebangs $out/bin/test 213 new_timestamp=$(stat -c %Y $out/bin/test) 214 if ! [ "$original_timestamp" = "$new_timestamp" ]; then 215 echo "Timestamp changed from $original_timestamp to $new_timestamp" 216 exit 1 217 fi 218 '' 219 ]; 220 assertion = "grep '^#!${lib.getExe earlyBash}' $out/bin/test > /dev/null"; 221 }) 222 // { 223 meta = { }; 224 }; 225 226 preserves-binary-data = 227 (derivation { 228 name = "preserves-binary-data"; 229 system = stdenv.buildPlatform.system; 230 builder = lib.getExe earlyBash; 231 initialPath = [ 232 earlyBash 233 earlyCoreutils 234 earlyDiffutils 235 earlyFindutils 236 earlySed 237 ]; 238 strictDeps = false; 239 args = [ 240 "-c" 241 '' 242 set -euo pipefail 243 . ${../../stdenv/generic/setup.sh} 244 . ${../../build-support/setup-hooks/patch-shebangs.sh} 245 mkdir -p $out/bin 246 # Create a script with binary data after the shebang 247 echo "#!/bin/bash" > $out/bin/test 248 echo "echo 'script start'" >> $out/bin/test 249 # Add some binary data (null bytes and other non-printable chars) 250 printf '\x00\x01\x02\xff\xfe' >> $out/bin/test 251 echo >> $out/bin/test 252 echo "echo 'script end'" >> $out/bin/test 253 chmod +x $out/bin/test 254 patchShebangs $out/bin/test 255 # Verify binary data is still present by checking file size and content 256 if ! printf '\x00\x01\x02\xff\xfe' | cmp -s - <(sed -n '3p' $out/bin/test | tr -d '\n'); then 257 echo "Binary data corrupted during patching" 258 exit 1 259 fi 260 '' 261 ]; 262 assertion = "grep '^#!${lib.getExe earlyBash}' $out/bin/test > /dev/null"; 263 }) 264 // { 265 meta = { }; 266 }; 267 }; 268in 269stdenv.mkDerivation { 270 name = "test-patch-shebangs"; 271 passthru = { 272 inherit (tests) 273 bad-shebang 274 ignores-nix-store 275 updates-nix-store 276 split-string 277 without-trailing-newline 278 dont-patch-builtins 279 read-only-script 280 preserves-read-only 281 preserves-timestamp 282 preserves-binary-data 283 ; 284 }; 285 buildCommand = '' 286 validate() { 287 local name=$1 288 local testout=$2 289 local assertion=$3 290 291 echo -n "... $name: " >&2 292 293 local rc=0 294 (out=$testout eval "$assertion") || rc=1 295 296 if [ "$rc" -eq 0 ]; then 297 echo "yes" >&2 298 else 299 echo "no" >&2 300 fi 301 302 return "$rc" 303 } 304 305 echo "checking whether patchShebangs works properly... ">&2 306 307 fail= 308 ${lib.concatStringsSep "\n" ( 309 lib.mapAttrsToList (_: test: '' 310 validate "${test.name}" "${test}" ${lib.escapeShellArg test.assertion} || fail=1 311 '') tests 312 )} 313 314 if [ "$fail" ]; then 315 echo "failed" 316 exit 1 317 else 318 echo "succeeded" 319 touch $out 320 fi 321 ''; 322}