- 
                Notifications
    You must be signed in to change notification settings 
- Fork 98
Request for public/stable APIs to enable/disable the hooks and to manually invoke registered functions #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| 
 Can you provide some pointers for this behavior? What is more "proper" about your approach? | 
| 
 Maybe the word choice proper was not the appropriate one. I'm not a native speaker so don't know what would be the best-fit word for this case, but ble.sh is an alternative implementation of a line editor. Everything including the prompt calculation and command execution is under the control of  
 It depends on what kind of information you need, but if you need the information on the interface of these hooks, it is explained in §1.2.2 of the manual. If you need the implementation details, it is hard to point one place because ble.sh implements an entire line editor and requires reading larger code sections to understand the whole execution flow, but  Edit (2022-02-20): If you are interested in how these APIs can be used from the framework that provides precmd and preexec mechanisms, you can read  | 
01bfc4e    to
    1c82488      
    Compare
  
    | I have added code comments to explain the new functions and force-pushed the changes. The overall diff of the forced push is here.diff --git a/bash-preexec.sh b/bash-preexec.sh
index f1758d3..06db478 100644
--- a/bash-preexec.sh
+++ b/bash-preexec.sh
@@ -153,6 +153,9 @@ __bp_precmd_invoke_cmd() {
     bash_preexec_invoke_precmd_functions "$__bp_last_ret_value" "$__bp_last_argument_prev_command"
 }
