github.com/benchkram/bob@v0.0.0-20240314204020-b7a57f2f9be9/install.sh (about) 1 #!/bin/sh 2 3 # Explanation https://gist.github.com/mohanpedala/1e2ff5661761d3abd0385e8223e16425 4 5 set -e 6 7 owner="benchkram" 8 name="bob" 9 base="https://github.com/${owner}" 10 11 cat /dev/null <<EOF 12 ------------------------------------------------------------------------ 13 https://github.com/client9/shlib - portable posix shell functions 14 Public domain - http://unlicense.org 15 https://github.com/client9/shlib/blob/master/LICENSE.md 16 but credit (and pull requests) appreciated. 17 ------------------------------------------------------------------------ 18 EOF 19 is_command() { 20 command -v "$1" >/dev/null 21 } 22 echoerr() { 23 echo "$@" 1>&2 24 } 25 log_prefix() { 26 echo "$0" 27 } 28 _logp=7 29 log_set_priority() { 30 _logp="$1" 31 } 32 log_priority() { 33 if test -z "$1"; then 34 echo "$_logp" 35 return 36 fi 37 [ "$1" -le "$_logp" ] 38 } 39 log_tag() { 40 case $1 in 41 0) echo "emerg" ;; 42 1) echo "alert" ;; 43 2) echo "crit" ;; 44 3) echo "err" ;; 45 4) echo "warning" ;; 46 5) echo "notice" ;; 47 6) echo "info" ;; 48 7) echo "debug" ;; 49 *) echo "$1" ;; 50 esac 51 } 52 log_debug() { 53 log_priority 7 || return 0 54 echoerr "$(log_prefix)" "$(log_tag 7)" "$@" 55 } 56 log_info() { 57 log_priority 6 || return 0 58 echoerr "$(log_prefix)" "$(log_tag 6)" "$@" 59 } 60 log_err() { 61 log_priority 3 || return 0 62 echoerr "$(log_prefix)" "$(log_tag 3)" "$@" 63 } 64 log_crit() { 65 log_priority 2 || return 0 66 echoerr "$(log_prefix)" "$(log_tag 2)" "$@" 67 } 68 uname_os() { 69 os=$(uname -s | tr '[:upper:]' '[:lower:]') 70 case "$os" in 71 cygwin_nt*) os="windows" ;; 72 mingw*) os="windows" ;; 73 msys_nt*) os="windows" ;; 74 esac 75 echo "$os" 76 } 77 uname_arch() { 78 arch=$(uname -m) 79 case $arch in 80 x86_64) arch="amd64" ;; 81 x86) arch="386" ;; 82 i686) arch="386" ;; 83 i386) arch="386" ;; 84 aarch64) arch="arm64" ;; 85 armv5*) arch="armv5" ;; 86 armv6*) arch="armv6" ;; 87 armv7*) arch="armv7" ;; 88 esac 89 echo ${arch} 90 } 91 uname_os_check() { 92 os=$(uname_os) 93 case "$os" in 94 darwin) return 0 ;; 95 dragonfly) return 0 ;; 96 freebsd) return 0 ;; 97 linux) return 0 ;; 98 android) return 0 ;; 99 nacl) return 0 ;; 100 netbsd) return 0 ;; 101 openbsd) return 0 ;; 102 plan9) return 0 ;; 103 solaris) return 0 ;; 104 windows) return 0 ;; 105 esac 106 log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib" 107 return 1 108 } 109 uname_arch_check() { 110 arch=$(uname_arch) 111 case "$arch" in 112 386) return 0 ;; 113 amd64) return 0 ;; 114 arm64) return 0 ;; 115 armv5) return 0 ;; 116 armv6) return 0 ;; 117 armv7) return 0 ;; 118 ppc64) return 0 ;; 119 ppc64le) return 0 ;; 120 mips) return 0 ;; 121 mipsle) return 0 ;; 122 mips64) return 0 ;; 123 mips64le) return 0 ;; 124 s390x) return 0 ;; 125 amd64p32) return 0 ;; 126 esac 127 log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib" 128 return 1 129 } 130 untar() { 131 tarball=$1 132 case "${tarball}" in 133 *.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;; 134 *.tar) tar --no-same-owner -xf "${tarball}" ;; 135 *.zip) unzip "${tarball}" ;; 136 *) 137 log_err "untar unknown archive format for ${tarball}" 138 return 1 139 ;; 140 esac 141 } 142 http_download_curl() { 143 local_file=$1 144 source_url=$2 145 header=$3 146 if [ -z "$header" ]; then 147 code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url") 148 else 149 code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url") 150 fi 151 if [ "$code" != "200" ]; then 152 log_debug "http_download_curl received HTTP status $code" 153 return 1 154 fi 155 return 0 156 } 157 http_download_wget() { 158 local_file=$1 159 source_url=$2 160 header=$3 161 if [ -z "$header" ]; then 162 wget -q -O "$local_file" "$source_url" 163 else 164 wget -q --header "$header" -O "$local_file" "$source_url" 165 fi 166 } 167 http_download() { 168 log_debug "http_download $2" 169 if is_command curl; then 170 http_download_curl "$@" 171 return 172 elif is_command wget; then 173 http_download_wget "$@" 174 return 175 fi 176 log_crit "http_download unable to find wget or curl" 177 return 1 178 } 179 http_copy() { 180 tmp=$(mktemp) 181 http_download "${tmp}" "$1" "$2" || return 1 182 body=$(cat "$tmp") 183 rm -f "${tmp}" 184 echo "$body" 185 } 186 github_release() { 187 owner_repo=$1 188 version=$2 189 test -z "$version" && version="latest" 190 giturl="https://github.com/${owner_repo}/releases/${version}" 191 json=$(http_copy "$giturl" "Accept:application/json") 192 test -z "$json" && return 1 193 version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//') 194 test -z "$version" && return 1 195 echo "$version" 196 } 197 hash_sha256() { 198 TARGET=${1:-/dev/stdin} 199 if is_command gsha256sum; then 200 hash=$(gsha256sum "$TARGET") || return 1 201 echo "$hash" | cut -d ' ' -f 1 202 elif is_command sha256sum; then 203 hash=$(sha256sum "$TARGET") || return 1 204 echo "$hash" | cut -d ' ' -f 1 205 elif is_command shasum; then 206 hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1 207 echo "$hash" | cut -d ' ' -f 1 208 elif is_command openssl; then 209 hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1 210 echo "$hash" | cut -d ' ' -f a 211 else 212 log_crit "hash_sha256 unable to find command to compute sha-256 hash" 213 return 1 214 fi 215 } 216 hash_sha256_verify() { 217 TARGET=$1 218 checksums=$2 219 if [ -z "$checksums" ]; then 220 log_err "hash_sha256_verify checksum file not specified in arg2" 221 return 1 222 fi 223 BASENAME=${TARGET##*/} 224 want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1) 225 if [ -z "$want" ]; then 226 log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'" 227 return 1 228 fi 229 got=$(hash_sha256 "$TARGET") 230 if [ "$want" != "$got" ]; then 231 log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got" 232 return 1 233 fi 234 } 235 cat /dev/null <<EOF 236 ------------------------------------------------------------------------ 237 End of functions from https://github.com/client9/shlib 238 ------------------------------------------------------------------------ 239 EOF 240 241 # Get OS 242 uname_os() { 243 os=$(uname -s | tr '[:upper:]' '[:lower:]') 244 case "$os" in 245 cygwin_nt*) os="windows" ;; 246 mingw*) os="windows" ;; 247 msys_nt*) os="windows" ;; 248 esac 249 echo "$os" 250 } 251 252 # Get architecture info 253 uname_arch() { 254 arch=$(uname -m) 255 case $arch in 256 x86_64) arch="amd64" ;; 257 x86) arch="386" ;; 258 i686) arch="386" ;; 259 i386) arch="386" ;; 260 aarch64) arch="arm64" ;; 261 armv5*) arch="armv5" ;; 262 armv6*) arch="armv6" ;; 263 armv7*) arch="armv7" ;; 264 esac 265 echo "$arch" 266 } 267 268 # Gets binary download URL from Github 269 # ex. https://github.com/benchkram/bob/releases/download/0.5.3/bob_0.5.3_linux_amd64 270 download_url() { 271 version=$1 272 os="$(uname_os)" 273 arch="$(uname_arch)" 274 url="${base}/${name}/releases/download/${version}/${name}_${version}_${os}_${arch}" 275 echo "$url" 276 } 277 278 binary_name() { 279 version=$1 280 os="$(uname_os)" 281 arch="$(uname_arch)" 282 echo "${name}_${version}_${os}_${arch}" 283 } 284 285 # Get binaries checksums URL 286 # ex. https://github.com/benchkram/bob/releases/download/0.5.3/checksums.txt 287 checksums_url() { 288 version=$1 289 os="$(uname_os)" 290 arch="$(uname_arch)" 291 url="${base}/${name}/releases/download/${version}/checksums.txt" 292 echo "$url" 293 } 294 295 # Validate supported OS 296 validate_os() { 297 os="$(uname_os)" 298 if [ "$os" != "linux" ] && [ "$os" != "darwin" ]; then 299 log_debug "your system is not supported" 300 return 1 301 fi 302 } 303 304 guidelines_autocompletion() { 305 echo " 306 To add auto-completion: 307 308 BASH: 309 * Add source <(bob completion) to your .bashrc 310 311 ZSH: 312 * Add source <(bob completion -z) to your .zshrc 313 " 314 } 315 316 absolute_path() { 317 cd "$(dirname "$1")" 318 case $(basename $1) in 319 ..) echo "$(dirname $(pwd))" ;; 320 .) echo "$(pwd)" ;; 321 *) echo "$(pwd)/$(basename $1)" ;; 322 esac 323 } 324 325 validate_os 326 327 tmpdir=$(mktemp -d) 328 log_debug "downloading files into ${tmpdir}" 329 330 bin_dir="${BIN_DIR:-$(pwd)}" 331 332 # Create the bin dir if it doesn't exists 333 if [ ! -d "${bin_dir}" ]; then 334 echo "Create non-existing directory ${bin_dir}" 335 if ! mkdir "${bin_dir}"; then 336 echo "Kindly asking for your password in order to install ${name} to ${install_path}" 337 sudo mkdir "${bin_dir}" 338 fi 339 fi 340 341 install_path=$(absolute_path "$bin_dir"/${name}) 342 343 # If bob already exists in bin dir, remove it 344 if [ -f "${install_path}" ]; then 345 if ! rm "${install_path}"; then 346 echo "Kindly asking for your password in order to remove ${install_path}" 347 sudo rm "${install_path}" 348 fi 349 fi 350 351 version="$(github_release "${owner}/${name}" "${BOB_VERSION}")" 352 bin_name="$(binary_name "$version")" 353 354 download_url="$(download_url "${version}")" 355 http_download "${tmpdir}/$bin_name" "${download_url}" 356 357 checksum_download_url="$(checksums_url "${version}")" 358 http_download "${tmpdir}/checksums.txt" "${checksum_download_url}" 359 hash_sha256_verify "${tmpdir}/$bin_name" "${tmpdir}/checksums.txt" 360 361 mv "${tmpdir}/$bin_name" "${tmpdir}/${name}" 362 363 if [ -w "${bin_dir}" ]; then 364 test ! -d "${bin_dir}" && install -d "${bin_dir}" 365 install "${tmpdir}/${name}" "${bin_dir}" 366 else 367 if ! install "${tmpdir}/${name}" "${bin_dir}"; then 368 echo "Kindly asking for your password in order to install ${name} to ${install_path}" 369 sudo install "${tmpdir}/${name}" "${bin_dir}" 370 fi 371 fi 372 373 rm -rf "${tmpdir}" 374 375 echo "" 376 echo "" 377 378 echo "Successfully installed ${name} in ${install_path}" 379 380 guidelines_autocompletion