go-script-bash icon indicating copy to clipboard operation
go-script-bash copied to clipboard

Consider including a `trap` module

Open mbland opened this issue 8 years ago • 0 comments

After working a bit with traps as part of @go.log_command and in tests/assertions, it occurs to me it might be helpful to produce a trap module that helps command scripts set traps that invoke any previously defined traps.

For example, any command scripts written in Bash executed via @go.log_command are sourced into the [email protected]_command_invoke environment. If that command script needs to set an EXIT trap, it also needs to take care to invoke the EXIT trap defined by [email protected]_command_invoke as well.

I'm thinking something along the lines of:

@go.parse_existing_trap_command {
  local signal="$1"
  local trap_command="$(trap -p $signal)"
  trap_command="${trap_command#*\'}"
  __go_existing_trap="${trap_command%\'*}"
}

@go.add_trap_command() {
  local commands="$1"
  local signal="$2"
  local __go_existing_trap
  @go.parse_existing_trap_command "$signal"
  trap "$commands; $__go_existing_trap" "$signal"
}

@go.remove_trap_command() {
  local command_to_remove="$1"
  local signal="$2"
  @go.replace_trap_command "$command_to_remove" '' "$signal"
}

@go.replace_trap_command() {
  local existing_command="$1; "
  local new_command="$2; "
  local signal="$3"

  local __go_existing_trap
  @go.parse_existing_trap "$signal"

  if [[ ! "$__go_existing_trap" =~ $existing_command ]]; then
    @go.printf 'Existing trap commands for %s not found: %s\n' \
      "$signal" "${existing_command%; }" >&2
    @go.print_stack_trace >&2
    exit 1
  fi
  trap "${__go_existing_trap/$existing_command/$new_command}" "$signal"
}

Alternatively, it may be desirable to update [email protected]_command_script to invoke the command using a new $BASH process if __GO_LOG_COMMAND_DEPTH -ne '0'. Or perhaps both?

Either way, the module may be generally useful all the same.

mbland avatar Dec 31 '16 18:12 mbland