00_libs.sh 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. # --[ Functions
  2. # Usage: expand_path <rel_path> [<relative_to>]
  3. #
  4. # Outputs the absolute path of <rel_path> relative to <relative_to> or the
  5. # current directory.
  6. #
  7. # Example:
  8. #
  9. # cd /usr/local/games
  10. # expand_path ../foo
  11. # # output: /usr/local/foo
  12. #
  13. expand_path() {
  14. local REPLY; realpath.absolute "${2+"$2"}" "${1+"$1"}"; echo "$REPLY"
  15. }
  16. # --- vendored from https://github.com/bashup/realpaths
  17. realpath.dirname() { REPLY=.; ! [[ $1 =~ /+[^/]+/*$|^//$ ]] || REPLY="${1%${BASH_REMATCH[0]}}"; REPLY=${REPLY:-/}; }
  18. realpath.basename(){ REPLY=/; ! [[ $1 =~ /*([^/]+)/*$ ]] || REPLY="${BASH_REMATCH[1]}"; }
  19. realpath.absolute() {
  20. REPLY=$PWD; local eg=extglob; ! shopt -q $eg || eg=; ${eg:+shopt -s $eg}
  21. while (($#)); do case $1 in
  22. //|//[^/]*) REPLY=//; set -- "${1:2}" "${@:2}" ;;
  23. /*) REPLY=/; set -- "${1##+(/)}" "${@:2}" ;;
  24. */*) set -- "${1%%/*}" "${1##${1%%/*}+(/)}" "${@:2}" ;;
  25. ''|.) shift ;;
  26. ..) realpath.dirname "$REPLY"; shift ;;
  27. *) REPLY="${REPLY%/}/$1"; shift ;;
  28. esac; done; ${eg:+shopt -u $eg}
  29. }
  30. # Usage: has <command>
  31. #
  32. # Returns 0 if the <command> is available. Returns 1 otherwise. It can be a
  33. # binary in the PATH or a shell function.
  34. #
  35. # Example:
  36. #
  37. # if has curl; then
  38. # echo "Yes we do"
  39. # fi
  40. #
  41. has() {
  42. type -tP "$1" &> /dev/null
  43. }
  44. # ---
  45. # Inspired by "stdlib.sh" from "direnv"
  46. # Usage: path_add <varname> <path> [<path> ...]
  47. #
  48. # Prepends the expanded <path> to the <varname> environment variable, in order.
  49. # It prevents a common mistake where <varname> is replaced by only the new <varname>,
  50. # or where a trailing colon is left in <varname>, resulting in the current directory
  51. # being considered in the <varname>. Supports adding multiple directories at once.
  52. # The added directories must also exists, what's more, this function makes sure
  53. # the <varname> includes only once all the entries.
  54. #
  55. # Example:
  56. #
  57. # pwd
  58. # # output: /my/project
  59. # path_add PATH bin
  60. # echo $PATH
  61. # # output: /my/project/bin:/usr/bin:/bin
  62. # path_add PATH bam boum
  63. # echo $PATH
  64. # # output: /my/project/bam:/my/project/boum:/my/project/bin:/usr/bin:/bin
  65. path_add() {
  66. local path i var_name="$1"
  67. # split existing paths into an array
  68. declare -a path_array
  69. IFS=: read -ra path_array <<<"${!1-}"
  70. shift
  71. # prepend the passed paths in the right order
  72. for ((i = $#; i > 0; i--)); do
  73. full_path="$(expand_path "${!i}")"
  74. # Make sure the directories exist
  75. [ ! -d "${full_path}" ] && continue
  76. path_array=("$(expand_path "${full_path}")" ${path_array[@]+"${path_array[@]}"})
  77. done
  78. # Remove duplicates entrie
  79. # ref: https://stackoverflow.com/questions/13648410/how-can-i-get-unique-values-from-an-array-in-bash
  80. readarray -t UniqArray < <(printf '%s\n' "${path_array[@]}" | awk '!x[$0]++')
  81. # join back all the paths
  82. path=$(
  83. IFS=:
  84. echo "${UniqArray[*]}"
  85. )
  86. # and finally export back the result to the original variable
  87. export "$var_name=$path"
  88. }
  89. # Usage: path_rm <varname> <pattern> [<pattern> ...]
  90. #
  91. # Removes directories that match any of the given shell patterns from
  92. # the <varname> environment variable. Order of the remaining directories is
  93. # preserved in the resulting <varname>.
  94. #
  95. # Bash pattern syntax:
  96. # https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html
  97. #
  98. # Example:
  99. #
  100. # echo $PATH
  101. # # output: /dontremove/me:/remove/me:/usr/local/bin/:...
  102. # path_rm PATH '/remove/*'
  103. # echo $PATH
  104. # # output: /dontremove/me:/usr/local/bin/:...
  105. path_rm() {
  106. local path i discard var_name="$1"
  107. # split existing paths into an array
  108. declare -a path_array
  109. IFS=: read -ra path_array <<<"${!1}"
  110. shift
  111. patterns=("$@")
  112. results=()
  113. # iterate over path entries, discard entries that match any of the patterns
  114. # shellcheck disable=SC2068
  115. for path in ${path_array[@]+"${path_array[@]}"}; do
  116. discard=false
  117. # shellcheck disable=SC2068
  118. for pattern in ${patterns[@]+"${patterns[@]}"}; do
  119. if [[ "$path" == +($pattern) ]]; then
  120. discard=true
  121. break
  122. fi
  123. done
  124. if ! $discard; then
  125. results+=("$path")
  126. fi
  127. done
  128. # join the result paths
  129. result=$(
  130. IFS=:
  131. echo "${results[*]}"
  132. )
  133. # and finally export back the result to the original variable
  134. export "$var_name=$result"
  135. }
  136. # --[ Color VARIABLES
  137. B=""
  138. S=""
  139. I=""
  140. E=""
  141. N=""
  142. black=''
  143. BLACK=''
  144. red=''
  145. RED=''
  146. green=''
  147. GREEN=''
  148. yellow=''
  149. YELLOW=''
  150. blue=''
  151. BLUE=''
  152. magenta=''
  153. MAGENTA=''
  154. cyan=''
  155. CYAN=''
  156. white=''
  157. WHITE=''
  158. FORM1=""
  159. EFORM1=""
  160. FORM2=""
  161. EFORM2=""
  162. FORM3=""
  163. EFORM3=""
  164. FORM4=""
  165. EFORM4=""