at 17.09-beta 144 lines 5.0 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 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 environment 17# --unset VAR : remove VAR from the environment 18# --run COMMAND : run command before the executable 19# The command can push extra flags to a magic list variable 20# extraFlagsArray, which are then added to the invocation 21# of 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# --suffix-each ENV SEP VALS : like --suffix, but VALS is a list 27# --prefix-contents ENV SEP FILES : like --suffix-each, but contents of FILES 28# are read first and used as VALS 29# --suffix-contents 30makeWrapper() { 31 local original="$1" 32 local wrapper="$2" 33 local params varName value command separator n fileNames 34 local argv0 flagsBefore flags 35 36 assertExecutable "$original" 37 38 mkdir -p "$(dirname "$wrapper")" 39 40 echo "#! $SHELL -e" > "$wrapper" 41 42 params=("$@") 43 for ((n = 2; n < ${#params[*]}; n += 1)); do 44 p="${params[$n]}" 45 46 if [[ "$p" == "--set" ]]; then 47 varName="${params[$((n + 1))]}" 48 value="${params[$((n + 2))]}" 49 n=$((n + 2)) 50 echo "export $varName=\"$value\"" >> "$wrapper" 51 elif [[ "$p" == "--unset" ]]; then 52 varName="${params[$((n + 1))]}" 53 n=$((n + 1)) 54 echo "unset $varName" >> "$wrapper" 55 elif [[ "$p" == "--run" ]]; then 56 command="${params[$((n + 1))]}" 57 n=$((n + 1)) 58 echo "$command" >> "$wrapper" 59 elif [[ ("$p" == "--suffix") || ("$p" == "--prefix") ]]; then 60 varName="${params[$((n + 1))]}" 61 separator="${params[$((n + 2))]}" 62 value="${params[$((n + 3))]}" 63 n=$((n + 3)) 64 if test -n "$value"; then 65 if test "$p" = "--suffix"; then 66 echo "export $varName=\$$varName\${$varName:+$separator}$value" >> "$wrapper" 67 else 68 echo "export $varName=$value\${$varName:+$separator}\$$varName" >> "$wrapper" 69 fi 70 fi 71 elif [[ "$p" == "--suffix-each" ]]; then 72 varName="${params[$((n + 1))]}" 73 separator="${params[$((n + 2))]}" 74 values="${params[$((n + 3))]}" 75 n=$((n + 3)) 76 for value in $values; do 77 echo "export $varName=\$$varName\${$varName:+$separator}$value" >> "$wrapper" 78 done 79 elif [[ ("$p" == "--suffix-contents") || ("$p" == "--prefix-contents") ]]; then 80 varName="${params[$((n + 1))]}" 81 separator="${params[$((n + 2))]}" 82 fileNames="${params[$((n + 3))]}" 83 n=$((n + 3)) 84 for fileName in $fileNames; do 85 if test "$p" = "--suffix-contents"; then 86 echo "export $varName=\$$varName\${$varName:+$separator}$(cat "$fileName")" >> "$wrapper" 87 else 88 echo "export $varName=$(cat "$fileName")\${$varName:+$separator}\$$varName" >> "$wrapper" 89 fi 90 done 91 elif [[ "$p" == "--add-flags" ]]; then 92 flags="${params[$((n + 1))]}" 93 n=$((n + 1)) 94 flagsBefore="$flagsBefore $flags" 95 elif [[ "$p" == "--argv0" ]]; then 96 argv0="${params[$((n + 1))]}" 97 n=$((n + 1)) 98 else 99 die "makeWrapper doesn't understand the arg $p" 100 fi 101 done 102 103 # Note: extraFlagsArray is an array containing additional flags 104 # that may be set by --run actions. 105 # Silence warning about unexpanded extraFlagsArray: 106 # shellcheck disable=SC2016 107 echo exec ${argv0:+-a \"$argv0\"} \""$original"\" \ 108 "$flagsBefore" '"${extraFlagsArray[@]}"' '"$@"' >> "$wrapper" 109 110 chmod +x "$wrapper" 111} 112 113addSuffix() { 114 suffix="$1" 115 shift 116 for name in "$@"; do 117 echo "$name$suffix" 118 done 119} 120 121filterExisting() { 122 for fn in "$@"; do 123 if test -e "$fn"; then 124 echo "$fn" 125 fi 126 done 127} 128 129# Syntax: wrapProgram <PROGRAM> <MAKE-WRAPPER FLAGS...> 130wrapProgram() { 131 local prog="$1" 132 local hidden 133 134 assertExecutable "$prog" 135 136 hidden="$(dirname "$prog")/.$(basename "$prog")"-wrapped 137 while [ -e "$hidden" ]; do 138 hidden="${hidden}_" 139 done 140 mv "$prog" "$hidden" 141 # Silence warning about unexpanded $0: 142 # shellcheck disable=SC2016 143 makeWrapper "$hidden" "$prog" --argv0 '$0' "${@:2}" 144}