#!/usr/bin/env bash repos="$HOME/.homesick/repos" # Include all helper functions. We will include the required command function later on. homeshick=${HOMESHICK_DIR:-$HOME/.homesick/repos/homeshick} # On travis-ci exit_status for some reason errors out, ignore it # shellcheck disable=SC1090 source "$homeshick/lib/exit_status.sh" # shellcheck source=lib/fs.sh source "$homeshick/lib/fs.sh" # shellcheck source=lib/git.sh source "$homeshick/lib/git.sh" # shellcheck source=lib/log.sh source "$homeshick/lib/log.sh" # shellcheck source=lib/prompt.sh source "$homeshick/lib/prompt.sh" # lots of global variables in here, so just disable SC2034 for the entire file # shellcheck disable=SC2034 true exit_status=$EX_SUCCESS type git &>/dev/null || err "$EX_SOFTWARE" "git not found in path" if [[ ! -d $repos ]]; then mkdir -p "$repos" fi # used in pull.sh # shellcheck disable=SC2034 T_START=$(date +%s) if [[ -z $GIT_VERSION ]]; then read -r _ _ GIT_VERSION _ < <(command git --version) if [[ ! $GIT_VERSION =~ ([0-9]+)(\.[0-9]+){0,3} ]]; then err "$EX_SOFTWARE" "could not determine git version" fi fi TALK=true SKIP=false FORCE=false BATCH=false VERBOSE=false # Retrieve all the flags preceeding a subcommand while [[ $# -gt 0 ]]; do if [[ $1 =~ ^- ]]; then # Convert combined short options into multiples short options (e.g. `-qb' to `-q -b') if [[ $1 =~ ^-[a-z]{2,} ]]; then param=$1 shift set -- "${param:0:2}" "-${param:2}" "$@" unset param fi case $1 in -h | --help) cmd="help" ; shift; continue ;; -q | --quiet) TALK=false ; shift; continue ;; -s | --skip) SKIP=true ; shift; continue ;; -f | --force) FORCE=true ; shift; continue ;; -b | --batch) BATCH=true ; shift; continue ;; -v | --verbose) VERBOSE=true ; shift; continue ;; *) err "$EX_USAGE" "Unknown option '$1'" ;; esac else break fi done [[ $# -gt 0 ]] || cmd="help" # Get the subcommand valid_commands=(cd clone generate list check updates refresh pull symlink link track help) if [[ ! $cmd ]]; then # We actually want literal matching of the rhs here, $1 shouldn't be a regexp # shellcheck disable=SC2076 if [[ " ${valid_commands[*]} " =~ " $1 " ]]; then cmd=$1 shift fi if [[ ! $cmd ]]; then err "$EX_USAGE" "Unknown command '$1'" fi fi # Get the arguments for the subcommand, also parse flags if there are any left while [[ $# -gt 0 ]]; do if [[ $1 =~ ^- ]]; then # Convert combined short options into multiples short options (e.g. `-qb' to `-q -b') if [[ $1 =~ ^-[a-z]{2,} ]]; then param=$1 shift set -- "${param:0:2}" "-${param:2}" "$@" unset param fi case $1 in -h | --help) cmd="help" shift; continue ;; -q | --quiet) TALK=false shift; continue ;; -s | --skip) SKIP=true shift; continue ;; -f | --force) FORCE=true shift; continue ;; -b | --batch) BATCH=true shift; continue ;; -v | --verbose) VERBOSE=true shift; continue ;; *) err "$EX_USAGE" "Unknown option '$1'" ;; esac fi case $cmd in cd | clone | generate | check | updates | pull | symlink | link) params+=("$1") shift; continue ;; refresh) [[ ! $threshhold ]] && threshhold=$(($1*86400)) || params+=("$1") shift; continue ;; track) [[ ! $castle ]] && castle=$1 || params+=("$1") shift; continue ;; list) err "$EX_USAGE" "The 'list' command does not take any arguments" ;; help) [[ ! $help_cmd ]] && help_cmd=$1 shift; continue;; *) err "$EX_USAGE" "Unknown command '$1'" ;; esac done # If no additional arguments are given, run the subcommand for every castle if [[ ${#params[@]} -eq 0 ]]; then case $cmd in check | updates | refresh | pull | symlink | link) while IFS= read -d $'\n' -r name ; do params+=("$name") done < <(list_castle_names) ;; # These commands require parameters, show the help message instead cd | clone | generate | track) help_cmd=$cmd; cmd="help"; exit_status=$EX_USAGE ;; esac fi # Default param for refresh is 7 [[ ! $threshhold ]] && threshhold=$((7*86400)) # Include the file that implements the invoked command case $cmd in cd) ;; symlink) # shellcheck source=lib/commands/link.sh source "$homeshick/lib/commands/link.sh" ;; updates) # shellcheck source=lib/commands/check.sh source "$homeshick/lib/commands/check.sh" ;; *) # Don't know what will be included, so just disable the rule # shellcheck disable=SC1090 source "$homeshick/lib/commands/$cmd.sh" ;; esac case $cmd in list) list ;; cd) help cd ;; # cd is implemented in the homeshick.{sh,csh} helper script. help) help $help_cmd ;; *) for param in "${params[@]}"; do case $cmd in clone) clone "$param" ;; generate) generate "$param" ;; check|updates) (check "$param") ;; refresh) (refresh $threshhold "$param") ;; pull) (pull "$param") ;; symlink|link) symlink "$param" ;; track) track "$castle" "$param" ;; esac result=$? if [[ $result == "$EX_USAGE" ]]; then exit "$EX_USAGE" fi if [[ $exit_status == 0 && $result != 0 ]]; then exit_status=$result fi done case $cmd in clone) symlink_cloned_files "${params[@]}" ;; refresh) pull_outdated $threshhold "${params[@]}" ;; pull) symlink_new_files "${params[@]}" ;; esac result=$? if [[ $exit_status == 0 && $result != 0 ]]; then exit_status=$result fi ;; esac exit $exit_status