Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Improve prior_trap processing #170

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jparise
Copy link

@jparise jparise commented Jan 13, 2025

We use trap to bootstrap our installation function (__bp_install). We remove our code upon first execution but need to restore any preexisting trap calls. We previously used sed to process the trap string, but that had two downsides:

  1. sed is an external command dependency. It needs to exist on the system, and we need to invoke it in a subshell (which has some runtime cost).

  2. The regular expression pattern was imperfect and didn't handle trickier cases like ' characters in the trap string:

     $ (trap "echo 'hello'" DEBUG; trap -p DEBUG)
     hello
     trap -- 'echo '\''hello'\''' DEBUG
    

This change removes the dependency on sed by locally evaluating the trap string and extracting any prior trap. This works reliably because we control the format our trap string, which looks like this (with newlines expanded):

__bp_trap_string="$(trap -p DEBUG)"
trap - DEBUG
__bp_install

We use `trap` to bootstrap our installation function (__bp_install). We
remove our code upon first execution but need to restore any preexisting
trap calls. We previously used `sed` to process the trap string, but
that had two downsides:

1. `sed` is an external command dependency. It needs to exist on the
   system, and we need to invoke it in a subshell (which has some
   runtime cost).
2. The regular expression pattern was imperfect and didn't handle
   trickier cases like `'` characters in the trap string:

        $ (trap "echo 'hello'" DEBUG; trap -p DEBUG)
        hello
        trap -- 'echo '\''hello'\''' DEBUG

This change removes the dependency on `sed` by locally evaluating the
trap string and extracting any prior trap. This works reliably because
we control the format our trap string, which looks like this (with
newlines expanded):

    __bp_trap_string="$(trap -p DEBUG)"
    trap - DEBUG
    __bp_install
foo() { (( trap_invoked_count += 1 )); }

# note setting this causes BATS to mis-report the failure line when this test fails
trap "foo && echo 'hello' >/dev/null" debug
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous sed-based pattern would fail with more complex cases like this.

mitchellh added a commit to ghostty-org/ghostty that referenced this pull request Jan 16, 2025
We use `trap` to bootstrap our installation function (__bp_install). We
remove our code upon first execution but need to restore any preexisting
trap calls. We previously used `sed` to process the trap string, but
that had two downsides:

1. `sed` is an external command dependency. It needs to exist on the
system, and we need to invoke it in a subshell (which has some runtime
cost).
2. The regular expression pattern was imperfect and didn't handle
trickier cases like `'` characters in the trap string:

        $ (trap "echo 'hello'" DEBUG; trap -p DEBUG)
        hello
        trap -- 'echo '\''hello'\''' DEBUG

This change removes the dependency on `sed` by locally evaluating the
trap string and extracting any prior trap. This works reliably because
we control the format our trap string, which looks like this (with
newlines expanded):

    __bp_trap_string="$(trap -p DEBUG)"
    trap - DEBUG
    __bp_install

Upstream: rcaloras/bash-preexec#170
@jparise
Copy link
Author

jparise commented Feb 2, 2025

As a proof point, Ghostty 1.1.0 shipped with this change to its bundled bash-preexec, and we haven't heard of any issues through the pre- or post-release period yet.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants