| #!/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 "$@" |