#!/usr/bin/env bash set -eo pipefail DEPS_PATH="${HOME}/.local/share" BOLD=$(tput bold) CYAN=$(tput setaf 6) GREEN=$(tput setaf 2) YELLOW=$(tput setaf 3) RED="$(tput setaf 1)" RESET=$(tput sgr0) log() { # Print a message and send it to stdout or stderr depending upon log level, also configurable with debug etc. # # Arguments: # level # - The log level, defined within a case check in this function # message # - The info message # line_number # - The line number of the calling function (${LINNO}) # # Usage: # log "info" "Could not find that directory" # # POSIX Compliant: # Yes # # Convert the level to uppercase local level level=$(echo "${1}" | tr '[:lower:]' '[:upper:]') shift local message message="${*}" case "${level}" in INFO) printf "%sINFO:%s %s%s%s\n" \ "${CYAN}" \ "${RESET}" \ "${BOLD}" \ "${message}" \ "${RESET}" >&2 return 0 ;; WARN*) printf "%sWARN:%s %s%s%s\n" \ "${YELLOW}" \ "${RESET}" \ "${BOLD}" \ "${message}" \ "${RESET}" >&2 return 0 ;; ERROR) printf "%sERROR:%s %s%s%s\n" \ "${RED}" \ "${RESET}" \ "${BOLD}" \ "${message}" \ "${RESET}" >&2 return 0 ;; # Further log levels can be added by extending this switch statement with more comparisons *) # Default case, no matches # Returns non-zero code as an improper log option was passed, this helps with using `set -e` log "ERROR" "Invalid log level passed, received level \"${level}\" with message \"${message}\"" return 1 ;; esac } print-break() { printf "${GREEN}%.s─${RESET}" $(seq 1 "$(tput cols)") } log "${@}" install-fzf() { local install_path="$/fzf" git clone --depth 1 https://github.com/junegunn/fzf.git "${install_path}" "${install_path}/install" \ --key-bindings \ --completion \ --no-update-rc \ --xdg >/dev/null } install-rust() { local install_path="${1}" export CARGO_HOME="${install_path}/cargo" export RUSTUP_HOME="${install_path}/rustup" curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --quiet export PATH="${PATH}:${install_path}/cargo/bin" } install-cargo-binary() { local binary="${1}" cargo install "${binary}" } check-script-deps() { local commands_to_check=( git gcc ) local ret_code=0 for cmd in "${commands_to_check[@]}"; do if ! command -v "${cmd}"; then log "warning" "Could not find command: ${GREEN}${cmd}${RESET}" ret_code=1 fi done return "${ret_code}" } main() { log "info" "Dependencies directory set to ${GREEN}${DEPS_PATH}${RESET}" mkdir -p "${DEPS_PATH}" print-break log "info" "Checking script dependencies..." if ! check-script-deps; then log "error" "Script dependencies failed, install missing dependencies and try again\n" fi log "info" "Script dependencies good" print-break log "info" "Installing ${GREEN}FZF${RESET}" if ! install-fzf "${DEPS_PATH}"; then log "error" "Failed to install ${GREEN}FZF${RESET}" exit 1 fi log "info" "Successfully installed ${GREEN}FZF${RESET}" print-break log "info" "Installing Rust" if ! install-rust "${DEPS_PATH}"; then log "error" "Failed to install ${GREEN}Rust${RESET}" exit 1 fi log "info" "Successfully installed ${GREEN}Rust${RESET}" print-break log "info" "Installing Cargo programs" local cargo_binaries=( ripgrep exa ) for pkg in "${cargo_binaries[@]}"; do log "info" "Installing ${GREEN}${pkg}${RESET}" if ! install-cargo-binary "${pkg}"; then log "error" "Failed installation of ${GREEN}${pkg}${RESET}" exit 1 fi done log "info" "Finished installing Cargo programs" } main