+# This function invokes every function defined in our function array
+# "precmd_function".  This function receives the arguments $1 and $2 for $? and
+# $_, respectively, that will be set for the precmd functions.
 bash_preexec_invoke_precmd_functions() {
     local __lastexit=$1 __lastarg=$2
     # Invoke every function defined in our function array.
@@ -267,8 +270,12 @@ __bp_preexec_invoke_exec() {
     __bp_set_ret_value "$preexec_ret_value" "$__bp_last_argument_prev_command"
 }
-# This function invokes every function defined in our function array.  This
-# function assigns the last error exit status to the variable
+# This function invokes every function defined in our function array
+# "preexec_function".  This function receives the arguments $1 and $2 for $?
+# and $_, respectively, that will be set for the preexec functions.  The third
+# argument $3 specifies the user command that is going to be executed
+# (corresponding to BASH_COMMAND in the DEBUG trap).  This function assigns the
+# last non-zero exit status from the preexec functions to the variable
 # `preexec_ret_value`.  If there is no error, preexec_ret_value is set to `0`.
 bash_preexec_invoke_preexec_functions() {
     local __lastexit=$1 __lastarg=$2 __this_command=$3
@@ -367,6 +374,7 @@ __bp_install_after_session_init() {
     PROMPT_COMMAND+=${bash_preexec_install_string}
 }
+# Remove hooks installed in the DEBUG trap and PROMPT_COMMAND.
 bash_preexec_uninstall() {
     # Remove __bp_install hook from PROMPT_COMMAND
     if [[ ${PROMPT_COMMAND-} == *"$bash_preexec_install_string"* ]]; then
@@ -389,6 +397,7 @@ bash_preexec_uninstall() {
         fi
     fi
 }
+declare -ft bash_preexec_uninstall
 # Run our install so long as we're not delaying it.
 if [[ -z "${__bp_delay_install:-}" ]]; thenP.S. If we need to describe the new APIs in README, I can also add the description there. Supported Bash versionsBy the way, what is the minimal Bash version that      PROMPT_COMMAND=${PROMPT_COMMAND/#$'__bp_precmd_invoke_cmd\n'/$'\n'}
    PROMPT_COMMAND=${PROMPT_COMMAND%$'\n__bp_interactive_mode'}
    PROMPT_COMMAND=${PROMPT_COMMAND#$'\n'} | 
| @akinomyoga Thanks for the PR and support of this project. I'll take a look and chime in before end of week! | 
| } | ||
|  | ||
| # Remove hooks installed in the DEBUG trap and PROMPT_COMMAND. | ||
| bash_preexec_uninstall() { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced that bash-preexec should be responsible for maintaining any over head of uninstalling itself from both trap and prompt_command. Any libraries using these shared variables have more or less had to clean them up and maintain them on their own, as does bash-preexec with its installation. With the defined global variables what's stopping from just implementing this in your own library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the defined global variables what's stopping from just implementing this in your own library?
If the setup of bash-preexec.sh would never change in the future forever, I could just assume the current setup of bash-preexec.sh and write a code to clean up the things that are installed by the current bash-preexec.sh.
However, if the __bp_install configuration can change in the future (e.g. as suggested in #128), the cleanup code also needs to be updated. I don't think it is a good idea to update the cleanup code at the users' side every time the __bp_install configuration of bash-preexec.sh is changed. In particular, if the method of uninstalling the hooks would not be provided by bash-preexec.sh, the user/library needs to maintain the separate cleanup code for each of all the past versions of bash-preexec.sh and to detect the precise version of bash-preexec.sh.
This is actually the reason that I would like to request the "stable" public API rather than relying on the details of the internal implementation that can be frequently changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get your reasoning and desire for this as a way to help with your library and not just implementing it yourself. I just think there's no real standard here I've seen other libraries that have clashed with bash-preexec as well since they also make the assumption they'll have access to these parts of the system configuration. (Liquid Prompt is one example) My assumption is, these too can cause issues with ble.sh and we're trying to chase individual fires here.
I am concerned that this is an esoteric use case and will likely just add operational overhead to maintaining it. With that said, if any other contributors see value in this I'm supportive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Maybe I miss your exact point (What does "the system configuration" mean?), but I think I'll later need to look at Liquid Prompt.
| @akinomyoga thanks again for the PR and trying to help make bash-preexec better. This small library has gotten more widely used across other projects/companies than ever originally anticipated. As such, it's definitely opinionated toward original use cases and has clashed withe other libraries over shared state like  I think I'm open to most of this change provided it's not breaking. Left comments and questions in line. 
 I think 3.1 sounds right. Unless there's some other feature being used that would date it later. We should add this to the documentation at the top. | 
01527e5    to
    4caf63c      
    Compare
  
    | Thank you for your careful review and valuable comments! I have addressed or commented on the points that you have raised in each review comment. edit: I have also rebased it on top of the current  
 Thank you for the clarification! Maybe we might also add the version check at the beginning of  | 
| 
 Sure. Feel free to add in separate commit if you'd like. Not necessary in this stack. | 
| } | ||
|  | ||
| # Remove hooks installed in the DEBUG trap and PROMPT_COMMAND. | ||
| bash_preexec_uninstall() { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get your reasoning and desire for this as a way to help with your library and not just implementing it yourself. I just think there's no real standard here I've seen other libraries that have clashed with bash-preexec as well since they also make the assumption they'll have access to these parts of the system configuration. (Liquid Prompt is one example) My assumption is, these too can cause issues with ble.sh and we're trying to chase individual fires here.
I am concerned that this is an esoteric use case and will likely just add operational overhead to maintaining it. With that said, if any other contributors see value in this I'm supportive.
| @dimo414 or any other contributors have thoughts on the necessity of an uninstall function i.e. the proposed | 
| I have noticed that an existing test for  bash-preexec/test/bash-preexec.bats Lines 53 to 59 in d308800 
 Here, line 58 should be  However, now I believe we can and should use  | 
| @akinomyoga thanks for updating with tests. Looks good. Will hold for any other feedback/input from other contributors. | 
4a37150    to
    697b588      
    Compare
  
    697b588    to
    fa43a27      
    Compare
  
    | There was a conflict, so I rebased and squashed commits. | 
fa43a27    to
    3305f42      
    Compare
  
    3305f42    to
    cbd3390      
    Compare
  
    * Do not prefix local varnames with underscores
* Make "__bp_invoke_pre{cmd,exec}_functions" return the last non-zero exit status
* Test "__bp_invoke_pre{cmd,exec}_functions"
    * Rename public functions and variables as "bash_preexec_*" * Remove the compatibility variable name "__bp_install_string" * Add a note on the "trace" function attribute * Preserve the previous exit status and argument * Test the installation of convenience functions * Test "bash_preexec_uninstall"
cbd3390    to
    020416e      
    Compare
  
    
bash-preexecrelies on theDEBUGtrap (forpreexec) andPROMPT_COMMAND(forprecmd). In particular, the hook using theDEBUGtrap is a kind of hack and fragile. TheDEBUGtrap is called for every single shell command (of the top-level whenset -Torshopt -s extdebugis not set), which makes the execution slower. TheDEBUGtrap can interfere with other Bash configurations that use theDEBUGtrap. The implementation ofpreexecby theDEBUGtrap also causes problems like #115, #104, #116, #100, #25, and #6. The hook usingPROMPT_COMMAND(forprecmd) is not so stable, in particular when other configurations add settings such asPROMPT_COMMAND="${PROMPT_COMMAND+$PROMPT_COMMAND;}__new_settings__"(see #128 for example).Therefore, when the other framework provides proper support for the
preexecandprecmdhooks, it would be better to just use them instead of relying on fragileDEBUGandPROMPT_COMMAND. To allow users or other Bash configuration frameworks to choose howprecmdandpreexecofbash-preexecwill be invoked, I would like to request public/stable APIs to install/uninstallDEBUGandPROMPThooks in arbitrary timing and also the public/stable APIs to invoke{precmd,preexec}_functionsfrom external mechanisms ofpreexecandprecmd.The public APIs that I would like to request in this PR are:
preexec_functionsbash_preexec_invoke_preexec_functionsin this PR.precmd_functionsbash_preexec_invoke_precmd_functionsin this PR.DEBUGandPROMPT_COMMANDbash_preexec_install_stringin this PR, which was originally named__bp_install_string.bash-preexecregisters to theDEBUGtrapbash_preexec_trapdebug_stringin this PR.DEBUGandPROMPT_COMMANDbash_preexec_uninstall. This is a new feature that did not exist previously.About the API names
I have initially created commit fe46a97 with the existing naming convention of
__bp_*. However, now we have merged #123 wherebash_preexec_*has been adopted as the name for the public interfaces, so I have followed the new convention in commit 01bfc4e. I can adjust these naming if there are any requests.Background
In my project of Bash configuration (ble.sh), I have so far received issues caused by the interference with
bash-preexecseveral times. I have been trying to make the Bash configuration work withbash-preexec, but there is still a limitation, and it is hard to make it work perfectly (including the other issues that are reported in this upstream repository).ble.shactually provides proper support for thePRECMDandPREEXEChooks, so I would like to recommend users to use them instead ofbash-preexec, but there are many existing settings and configurations that rely onbash-preexec. Also, I don't want to unnecessarily require users to create dependency on ble.sh. So I decided to rewrite the hooks bybash-preexecwhenble.shdetects it. Currently,ble.shassumes many things about the internals ofbash-preexecin rewriting the hooks bybash-preexec, which is not ideal. What I actually need is just several public/stable APIs just I described above.Related discussions: