#!/bin/bash
#
# A simple script to wrap the execution of a command so that it stores its
# output and return value into a file and then process it to later on.
#
# This is meant to be used in a makefile, specifically to allow for the output
# of a command to be stored in a file and added to the dist list, even if the
# command actually failed.
#
# For example, your makefile might include:
#
# my_target := lint
# my_target_output := $(OUT_DIR)/lint-output.txt
# my_target_retval := $(OUT_DIR)/lint-retval.txt
#
# $(my_target_output) $(my_target_retval): PRIVATE_MODULE := $(my_target)
# $(my_target_output) $(my_target_retval): PRIVATE_OUTPUT := $(my_target_output)
# $(my_target_output) $(my_target_retval): PRIVATE_RETVAL := $(my_target_retval)
# $(my_target_output) $(my_target_retval):
# $(PATH)/wrapper.sh \
# $(PRIVATE_MODULE) \
# $(PRIVATE_OUTPUT) \
# $(PRIVATE_RETVAL) \
# wrap \
# $(PATH)/run-list.sh $(LOCAL_PATH)/src
#
# $(my_target): PRIVATE_MODULE := $(my_target)
# $(my_target): PRIVATE_OUTPUT := $(my_target_output)
# $(my_target): PRIVATE_RETVAL := $(my_target_retval)
# $(my_target): $(my_target_output) $(my_target_retval)
# $(PATH)/wrapper.sh \
# $(PRIVATE_MODULE) \
# $(PRIVATE_OUTPUT) \
# $(PRIVATE_RETVAL) \
# eval
set -euo pipefail
# Terminate with a fatal error.
function fatal() {
echo "Fatal: $*"
exit 113
}
function main() {
local module="${1-}"; shift || fatal "missing argument: module"
local output="${1-}"; shift || fatal "missing argument: output"
local retval="${1-}"; shift || fatal "missing argument: retval"
local action="${1-}"; shift || fatal "missing argument: action"
# The rest of the arguments are the command to run.
if [ "$action" = 'wrap' ]; then
# Run the command specified by the rest of arguments ("$@") and save output
# and return value.
echo 0 >"${retval}"
"$@" >"${output}" 2>&1 || echo "$?" >"${retval}"
# Wrapping itself is always successful.
return
elif [ "$action" = 'eval' ]; then
local result="$(cat "${retval}")"
if [ "$result" = 0 ]; then
# If successful only print the last few lines.
tail -n 5 "$output" | sed -e "s/^/${module}: /"
else
# Print the entire output on failure.
cat "$output" | sed -e "s/^/${module}: /"
fi
# Evaluating returns the stored return value.
return "$result"
else
fatal "invalid action: $action"
fi
}
main "$@"