Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at staging-python 155 lines 5.5 kB view raw
1# Assert that FILE exists and is executable 2# 3# assertExecutable FILE 4assertExecutable() { 5 local file="$1" 6 [[ -f "$file" && -x "$file" ]] || \ 7 die "Cannot wrap '$file' because it is not an executable file" 8} 9 10# construct an executable file that wraps the actual executable 11# makeWrapper EXECUTABLE OUT_PATH ARGS 12 13# ARGS: 14# --argv0 NAME : set name of executed process to NAME 15# (otherwise it’s called …-wrapped) 16# --set VAR VAL : add VAR with value VAL to the executable’s 17# environment 18# --set-default VAR VAL : like --set, but only adds VAR if not already set in 19# the environment 20# --unset VAR : remove VAR from the environment 21# --run COMMAND : run command before the executable 22# --add-flags FLAGS : add FLAGS to invocation of executable 23 24# --prefix ENV SEP VAL : suffix/prefix ENV with VAL, separated by SEP 25# --suffix 26# --prefix-each ENV SEP VALS : like --prefix, but VALS is a list 27# --suffix-each ENV SEP VALS : like --suffix, but VALS is a list 28# --prefix-contents ENV SEP FILES : like --suffix-each, but contents of FILES 29# are read first and used as VALS 30# --suffix-contents 31makeWrapper() { 32 local original="$1" 33 local wrapper="$2" 34 local params varName value command separator n fileNames 35 local argv0 flagsBefore flags 36 37 assertExecutable "$original" 38 39 mkdir -p "$(dirname "$wrapper")" 40 41 echo "#! @shell@ -e" > "$wrapper" 42 43 params=("$@") 44 for ((n = 2; n < ${#params[*]}; n += 1)); do 45 p="${params[$n]}" 46 47 if [[ "$p" == "--set" ]]; then 48 varName="${params[$((n + 1))]}" 49 value="${params[$((n + 2))]}" 50 n=$((n + 2)) 51 echo "export $varName=${value@Q}" >> "$wrapper" 52 elif [[ "$p" == "--set-default" ]]; then 53 varName="${params[$((n + 1))]}" 54 value="${params[$((n + 2))]}" 55 n=$((n + 2)) 56 echo "export $varName=\${$varName-${value@Q}}" >> "$wrapper" 57 elif [[ "$p" == "--unset" ]]; then 58 varName="${params[$((n + 1))]}" 59 n=$((n + 1)) 60 echo "unset $varName" >> "$wrapper" 61 elif [[ "$p" == "--run" ]]; then 62 command="${params[$((n + 1))]}" 63 n=$((n + 1)) 64 echo "$command" >> "$wrapper" 65 elif [[ ("$p" == "--suffix") || ("$p" == "--prefix") ]]; then 66 varName="${params[$((n + 1))]}" 67 separator="${params[$((n + 2))]}" 68 value="${params[$((n + 3))]}" 69 n=$((n + 3)) 70 if test -n "$value"; then 71 if test "$p" = "--suffix"; then 72 echo "export $varName=\$$varName\${$varName:+${separator@Q}}${value@Q}" >> "$wrapper" 73 else 74 echo "export $varName=${value@Q}\${$varName:+${separator@Q}}\$$varName" >> "$wrapper" 75 fi 76 fi 77 elif [[ "$p" == "--prefix-each" ]]; then 78 varName="${params[$((n + 1))]}" 79 separator="${params[$((n + 2))]}" 80 values="${params[$((n + 3))]}" 81 n=$((n + 3)) 82 for value in $values; do 83 echo "export $varName=${value@Q}\${$varName:+${separator@Q}}\$$varName" >> "$wrapper" 84 done 85 elif [[ "$p" == "--suffix-each" ]]; then 86 varName="${params[$((n + 1))]}" 87 separator="${params[$((n + 2))]}" 88 values="${params[$((n + 3))]}" 89 n=$((n + 3)) 90 for value in $values; do 91 echo "export $varName=\$$varName\${$varName:+$separator}${value@Q}" >> "$wrapper" 92 done 93 elif [[ ("$p" == "--suffix-contents") || ("$p" == "--prefix-contents") ]]; then 94 varName="${params[$((n + 1))]}" 95 separator="${params[$((n + 2))]}" 96 fileNames="${params[$((n + 3))]}" 97 n=$((n + 3)) 98 for fileName in $fileNames; do 99 contents="$(cat "$fileName")" 100 if test "$p" = "--suffix-contents"; then 101 echo "export $varName=\$$varName\${$varName:+$separator}${contents@Q}" >> "$wrapper" 102 else 103 echo "export $varName=${contents@Q}\${$varName:+$separator}\$$varName" >> "$wrapper" 104 fi 105 done 106 elif [[ "$p" == "--add-flags" ]]; then 107 flags="${params[$((n + 1))]}" 108 n=$((n + 1)) 109 flagsBefore="$flagsBefore $flags" 110 elif [[ "$p" == "--argv0" ]]; then 111 argv0="${params[$((n + 1))]}" 112 n=$((n + 1)) 113 else 114 die "makeWrapper doesn't understand the arg $p" 115 fi 116 done 117 118 echo exec ${argv0:+-a \"$argv0\"} \""$original"\" \ 119 "$flagsBefore" '"$@"' >> "$wrapper" 120 121 chmod +x "$wrapper" 122} 123 124addSuffix() { 125 suffix="$1" 126 shift 127 for name in "$@"; do 128 echo "$name$suffix" 129 done 130} 131 132filterExisting() { 133 for fn in "$@"; do 134 if test -e "$fn"; then 135 echo "$fn" 136 fi 137 done 138} 139 140# Syntax: wrapProgram <PROGRAM> <MAKE-WRAPPER FLAGS...> 141wrapProgram() { 142 local prog="$1" 143 local hidden 144 145 assertExecutable "$prog" 146 147 hidden="$(dirname "$prog")/.$(basename "$prog")"-wrapped 148 while [ -e "$hidden" ]; do 149 hidden="${hidden}_" 150 done 151 mv "$prog" "$hidden" 152 # Silence warning about unexpanded $0: 153 # shellcheck disable=SC2016 154 makeWrapper "$hidden" "$prog" --argv0 '$0' "${@:2}" 155}