|
@@ -0,0 +1,181 @@
|
|
|
|
+# --[ Functions
|
|
|
|
+
|
|
|
|
+# Usage: expand_path <rel_path> [<relative_to>]
|
|
|
|
+#
|
|
|
|
+# Outputs the absolute path of <rel_path> relative to <relative_to> or the
|
|
|
|
+# current directory.
|
|
|
|
+#
|
|
|
|
+# Example:
|
|
|
|
+#
|
|
|
|
+# cd /usr/local/games
|
|
|
|
+# expand_path ../foo
|
|
|
|
+# # output: /usr/local/foo
|
|
|
|
+#
|
|
|
|
+expand_path() {
|
|
|
|
+ local REPLY; realpath.absolute "${2+"$2"}" "${1+"$1"}"; echo "$REPLY"
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+# --- vendored from https://github.com/bashup/realpaths
|
|
|
|
+realpath.dirname() { REPLY=.; ! [[ $1 =~ /+[^/]+/*$|^//$ ]] || REPLY="${1%${BASH_REMATCH[0]}}"; REPLY=${REPLY:-/}; }
|
|
|
|
+realpath.basename(){ REPLY=/; ! [[ $1 =~ /*([^/]+)/*$ ]] || REPLY="${BASH_REMATCH[1]}"; }
|
|
|
|
+
|
|
|
|
+realpath.absolute() {
|
|
|
|
+ REPLY=$PWD; local eg=extglob; ! shopt -q $eg || eg=; ${eg:+shopt -s $eg}
|
|
|
|
+ while (($#)); do case $1 in
|
|
|
|
+ //|//[^/]*) REPLY=//; set -- "${1:2}" "${@:2}" ;;
|
|
|
|
+ /*) REPLY=/; set -- "${1##+(/)}" "${@:2}" ;;
|
|
|
|
+ */*) set -- "${1%%/*}" "${1##${1%%/*}+(/)}" "${@:2}" ;;
|
|
|
|
+ ''|.) shift ;;
|
|
|
|
+ ..) realpath.dirname "$REPLY"; shift ;;
|
|
|
|
+ *) REPLY="${REPLY%/}/$1"; shift ;;
|
|
|
|
+ esac; done; ${eg:+shopt -u $eg}
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+# Usage: has <command>
|
|
|
|
+#
|
|
|
|
+# Returns 0 if the <command> is available. Returns 1 otherwise. It can be a
|
|
|
|
+# binary in the PATH or a shell function.
|
|
|
|
+#
|
|
|
|
+# Example:
|
|
|
|
+#
|
|
|
|
+# if has curl; then
|
|
|
|
+# echo "Yes we do"
|
|
|
|
+# fi
|
|
|
|
+#
|
|
|
|
+has() {
|
|
|
|
+ type -tP "$1" &> /dev/null
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+# ---
|
|
|
|
+# Inspired by "stdlib.sh" from "direnv"
|
|
|
|
+# Usage: path_add <varname> <path> [<path> ...]
|
|
|
|
+#
|
|
|
|
+# Prepends the expanded <path> to the <varname> environment variable, in order.
|
|
|
|
+# It prevents a common mistake where <varname> is replaced by only the new <varname>,
|
|
|
|
+# or where a trailing colon is left in <varname>, resulting in the current directory
|
|
|
|
+# being considered in the <varname>. Supports adding multiple directories at once.
|
|
|
|
+# The added directories must also exists, what's more, this function makes sure
|
|
|
|
+# the <varname> includes only once all the entries.
|
|
|
|
+#
|
|
|
|
+# Example:
|
|
|
|
+#
|
|
|
|
+# pwd
|
|
|
|
+# # output: /my/project
|
|
|
|
+# path_add PATH bin
|
|
|
|
+# echo $PATH
|
|
|
|
+# # output: /my/project/bin:/usr/bin:/bin
|
|
|
|
+# path_add PATH bam boum
|
|
|
|
+# echo $PATH
|
|
|
|
+# # output: /my/project/bam:/my/project/boum:/my/project/bin:/usr/bin:/bin
|
|
|
|
+path_add() {
|
|
|
|
+ local path i var_name="$1"
|
|
|
|
+ # split existing paths into an array
|
|
|
|
+ declare -a path_array
|
|
|
|
+ IFS=: read -ra path_array <<<"${!1-}"
|
|
|
|
+ shift
|
|
|
|
+
|
|
|
|
+ # prepend the passed paths in the right order
|
|
|
|
+ for ((i = $#; i > 0; i--)); do
|
|
|
|
+ full_path="$(expand_path "${!i}")"
|
|
|
|
+ # Make sure the directories exist
|
|
|
|
+ [ ! -d "${full_path}" ] && continue
|
|
|
|
+ path_array=("$(expand_path "${full_path}")" ${path_array[@]+"${path_array[@]}"})
|
|
|
|
+ done
|
|
|
|
+
|
|
|
|
+ # Remove duplicates entrie
|
|
|
|
+ # ref: https://stackoverflow.com/questions/13648410/how-can-i-get-unique-values-from-an-array-in-bash
|
|
|
|
+ readarray -t UniqArray < <(printf '%s\n' "${path_array[@]}" | awk '!x[$0]++')
|
|
|
|
+
|
|
|
|
+ # join back all the paths
|
|
|
|
+ path=$(
|
|
|
|
+ IFS=:
|
|
|
|
+ echo "${UniqArray[*]}"
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ # and finally export back the result to the original variable
|
|
|
|
+ export "$var_name=$path"
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+# Usage: path_rm <varname> <pattern> [<pattern> ...]
|
|
|
|
+#
|
|
|
|
+# Removes directories that match any of the given shell patterns from
|
|
|
|
+# the <varname> environment variable. Order of the remaining directories is
|
|
|
|
+# preserved in the resulting <varname>.
|
|
|
|
+#
|
|
|
|
+# Bash pattern syntax:
|
|
|
|
+# https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html
|
|
|
|
+#
|
|
|
|
+# Example:
|
|
|
|
+#
|
|
|
|
+# echo $PATH
|
|
|
|
+# # output: /dontremove/me:/remove/me:/usr/local/bin/:...
|
|
|
|
+# path_rm PATH '/remove/*'
|
|
|
|
+# echo $PATH
|
|
|
|
+# # output: /dontremove/me:/usr/local/bin/:...
|
|
|
|
+path_rm() {
|
|
|
|
+ local path i discard var_name="$1"
|
|
|
|
+ # split existing paths into an array
|
|
|
|
+ declare -a path_array
|
|
|
|
+ IFS=: read -ra path_array <<<"${!1}"
|
|
|
|
+ shift
|
|
|
|
+
|
|
|
|
+ patterns=("$@")
|
|
|
|
+ results=()
|
|
|
|
+
|
|
|
|
+ # iterate over path entries, discard entries that match any of the patterns
|
|
|
|
+ # shellcheck disable=SC2068
|
|
|
|
+ for path in ${path_array[@]+"${path_array[@]}"}; do
|
|
|
|
+ discard=false
|
|
|
|
+ # shellcheck disable=SC2068
|
|
|
|
+ for pattern in ${patterns[@]+"${patterns[@]}"}; do
|
|
|
|
+ if [[ "$path" == +($pattern) ]]; then
|
|
|
|
+ discard=true
|
|
|
|
+ break
|
|
|
|
+ fi
|
|
|
|
+ done
|
|
|
|
+ if ! $discard; then
|
|
|
|
+ results+=("$path")
|
|
|
|
+ fi
|
|
|
|
+ done
|
|
|
|
+
|
|
|
|
+ # join the result paths
|
|
|
|
+ result=$(
|
|
|
|
+ IFS=:
|
|
|
|
+ echo "${results[*]}"
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ # and finally export back the result to the original variable
|
|
|
|
+ export "$var_name=$result"
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+# --[ Color VARIABLES
|
|
|
|
+B="[1m"
|
|
|
|
+S="[4m"
|
|
|
|
+I="[7m"
|
|
|
|
+E="[7m[1m"
|
|
|
|
+N="[0m"
|
|
|
|
+black='[0;30m'
|
|
|
|
+BLACK='[1;30m'
|
|
|
|
+red='[0;31m'
|
|
|
|
+RED='[1;31m'
|
|
|
|
+green='[0;32m'
|
|
|
|
+GREEN='[1;32m'
|
|
|
|
+yellow='[0;33m'
|
|
|
|
+YELLOW='[1;33m'
|
|
|
|
+blue='[0;34m'
|
|
|
|
+BLUE='[1;34m'
|
|
|
|
+magenta='[0;35m'
|
|
|
|
+MAGENTA='[1;35m'
|
|
|
|
+cyan='[0;36m'
|
|
|
|
+CYAN='[1;36m'
|
|
|
|
+white='[0;37m'
|
|
|
|
+WHITE='[1;37m'
|
|
|
|
+FORM1="[0;34m"
|
|
|
|
+EFORM1="[m"
|
|
|
|
+FORM2="[0;36;40m"
|
|
|
|
+EFORM2="[m"
|
|
|
|
+FORM3="[0;33;40m"
|
|
|
|
+EFORM3="[m"
|
|
|
|
+FORM4="[0;32;40m"
|
|
|
|
+EFORM4="[m"
|