2017-07-30 19:42:20 +01:00
|
|
|
|
# Assert that FILE exists and is executable
|
|
|
|
|
#
|
|
|
|
|
# assertExecutable FILE
|
|
|
|
|
assertExecutable() {
|
|
|
|
|
local file="$1"
|
2017-08-11 11:26:51 +01:00
|
|
|
|
[[ -f "$file" && -x "$file" ]] || \
|
|
|
|
|
die "Cannot wrap '$file' because it is not an executable file"
|
2017-07-30 19:42:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
2016-10-07 14:55:16 +01:00
|
|
|
|
# construct an executable file that wraps the actual executable
|
|
|
|
|
# makeWrapper EXECUTABLE ARGS
|
|
|
|
|
|
|
|
|
|
# ARGS:
|
|
|
|
|
# --argv0 NAME : set name of executed process to NAME
|
|
|
|
|
# (otherwise it’s called …-wrapped)
|
|
|
|
|
# --set VAR VAL : add VAR with value VAL to the executable’s environment
|
|
|
|
|
# --unset VAR : remove VAR from the environment
|
|
|
|
|
# --run COMMAND : run command before the executable
|
|
|
|
|
# The command can push extra flags to a magic list variable
|
|
|
|
|
# extraFlagsArray, which are then added to the invocation
|
|
|
|
|
# of the executable
|
|
|
|
|
# --add-flags FLAGS : add FLAGS to invocation of executable
|
|
|
|
|
|
|
|
|
|
# --prefix ENV SEP VAL : suffix/prefix ENV with VAL, separated by SEP
|
|
|
|
|
# --suffix
|
|
|
|
|
# --suffix-each ENV SEP VALS : like --suffix, but VALS is a list
|
|
|
|
|
# --prefix-contents ENV SEP FILES : like --suffix-each, but contents of FILES
|
|
|
|
|
# are read first and used as VALS
|
|
|
|
|
# --suffix-contents
|
2005-02-16 11:13:18 +00:00
|
|
|
|
makeWrapper() {
|
2017-03-05 10:56:30 +00:00
|
|
|
|
local original="$1"
|
|
|
|
|
local wrapper="$2"
|
2008-01-18 11:28:41 +00:00
|
|
|
|
local params varName value command separator n fileNames
|
2017-03-05 10:56:30 +00:00
|
|
|
|
local argv0 flagsBefore flags
|
2005-02-16 11:13:18 +00:00
|
|
|
|
|
2017-08-11 11:26:51 +01:00
|
|
|
|
assertExecutable "$original"
|
2017-07-30 19:42:20 +01:00
|
|
|
|
|
2017-03-05 10:56:30 +00:00
|
|
|
|
mkdir -p "$(dirname "$wrapper")"
|
2005-02-16 11:13:18 +00:00
|
|
|
|
|
2017-03-05 10:56:30 +00:00
|
|
|
|
echo "#! $SHELL -e" > "$wrapper"
|
2005-02-16 11:13:18 +00:00
|
|
|
|
|
|
|
|
|
params=("$@")
|
|
|
|
|
for ((n = 2; n < ${#params[*]}; n += 1)); do
|
2017-03-05 10:56:30 +00:00
|
|
|
|
p="${params[$n]}"
|
2005-02-16 11:13:18 +00:00
|
|
|
|
|
2017-04-14 04:49:05 +01:00
|
|
|
|
if [[ "$p" == "--set" ]]; then
|
2017-03-05 10:56:30 +00:00
|
|
|
|
varName="${params[$((n + 1))]}"
|
|
|
|
|
value="${params[$((n + 2))]}"
|
2005-03-09 19:07:23 +00:00
|
|
|
|
n=$((n + 2))
|
2017-11-11 10:10:01 +00:00
|
|
|
|
echo "export $varName=${value@Q}" >> "$wrapper"
|
2017-11-17 10:11:01 +00:00
|
|
|
|
elif [[ "$p" == "--set-default" ]]; then
|
|
|
|
|
varName="${params[$((n + 1))]}"
|
|
|
|
|
value="${params[$((n + 2))]}"
|
|
|
|
|
n=$((n + 2))
|
|
|
|
|
echo "export $varName=\${$varName-${value@Q}}" >> "$wrapper"
|
2017-04-14 04:49:05 +01:00
|
|
|
|
elif [[ "$p" == "--unset" ]]; then
|
2017-03-05 10:56:30 +00:00
|
|
|
|
varName="${params[$((n + 1))]}"
|
2016-02-28 13:27:43 +00:00
|
|
|
|
n=$((n + 1))
|
|
|
|
|
echo "unset $varName" >> "$wrapper"
|
2017-04-14 04:49:05 +01:00
|
|
|
|
elif [[ "$p" == "--run" ]]; then
|
2017-03-05 10:56:30 +00:00
|
|
|
|
command="${params[$((n + 1))]}"
|
2008-01-18 11:28:41 +00:00
|
|
|
|
n=$((n + 1))
|
2017-03-05 10:56:30 +00:00
|
|
|
|
echo "$command" >> "$wrapper"
|
2017-04-14 04:49:05 +01:00
|
|
|
|
elif [[ ("$p" == "--suffix") || ("$p" == "--prefix") ]]; then
|
2017-03-05 10:56:30 +00:00
|
|
|
|
varName="${params[$((n + 1))]}"
|
|
|
|
|
separator="${params[$((n + 2))]}"
|
|
|
|
|
value="${params[$((n + 3))]}"
|
2005-02-16 11:13:18 +00:00
|
|
|
|
n=$((n + 3))
|
2005-02-16 11:24:40 +00:00
|
|
|
|
if test -n "$value"; then
|
2005-03-13 20:43:04 +00:00
|
|
|
|
if test "$p" = "--suffix"; then
|
2017-11-11 10:10:01 +00:00
|
|
|
|
echo "export $varName=\$$varName\${$varName:+${separator@Q}}${value@Q}" >> "$wrapper"
|
2005-03-13 20:43:04 +00:00
|
|
|
|
else
|
2017-11-11 10:10:01 +00:00
|
|
|
|
echo "export $varName=${value@Q}\${$varName:+${separator@Q}}\$$varName" >> "$wrapper"
|
2005-03-13 20:43:04 +00:00
|
|
|
|
fi
|
2005-02-16 11:24:40 +00:00
|
|
|
|
fi
|
2017-04-14 04:49:05 +01:00
|
|
|
|
elif [[ "$p" == "--suffix-each" ]]; then
|
2017-03-05 10:56:30 +00:00
|
|
|
|
varName="${params[$((n + 1))]}"
|
|
|
|
|
separator="${params[$((n + 2))]}"
|
|
|
|
|
values="${params[$((n + 3))]}"
|
2005-02-16 11:38:52 +00:00
|
|
|
|
n=$((n + 3))
|
|
|
|
|
for value in $values; do
|
2017-11-11 10:10:01 +00:00
|
|
|
|
echo "export $varName=\$$varName\${$varName:+$separator}${value@Q}" >> "$wrapper"
|
2005-02-16 11:38:52 +00:00
|
|
|
|
done
|
2017-04-14 04:49:05 +01:00
|
|
|
|
elif [[ ("$p" == "--suffix-contents") || ("$p" == "--prefix-contents") ]]; then
|
2017-03-05 10:56:30 +00:00
|
|
|
|
varName="${params[$((n + 1))]}"
|
|
|
|
|
separator="${params[$((n + 2))]}"
|
|
|
|
|
fileNames="${params[$((n + 3))]}"
|
2005-02-16 11:38:52 +00:00
|
|
|
|
n=$((n + 3))
|
|
|
|
|
for fileName in $fileNames; do
|
2017-11-11 10:10:01 +00:00
|
|
|
|
contents="$(cat "$fileName")"
|
2009-07-16 12:22:37 +01:00
|
|
|
|
if test "$p" = "--suffix-contents"; then
|
2017-11-11 10:10:01 +00:00
|
|
|
|
echo "export $varName=\$$varName\${$varName:+$separator}${contents@Q}" >> "$wrapper"
|
2009-07-16 12:22:37 +01:00
|
|
|
|
else
|
2017-11-11 10:10:01 +00:00
|
|
|
|
echo "export $varName=${contents@Q}\${$varName:+$separator}\$$varName" >> "$wrapper"
|
2009-07-16 12:22:37 +01:00
|
|
|
|
fi
|
2005-02-16 11:38:52 +00:00
|
|
|
|
done
|
2017-04-14 04:49:05 +01:00
|
|
|
|
elif [[ "$p" == "--add-flags" ]]; then
|
2017-03-05 10:56:30 +00:00
|
|
|
|
flags="${params[$((n + 1))]}"
|
2008-06-14 21:45:58 +01:00
|
|
|
|
n=$((n + 1))
|
|
|
|
|
flagsBefore="$flagsBefore $flags"
|
2017-04-14 04:49:05 +01:00
|
|
|
|
elif [[ "$p" == "--argv0" ]]; then
|
2017-03-05 10:56:30 +00:00
|
|
|
|
argv0="${params[$((n + 1))]}"
|
2015-08-30 16:41:43 +01:00
|
|
|
|
n=$((n + 1))
|
2017-04-14 04:49:05 +01:00
|
|
|
|
else
|
|
|
|
|
die "makeWrapper doesn't understand the arg $p"
|
2015-08-30 16:41:43 +01:00
|
|
|
|
fi
|
2005-02-16 11:13:18 +00:00
|
|
|
|
done
|
|
|
|
|
|
2009-04-05 19:13:59 +01:00
|
|
|
|
# Note: extraFlagsArray is an array containing additional flags
|
|
|
|
|
# that may be set by --run actions.
|
2017-03-05 10:56:30 +00:00
|
|
|
|
# Silence warning about unexpanded extraFlagsArray:
|
|
|
|
|
# shellcheck disable=SC2016
|
|
|
|
|
echo exec ${argv0:+-a \"$argv0\"} \""$original"\" \
|
|
|
|
|
"$flagsBefore" '"${extraFlagsArray[@]}"' '"$@"' >> "$wrapper"
|
2015-08-21 00:28:31 +01:00
|
|
|
|
|
2017-03-05 10:56:30 +00:00
|
|
|
|
chmod +x "$wrapper"
|
2005-02-16 11:13:18 +00:00
|
|
|
|
}
|
2005-02-16 11:38:52 +00:00
|
|
|
|
|
|
|
|
|
addSuffix() {
|
2017-03-05 10:56:30 +00:00
|
|
|
|
suffix="$1"
|
2005-02-16 11:38:52 +00:00
|
|
|
|
shift
|
|
|
|
|
for name in "$@"; do
|
|
|
|
|
echo "$name$suffix"
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
filterExisting() {
|
|
|
|
|
for fn in "$@"; do
|
|
|
|
|
if test -e "$fn"; then
|
|
|
|
|
echo "$fn"
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
}
|
2008-01-18 10:29:58 +00:00
|
|
|
|
|
|
|
|
|
# Syntax: wrapProgram <PROGRAM> <MAKE-WRAPPER FLAGS...>
|
|
|
|
|
wrapProgram() {
|
|
|
|
|
local prog="$1"
|
2017-03-05 10:56:30 +00:00
|
|
|
|
local hidden
|
2017-07-30 19:42:20 +01:00
|
|
|
|
|
2017-08-11 11:26:51 +01:00
|
|
|
|
assertExecutable "$prog"
|
2017-07-30 19:42:20 +01:00
|
|
|
|
|
2017-03-05 10:56:30 +00:00
|
|
|
|
hidden="$(dirname "$prog")/.$(basename "$prog")"-wrapped
|
2017-04-12 16:12:16 +01:00
|
|
|
|
while [ -e "$hidden" ]; do
|
|
|
|
|
hidden="${hidden}_"
|
|
|
|
|
done
|
2017-03-05 10:56:30 +00:00
|
|
|
|
mv "$prog" "$hidden"
|
|
|
|
|
# Silence warning about unexpanded $0:
|
|
|
|
|
# shellcheck disable=SC2016
|
2017-04-14 04:49:05 +01:00
|
|
|
|
makeWrapper "$hidden" "$prog" --argv0 '$0' "${@:2}"
|
2008-01-18 10:29:58 +00:00
|
|
|
|
}
|