[bash] improve PATH manipulation

The previous implementation failed to prevent duplicates if the entry
being added was the only entry already present in the path. The reason
is that it always required a : to be present in order to remove the new
entry before adding it.

The new implementation is clearer and solves that. However, if the new
entry is already present it will be kept where it was, not moved to the
front of the list. This is fine at the moment.
This commit is contained in:
Fernando Schauenburg 2020-12-03 18:34:23 +01:00
parent eef6e7d58f
commit 6c7b29705e

View file

@ -39,17 +39,19 @@ export VIMINIT='let $MYVIMRC="$XDG_CONFIG_HOME/vim/vimrc" | source $MYVIMRC'
# shellcheck disable=SC1091 # /etc/profile is provided by macOS. # shellcheck disable=SC1091 # /etc/profile is provided by macOS.
[ "$(uname)" == "Darwin" ] && { PATH=""; source /etc/profile; } [ "$(uname)" == "Darwin" ] && { PATH=""; source /etc/profile; }
prepend_dir() { # 1: dir to add, 2: variable to manipulate _prepend_path() { # 1: dir to add, 2: path variable to manipulate
[ -d "$1" ] && [ -n "$2" ] || return if [ -d "$1" ] && [ -n "$2" ]; then
local list="${!2}" # capture current value local _path="${!2}" # get path variable value
list=${list#"$1:"} # remove dir from beginning case ":$_path:" in
list=${list//":$1:"/:} # remove dir from middle *":$1:"*) :;; # dir already in path, noop (:)
list=${list%":$1"} # remove dir from end *) _path="$1${_path:+:}$_path";; # prepend (adding : if not empty)
printf -v "$2" "$1${list:+":$list"}" # add in front (use : only if empty) esac
printf -v "$2" "%s" "$_path" # write back to path variable
fi
} }
# Add custom bin dirs to PATH if they exist and are not already in PATH. # Add custom bin dirs to PATH if they exist and are not already in PATH.
while read -r dir; do prepend_dir "$dir" PATH; done <<EOL while read -r dir; do _prepend_path "$dir" PATH; done <<EOL
$LOCAL_PREFIX/bin $LOCAL_PREFIX/bin
$LOCAL_PREFIX/opt/man-db/libexec/bin $LOCAL_PREFIX/opt/man-db/libexec/bin
$LOCAL_PREFIX/opt/coreutils/libexec/gnubin $LOCAL_PREFIX/opt/coreutils/libexec/gnubin
@ -60,7 +62,7 @@ EOL
# Prepend custom man directories to MANPATH if they exist, so that we get # Prepend custom man directories to MANPATH if they exist, so that we get
# correct man page entries when multiple versions of a command are # correct man page entries when multiple versions of a command are
# available. # available.
while read -r dir; do prepend_dir "$dir" MANPATH; done <<EOL while read -r dir; do _prepend_path "$dir" MANPATH; done <<EOL
$LOCAL_PREFIX/share/man $LOCAL_PREFIX/share/man
$LOCAL_PREFIX/opt/man-db/libexec/man $LOCAL_PREFIX/opt/man-db/libexec/man
$LOCAL_PREFIX/opt/coreutils/libexec/gnuman $LOCAL_PREFIX/opt/coreutils/libexec/gnuman
@ -68,7 +70,7 @@ while read -r dir; do prepend_dir "$dir" MANPATH; done <<EOL
$HOME/.local/share/man $HOME/.local/share/man
EOL EOL
unset dir prepend_dir unset dir
############################################################################## ##############################################################################
# Customize shell options & variables # Customize shell options & variables