8cb53ba692a3df24a9b3159ef221ec3cf8d058e1

Author
Marc Cornellà <hello@mcornella.com>
Committer
Marc Cornellà <hello@mcornella.com>
Date

Message

fix(gnu-utils): reassign GNU utils on `preexec` (#10535)

The previous version rebound the `hash` and `rehash` builtins to
reassing GNU utils when they were called. This didn't take into
account that when `$PATH` changes, the commands are rehashed as
well.

This version adds a preexec hook to reassign the GNU utilities
before running any command, if and only if they aren't already
reassigned. This is checked by looking at the `whoami` command.

Fixes #10535

Diff

 1diff --git a/plugins/gnu-utils/gnu-utils.plugin.zsh b/plugins/gnu-utils/gnu-utils.plugin.zsh
 2index 5b8f71c8a0596d6e32c122638c369fe757e85d05..6ede9e3a7be873d397bdb5e32cdedbc711d2957a 100644
 3--- a/plugins/gnu-utils/gnu-utils.plugin.zsh
 4+++ b/plugins/gnu-utils/gnu-utils.plugin.zsh
 5@@ -11,11 +11,8 @@ if [[ ! -x "${commands[gwhoami]}" ]]; then
 6 fi
 7 
 8 __gnu_utils() {
 9-  emulate -L zsh
10-  local gcmds
11+  local -a gcmds
12   local gcmd
13-  local cmd
14-  local prefix
15 
16   # coreutils 
17   gcmds=('g[' 'gbase64' 'gbasename' 'gcat' 'gchcon' 'gchgrp' 'gchmod'
18@@ -43,36 +40,21 @@ __gnu_utils() {
19     (( ${+commands[$gcmd]} )) || continue
20     
21     # This method allows for builtin commands to be primary but it's
22-    # lost if hash -r or rehash -f is executed. Thus, those two 
23-    # functions have to be wrapped.
24+    # lost if hash -r or rehash is executed, or if $PATH is updated.
25+    # Thus, a preexec hook is needed, which will only run if whoami
26+    # is not already rehashed.
27     #
28     hash ${gcmd[2,-1]}=${commands[$gcmd]}
29-
30-    # This method generates wrapper functions.
31-    # It will override shell builtins.
32-    #
33-    # eval "function $gcmd[2,-1]() { \"${prefix}/${gcmd//"["/"\\["}\" \"\$@\"; }"
34-
35-    # This method is inflexible since the aliases are at risk of being
36-    # overridden resulting in the BSD coreutils being called.
37-    #
38-    # alias "$gcmd[2,-1]"="${prefix}/${gcmd//"["/"\\["}"
39   done
40 
41   return 0
42 }
43-__gnu_utils
44 
45-function hash() {
46-  if [[ "$*" =~ "-(r|f)" ]]; then
47-    builtin hash "$@"
48-    __gnu_utils
49-  else
50-    builtin hash "$@"
51-  fi
52+__gnu_utils_preexec() {
53+  # Run __gnu_utils when the whoami command is not already rehashed.
54+  # This acts as a sign that we need to rehash all GNU utils.
55+  [[ "${commands[whoami]}" = "${commands[gwhoami]}" ]] || __gnu_utils
56 }
57 
58-function rehash() {
59-  builtin rehash "$@"
60-  __gnu_utils
61-}
62+autoload -Uz add-zsh-hook
63+add-zsh-hook preexec __gnu_utils_preexec