#!/usr/bin/env bash # This script was generated by bashly 1.2.0 (https://bashly.dannyb.co) # Modifying it manually is not recommended # :wrapper.bash3_bouncer if [[ "${BASH_VERSINFO:-0}" -lt 4 ]]; then printf "bash version 4 or higher is required\n" >&2 exit 1 fi # :command.master_script # :command.version_command version_command() { echo "$version" } # :command.usage rush_usage() { printf "rush - Personal package manager.\n\n" printf "%s\n" "$(bold "Usage:")" printf " rush COMMAND\n" printf " rush [COMMAND] --help | -h\n" printf " rush --version | -v\n" echo # :command.usage_commands printf "%s\n" "$(bold "Repository Commands:")" printf " %s Register a local repository.\n" "add " printf " %s Unregister a local repository.\n" "remove " echo printf "%s\n" "$(bold "Git Commands:")" printf " %s Clone a GitHub package repository.\n" "clone " printf " %s Git pull one or all repositories.\n" "pull " printf " %s Git push one or all repositories.\n" "push " echo printf "%s\n" "$(bold "Config Commands:")" printf " %s Show or edit the configuration file.\n" "config " printf " %s Set a default repository.\n" "default " echo printf "%s\n" "$(bold "Package Commands:")" printf " %s Install a package. (default)\n" "get " printf " %s Uninstall a package.\n" "undo " printf " %s Install a package from a remote repo.\n" "snatch " printf " %s Copy a package between local repositories.\n" "copy " printf " %s Show information about a package.\n" "info " printf " %s Show packages in one or all repositories.\n" "list " printf " %s Search in package names and info files.\n" "search " printf " %s Edit package files.\n" "edit " printf " %s Show package files.\n" "show " echo printf "%s\n" "$(bold "Internal Commands:")" printf " %s Generate bash completions.\n" "completions" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo printf " %s\n" "--version, -v" printf " Show version number\n" echo # :command.usage_environment_variables printf "%s\n" "$(bold "Environment Variables:")" # :environment_variable.usage printf " %s\n" "RUSH_CONFIG" printf " Location of the rush config file.\n \n Default: ~/rush.ini\n" echo # :environment_variable.usage printf " %s\n" "RUSH_ROOT" printf " Location of the default base directory for cloning repositories.\n \n Default: ~/rush-repos\n" echo fi } # :command.usage rush_add_usage() { if [[ -n $long_usage ]]; then printf "rush add\n\n" printf " Register a local repository.\n \n This command adds the specified path to the configuration file.\n\n" else printf "rush add - Register a local repository.\n\n" fi printf "Alias: a\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush add REPO PATH\n" printf " rush add --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "REPO" printf " Repository name.\n" echo # :argument.usage printf " %s\n" "PATH" printf " Path to the repository.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush add default ~/rush-repos/default\n" echo fi } # :command.usage rush_remove_usage() { if [[ -n $long_usage ]]; then printf "rush remove\n\n" printf " Unregister a local repository.\n \n This command removes the specified path to the configuration file.\n\n" else printf "rush remove - Unregister a local repository.\n\n" fi printf "Alias: r\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush remove REPO [OPTIONS]\n" printf " rush remove --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--purge, -p" printf " Also remove the local repository's directory.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "REPO" printf " Repository name.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush remove bobby\n" printf " rush remove bobby --purge\n" echo fi } # :command.usage rush_clone_usage() { if [[ -n $long_usage ]]; then printf "rush clone\n\n" printf " Clone a GitHub package repository.\n \n This command clones the repository and registers it in the configuration file.\n\n" else printf "rush clone - Clone a GitHub package repository.\n\n" fi printf "%s\n" "$(bold "Usage:")" printf " rush clone GITHUB_USER [PATH] [OPTIONS]\n" printf " rush clone --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--ssh, -s" printf " Clone using SSH instead of HTTPS.\n" echo # :flag.usage printf " %s\n" "--default, -d" printf " Set this as the default repository (same as \`--name default\`).\n" echo # :flag.usage printf " %s\n" "--name, -n NAME" printf " Name to use in the config file.\n \n Default: GitHub user\n" echo # :flag.usage printf " %s\n" "--shallow, -w" printf " Perform a shallow clone, instead of the default full clone.\n" echo # :flag.usage printf " %s\n" "--ignore, -i" printf " Ignore (do not clone) if a repository with this name exists.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "GITHUB_USER" printf " Github user.\n \n This user is expected to have a repository named \`rush-repo\`.\n \n If you need to use a different name, use the \`user/repo\` syntax.\n" echo # :argument.usage printf " %s\n" "PATH" printf " Local path to clone the repository into.\n \n Default: ~/rush-repos//\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush clone bobby\n" printf " rush clone bobby --default\n" printf " rush clone bobby/bobs-repo ./repos/bobby --ssh\n" printf " rush clone bobby --name sample --ignore\n" echo fi } # :command.usage rush_pull_usage() { printf "rush pull - Git pull one or all repositories.\n\n" printf "Alias: p, download, update\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush pull [REPO]\n" printf " rush pull --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "REPO" printf " Repository name.\n" echo fi } # :command.usage rush_push_usage() { printf "rush push - Git push one or all repositories.\n\n" printf "Alias: upload\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush push [REPO] [OPTIONS]\n" printf " rush push --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--all, -a" printf " Push all repositories.\n" echo # :flag.usage printf " %s\n" "--message, -m TEXT" printf " Commit message.\n" printf " Default: automatic commit\n" echo # :flag.usage printf " %s\n" "--chmod, -x" printf " Apply the executable bit to all main and undo scripts in the git repository\n index.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "REPO" printf " Repository name.\n" printf " Default: default\n" echo fi } # :command.usage rush_config_usage() { printf "rush config - Show or edit the configuration file.\n\n" printf "Alias: c\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush config [OPTIONS]\n" printf " rush config --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--edit, -e" printf " Open the configuration file for editing.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo fi } # :command.usage rush_default_usage() { if [[ -n $long_usage ]]; then printf "rush default\n\n" printf " Set a default repository.\n \n This command adds (or updates) a repository named \`default\` to the\n configuration file, and copies the path from the provided repo.\n\n" else printf "rush default - Set a default repository.\n\n" fi printf "%s\n" "$(bold "Usage:")" printf " rush default REPO\n" printf " rush default --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "REPO" printf " Repository name.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush default sample\n" echo fi } # :command.usage rush_get_usage() { if [[ -n $long_usage ]]; then printf "rush get\n\n" printf " Install a package.\n \n This command runs the main script in the package directory.\n \n This is the default command, which means that running \`rush package\` is the\n same as running \`rush get package\`.\n\n" else printf "rush get - Install a package.\n\n" fi printf "Alias: g\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush [get] PACKAGE [OPTIONS]\n" printf " rush get --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--clone, -c" printf " Clone the repository if it is not found locally.\n \n This flag will look for a GitHub user with the same name as the repository,\n and attempt to clone their rush-repo repository.\n" echo # :flag.usage printf " %s\n" "--force, -f" printf " Force installation.\n \n This may mean different things in different packages.\n" echo # :flag.usage printf " %s\n" "--verbose, -v" printf " Show additional details if possible.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "PACKAGE" printf " Package name.\n \n This can either be the package name without the repository name (in this\n case, the default repository will be used) or in the form of \`repo:package\`.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush ruby\n" printf " rush get ruby --force\n" printf " rush get centos:ruby\n" echo fi } # :command.usage rush_undo_usage() { if [[ -n $long_usage ]]; then printf "rush undo\n\n" printf " Uninstall a package.\n \n This command runs the undo script in the package directory.\n\n" else printf "rush undo - Uninstall a package.\n\n" fi printf "Alias: u\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush undo PACKAGE [OPTIONS]\n" printf " rush undo --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--verbose, -v" printf " Show additional details if possible.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "PACKAGE" printf " Package name.\n \n This can either be the package name without the repository name (in this\n case, the default repository will be used) or in the form of \`repo:package\`.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush undo ruby\n" printf " rush undo centos:ruby\n" echo fi } # :command.usage rush_snatch_usage() { if [[ -n $long_usage ]]; then printf "rush snatch\n\n" printf " Install a package from a remote repo.\n \n This command is a shortcut to running clone followed by get.\n \n It will clone the repository to a temporary directory and run the main package\n script.\n\n" else printf "rush snatch - Install a package from a remote repo.\n\n" fi printf "%s\n" "$(bold "Usage:")" printf " rush snatch GITHUB_USER PACKAGE [OPTIONS]\n" printf " rush snatch --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--force, -f" printf " Force installation.\n \n This may mean different things in different packages.\n" echo # :flag.usage printf " %s\n" "--verbose, -v" printf " Show additional details if possible.\n" echo # :flag.usage printf " %s\n" "--undo, -u" printf " Run the undo script instead of the main script.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "GITHUB_USER" printf " Github user.\n \n This user is expected to have a repository named \`rush-repo\`.\n \n If you need to use a different name, use the \`user/repo\` syntax.\n" echo # :argument.usage printf " %s\n" "PACKAGE" printf " Package name.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush snatch james python\n" printf " rush snatch james python --undo\n" printf " rush snatch james/other-rush-repo python\n" echo fi } # :command.usage rush_copy_usage() { printf "rush copy - Copy a package between local repositories.\n\n" printf "%s\n" "$(bold "Usage:")" printf " rush copy SOURCE_PACKAGE [TARGET_PACKAGE] [OPTIONS]\n" printf " rush copy --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--force, -f" printf " Copy the package even if it already exists in the target repository.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "SOURCE_PACKAGE" printf " Source package name.\n \n This can either be the package name without the repository name (in this\n case, the default repository will be used) or in the form of \`repo:package\`.\n" echo # :argument.usage printf " %s\n" "TARGET_PACKAGE" printf " Target package name.\n \n This can either be the package name without the repository name (in this\n case, the default repository will be used) or in the form of \`repo:package\`.\n \n If left empty, the package will be copied with the same name to the default\n repository.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush copy james:python\n" printf " rush copy james:python python3\n" printf " rush copy james:python bobby:python3 --force\n" echo fi } # :command.usage rush_info_usage() { if [[ -n $long_usage ]]; then printf "rush info\n\n" printf " Show information about a package.\n \n This command shows the info file from the package directory.\n\n" else printf "rush info - Show information about a package.\n\n" fi printf "Alias: i\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush info PACKAGE\n" printf " rush info --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "PACKAGE" printf " Package name.\n \n This can either be the package name without the repository name (in this\n case, the default repository will be used) or in the form of \`repo:package\`.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush info ruby\n" printf " rush info centos:ruby\n" echo fi } # :command.usage rush_list_usage() { printf "rush list - Show packages in one or all repositories.\n\n" printf "Alias: l, ls\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush list [REPO_OR_PACKAGE] [OPTIONS]\n" printf " rush list --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_flags # :flag.usage printf " %s\n" "--simple, -s" printf " Show only package names.\n" echo # :flag.usage printf " %s\n" "--all, -a" printf " Show nested packages as well.\n" echo # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "REPO_OR_PACKAGE" printf " Repository name or package name.\n \n Leave blank to show all packages in all repositories.\n \n Provide a repository name to show only packages in this repository.\n \n Provide a package name (may be in the form of \`repo:package\`) to show nested\n packages.\n" echo # :command.usage_examples printf "%s\n" "$(bold "Examples:")" printf " rush list\n" printf " rush list personal:apps\n" printf " rush list personal\n" printf " rush list apps\n" printf " rush list apps --simple --all\n" echo fi } # :command.usage rush_search_usage() { printf "rush search - Search in package names and info files.\n\n" printf "Alias: s\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush search TEXT\n" printf " rush search --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "TEXT" printf " Text to search for.\n" echo fi } # :command.usage rush_edit_usage() { printf "rush edit - Edit package files.\n\n" printf "Alias: e\n" echo printf "%s\n" "$(bold "Usage:")" printf " rush edit PACKAGE [FILE]\n" printf " rush edit --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "PACKAGE" printf " Package name.\n \n This can either be the package name without the repository name (in this\n case, the default repository will be used) or in the form of \`repo:package\`.\n" echo # :argument.usage printf " %s\n" "FILE" printf " File to edit.\n" printf " Default: main\n" echo fi } # :command.usage rush_show_usage() { printf "rush show - Show package files.\n\n" printf "%s\n" "$(bold "Usage:")" printf " rush show PACKAGE [FILE]\n" printf " rush show --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo # :command.usage_args printf "%s\n" "$(bold "Arguments:")" # :argument.usage printf " %s\n" "PACKAGE" printf " Package name.\n \n This can either be the package name without the repository name (in this\n case, the default repository will be used) or in the form of \`repo:package\`.\n" echo # :argument.usage printf " %s\n" "FILE" printf " File to show (show all if not specified).\n" echo fi } # :command.usage rush_completions_usage() { printf "rush completions - Generate bash completions.\n\n" printf "%s\n" "$(bold "Usage:")" printf " rush completions\n" printf " rush completions --help | -h\n" echo # :command.long_usage if [[ -n $long_usage ]]; then printf "%s\n" "$(bold "Options:")" # :command.usage_fixed_flags printf " %s\n" "--help, -h" printf " Show this help\n" echo fi } # :command.normalize_input # :command.normalize_input_function normalize_input() { local arg flags passthru passthru=false while [[ $# -gt 0 ]]; do arg="$1" if [[ $passthru == true ]]; then input+=("$arg") elif [[ $arg =~ ^(--[a-zA-Z0-9_\-]+)=(.+)$ ]]; then input+=("${BASH_REMATCH[1]}") input+=("${BASH_REMATCH[2]}") elif [[ $arg =~ ^(-[a-zA-Z0-9])=(.+)$ ]]; then input+=("${BASH_REMATCH[1]}") input+=("${BASH_REMATCH[2]}") elif [[ $arg =~ ^-([a-zA-Z0-9][a-zA-Z0-9]+)$ ]]; then flags="${BASH_REMATCH[1]}" for ((i = 0; i < ${#flags}; i++)); do input+=("-${flags:i:1}") done elif [[ "$arg" == "--" ]]; then passthru=true input+=("$arg") else input+=("$arg") fi shift done } # :command.inspect_args inspect_args() { if ((${#args[@]})); then readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort) echo args: for k in "${sorted_keys[@]}"; do echo "- \${args[$k]} = ${args[$k]}" done else echo args: none fi if ((${#other_args[@]})); then echo echo other_args: echo "- \${other_args[*]} = ${other_args[*]}" for i in "${!other_args[@]}"; do echo "- \${other_args[$i]} = ${other_args[$i]}" done fi if ((${#deps[@]})); then readarray -t sorted_keys < <(printf '%s\n' "${!deps[@]}" | sort) echo echo deps: for k in "${sorted_keys[@]}"; do echo "- \${deps[$k]} = ${deps[$k]}" done fi if ((${#env_var_names[@]})); then readarray -t sorted_names < <(printf '%s\n' "${env_var_names[@]}" | sort) echo echo "environment variables:" for k in "${sorted_names[@]}"; do echo "- \$$k = ${!k:-}" done fi } # :command.user_lib # src/lib/abort.sh abort() { red "$1" exit 1 } # src/lib/colors.sh print_in_color() { local color="$1" shift if [[ -z ${NO_COLOR+x} ]]; then printf "$color%b\e[0m\n" "$*" else printf "%b\n" "$*" fi } red() { print_in_color "\e[31m" "$*"; } green() { print_in_color "\e[32m" "$*"; } yellow() { print_in_color "\e[33m" "$*"; } blue() { print_in_color "\e[34m" "$*"; } magenta() { print_in_color "\e[35m" "$*"; } cyan() { print_in_color "\e[36m" "$*"; } bold() { print_in_color "\e[1m" "$*"; } underlined() { print_in_color "\e[4m" "$*"; } red_bold() { print_in_color "\e[1;31m" "$*"; } green_bold() { print_in_color "\e[1;32m" "$*"; } yellow_bold() { print_in_color "\e[1;33m" "$*"; } blue_bold() { print_in_color "\e[1;34m" "$*"; } magenta_bold() { print_in_color "\e[1;35m" "$*"; } cyan_bold() { print_in_color "\e[1;36m" "$*"; } red_underlined() { print_in_color "\e[4;31m" "$*"; } green_underlined() { print_in_color "\e[4;32m" "$*"; } yellow_underlined() { print_in_color "\e[4;33m" "$*"; } blue_underlined() { print_in_color "\e[4;34m" "$*"; } magenta_underlined() { print_in_color "\e[4;35m" "$*"; } cyan_underlined() { print_in_color "\e[4;36m" "$*"; } # src/lib/config.sh config_show() { config_load ini_show } config_get() { local key="${1-}" local default_value="${2-}" config_load echo "${ini["$key"]:-$default_value}" } config_set() { local key="${1-}" shift local value="$*" config_load ini["$key"]="$value" config_save } config_del() { local key="${1-}" config_load unset "ini[$key]" config_save } config_keys() { config_load ini_keys } config_has_key() { [[ $(config_get "$1") ]] } config_reload() { declare -g config_loaded=false config_load } config_load() { [[ "${config_loaded-}" == "true" ]] && return declare -g CONFIG_FILE=${CONFIG_FILE:=config.ini} declare -g config_loaded=true [[ -f "$CONFIG_FILE" ]] || touch "$CONFIG_FILE" ini_load "$CONFIG_FILE" } config_save() { ini_save "$CONFIG_FILE" } # src/lib/ini.sh ini_load() { declare -gA ini local ini_file="$1" local section="" local key="" local value="" local section_regex="^\[(.+)\]" local key_regex="^([^ =]+) *= *(.*) *$" local comment_regex="^;" while IFS= read -r line; do if [[ $line =~ $comment_regex ]]; then continue elif [[ $line =~ $section_regex ]]; then section="${BASH_REMATCH[1]}." elif [[ $line =~ $key_regex ]]; then key="${BASH_REMATCH[1]}" value="${BASH_REMATCH[2]}" [[ $value == *\$* ]] && eval "value=\"$value\"" ini["${section}${key}"]="$value" fi done <"$ini_file" } ini_save() { declare -gA ini local ini_file="$1" local current_section="" local has_free_keys=false rm -f "$ini_file" for key in $(ini_keys); do [[ $key == *.* ]] && continue has_free_keys=true value="${ini[$key]}" echo "$key = $value" >>"$ini_file" done [[ "${has_free_keys}" == "true" ]] && echo >>"$ini_file" for key in $(ini_keys); do [[ $key == *.* ]] || continue value="${ini[$key]}" IFS="." read -r section_name key_name <<<"$key" if [[ "$current_section" != "$section_name" ]]; then [[ $current_section ]] && echo >>"$ini_file" echo "[$section_name]" >>"$ini_file" current_section="$section_name" fi echo "$key_name = $value" >>"$ini_file" done } ini_show() { declare -gA ini for key in $(ini_keys); do echo "$key = ${ini[$key]}" done } ini_keys() { declare -gA ini local keys=("${!ini[@]}") for a in "${keys[@]}"; do echo "$a"; done | sort } # src/lib/is_busybox_grep.sh is_busybox_grep() { grep --version 2>&1 | grep -i busybox >/dev/null 2>&1 } # src/lib/say.sh say() { printf "%-20s | %s\n" "$(magenta "$1")" "$(bold "${*:2}")" } # src/lib/send_completions.sh send_completions() { echo $'# rush completion -*- shell-script -*-' echo $'' echo $'# This bash completions script was generated by' echo $'# completely (https://github.com/dannyben/completely)' echo $'# Modifying it manually is not recommended' echo $'' echo $'_rush_completions_filter() {' echo $' local words="$1"' echo $' local cur=${COMP_WORDS[COMP_CWORD]}' echo $' local result=()' echo $'' echo $' if [[ "${cur:0:1}" == "-" ]]; then' echo $' echo "$words"' echo $'' echo $' else' echo $' for word in $words; do' echo $' [[ "${word:0:1}" != "-" ]] && result+=("$word")' echo $' done' echo $'' echo $' echo "${result[*]}"' echo $'' echo $' fi' echo $'}' echo $'' echo $'_rush_completions() {' echo $' local cur=${COMP_WORDS[COMP_CWORD]}' echo $' local compwords=("${COMP_WORDS[@]:1:$COMP_CWORD-1}")' echo $' local compline="${compwords[*]}"' echo $'' echo $' case "$compline" in' echo $' \'completions\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'download\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'default\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'snatch\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--force --help --undo --verbose -f -h -u -v")" -- "$cur")' echo $' ;;' echo $'' echo $' \'search\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'config\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--edit --help -e -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'upload\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--all --chmod --help --message -a -h -m -x")" -- "$cur")' echo $' ;;' echo $'' echo $' \'update\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'remove\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help --purge -h -p")" -- "$cur")' echo $' ;;' echo $'' echo $' \'clone\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -A directory -W "$(_rush_completions_filter "--default --help --ignore --name --shallow --ssh -d -h -i -n -s -w")" -- "$cur")' echo $' ;;' echo $'' echo $' \'edit\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'pull\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'push\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--all --chmod --help --message -a -h -m -x")" -- "$cur")' echo $' ;;' echo $'' echo $' \'show\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'undo\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --help --verbose -h -v")" -- "$cur")' echo $' ;;' echo $'' echo $' \'copy\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --force --help -f -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'info\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'list\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--all --help --simple -a -h -s")" -- "$cur")' echo $' ;;' echo $'' echo $' \'get\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --clone --force --help --verbose -c -f -h -v")" -- "$cur")' echo $' ;;' echo $'' echo $' \'add\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -A directory -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'ls\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--all --help --simple -a -h -s")" -- "$cur")' echo $' ;;' echo $'' echo $' \'e\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'s\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'l\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--all --help --simple -a -h -s")" -- "$cur")' echo $' ;;' echo $'' echo $' \'i\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'u\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --help --verbose -h -v")" -- "$cur")' echo $' ;;' echo $'' echo $' \'g\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --clone --force --help --verbose -c -f -h -v")" -- "$cur")' echo $' ;;' echo $'' echo $' \'c\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--edit --help -e -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'p\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' \'r\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "--help --purge -h -p")" -- "$cur")' echo $' ;;' echo $'' echo $' \'a\'*)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -A directory -W "$(_rush_completions_filter "--help -h")" -- "$cur")' echo $' ;;' echo $'' echo $' *)' echo $' while read -r; do COMPREPLY+=("$REPLY"); done < <(compgen -W "$(_rush_completions_filter "$(rush list -s -a) --help --version -h -v a add c clone completions config copy default download e edit g get i info l list ls p pull push r remove s search show snatch u undo update upload")" -- "$cur")' echo $' ;;' echo $'' echo $' esac' echo $'} &&' echo $' complete -F _rush_completions rush' echo $'' echo $'# ex: filetype=sh' } # src/lib/warn.sh warn() { printf "%-20s | %s\n" "$(red "$1")" "$(red_bold "${*:2}")" } # :command.command_functions # :command.function rush_add_command() { # src/add_command.sh repo=${args[repo]} path=${args[path]} config_set "$repo" "$path" say "add" "$repo = $path" } # :command.function rush_remove_command() { # src/remove_command.sh repo=${args[repo]} purge=${args[--purge]} say "remove" "$repo" if [[ $purge ]]; then repo_path=$(config_get "$repo") if [[ -d $repo_path ]]; then rm -rf "$repo_path" say "remove" "purged $repo_path" fi fi config_del "$repo" } # :command.function rush_clone_command() { # src/clone_command.sh path=${args[path]} repo_id=${args[github_user]} use_ssh=${args[--ssh]} shallow=${args[--shallow]} ignore=${args[--ignore]} default_repo_name=${repo_id%%/*} default=${args[--default]} if [[ $default ]]; then repo_name=default else repo_name=${args[--name]:-$default_repo_name} fi [[ $repo_id = */* ]] || repo_id="$repo_id/rush-repo" if [[ $use_ssh ]]; then repo_url=git@github.com:$repo_id.git else repo_url=https://github.com/$repo_id.git fi [[ $path ]] || path="$RUSH_ROOT/$repo_id" if [[ -d $path ]]; then if [[ $ignore ]]; then skip=1 else abort "directory $path already exists." fi fi if config_has_key "$repo_name"; then if [[ $ignore ]]; then skip=1 else abort "the repository is already registered:\n$repo_name = $(config_get "$repo_name")." fi fi if [[ $skip ]]; then say "clone" "skipping $repo_name (exists)" else say "clone" "$repo_url" if [[ $shallow ]]; then git clone --depth 1 "$repo_url" "$path" else git clone "$repo_url" "$path" fi config_set "$repo_name" "$path" fi } # :command.function rush_pull_command() { # src/pull_command.sh repo=${args[repo]} pull_repo() { local repo_path="$1" local repo="$2" if [[ -d "$repo_path/.git" ]]; then say "pull" "$repo" (cd "$repo_path" && git pull) else say "pull" "skipping $repo (not a git repo)" fi } if [[ $repo ]]; then repo_path=$(config_get "$repo") [[ $repo_path ]] || abort "no such repo: $repo" pull_repo "$repo_path" "$repo" else for k in $(config_keys); do pull_repo "$(config_get "$k")" "$k" done fi } # :command.function rush_push_command() { # src/push_command.sh set +e all=${args[--all]} repo=${args[repo]:-default} message=${args[--message]:-"automatic commit"} push_repo() { local repo_path="$1" local repo="$2" if [[ -d "$repo_path/.git" ]]; then say "push" "$repo" ( set -e cd "$repo_path" say "push" "$repo: adding files" git add . --all if [[ -n "${args[--chmod]}" ]]; then say "push" "$repo: applying chmod +x" git ls-files | grep -E "undo|main" | xargs -I {} git update-index --chmod +x {} fi say "push" "$repo: committing" git commit -am "$message" say "push" "$repo: pushing" git push ) else say "push" "$repo: skipping (not a git repo)" fi } if [[ $all ]]; then for k in $(config_keys); do push_repo "$(config_get "$k")" "$k" done else repo_path=$(config_get "$repo") [[ $repo_path ]] || abort "no such repo: $repo" push_repo "$repo_path" "$repo" fi } # :command.function rush_config_command() { # src/config_command.sh if [[ "${args[--edit]}" ]]; then editor="${EDITOR:-vi}" "$editor" "$CONFIG_FILE" else cyan "# $CONFIG_FILE" config_show fi } # :command.function rush_default_command() { # src/default_command.sh repo=${args[repo]} repo_path=$(config_get "$repo") [[ $repo_path ]] || abort "repo not found: $repo" config_set "default" "$repo_path" config_del "$repo" say "default" "$repo ($repo_path)" } # :command.function rush_get_command() { # src/get_command.sh package=${args[package]} repo="default" clone=${args[--clone]} [[ -n "${args['--force']}" ]] && export FORCE=1 [[ -n "${args['--verbose']}" ]] && export VERBOSE=1 if [[ $package =~ (.*):(.*) ]]; then repo=${BASH_REMATCH[1]} package=${BASH_REMATCH[2]} fi if ! config_has_key "$repo" && [[ $clone ]] && [[ $repo != 'default' ]]; then say "get" "repo $repo does not exist, attempting clone" rush clone "$repo" fi repo_path=$(config_get "$repo") package_path=$repo_path/$package script=$package_path/main [[ $repo_path ]] || abort "repo not found: $repo" [[ -d $package_path ]] || abort "package not found: $repo:$package" [[ -f $script ]] || abort "script not found: $script" export REPO="$repo" export REPO_PATH="$repo_path" [[ -z "$USER_CWD" ]] && export USER_CWD="$PWD" if [[ $repo == "default" ]]; then package_name="$package" else package_name="$repo:$package" fi say "get" "$package_name" [[ -x "$script" ]] || chmod u+x "$script" cd "$package_path" finish() { exitcode="$?" [[ $exitcode == 0 ]] || warn "get" "$package_name exited with error ($exitcode)" } trap finish EXIT ./main } # :command.function rush_undo_command() { # src/undo_command.sh package=${args[package]} repo="default" [[ -n "${args['--verbose']}" ]] && export VERBOSE=1 if [[ $package =~ (.*):(.*) ]]; then repo=${BASH_REMATCH[1]} package=${BASH_REMATCH[2]} fi repo_path=$(config_get "$repo") package_path=$repo_path/$package script=$package_path/undo [[ $repo_path ]] || abort "repo not found: $repo" [[ -d $package_path ]] || abort "package not found: $repo:$package" [[ -f $script ]] || abort "script not found: $script" export REPO="$repo" export REPO_PATH="$repo_path" [[ -z "$USER_CWD" ]] && export USER_CWD="$PWD" if [[ $repo == "default" ]]; then package_name="$package" else package_name="$repo:$package" fi say "undo" "$package_name" [[ -x "$script" ]] || chmod u+x "$script" cd "$package_path" finish() { exitcode="$?" [[ $exitcode == 0 ]] || warn "undo" "$package_name exited with error ($exitcode)" } trap finish EXIT ./undo } # :command.function rush_snatch_command() { # src/snatch_command.sh repo_id=${args[github_user]} package=${args[package]} undo=${args[--undo]} tmpdir="$(mktemp -d -t rush-snatch.XXXXXX)" path="$tmpdir/snatched" [[ -n "${args['--force']}" ]] && export FORCE=1 [[ -n "${args['--verbose']}" ]] && export VERBOSE=1 cleanup() { rush remove snatched --purge rm -r "$tmpdir" } say "snatch" "$repo_id $package" trap cleanup EXIT ERR INT TERM rush clone "$repo_id" "$path" --name snatched if [[ $undo ]]; then rush undo "snatched:$package" else rush get "snatched:$package" fi } # :command.function rush_copy_command() { # src/copy_command.sh source_package=${args[source_package]} target_package=${args[target_package]} force=${args[--force]} source_repo=default target_repo=default if [[ $source_package =~ (.*):(.*) ]]; then source_repo=${BASH_REMATCH[1]} source_package=${BASH_REMATCH[2]} fi if [[ -z "$target_package" ]]; then target_package="$source_package" elif [[ $target_package =~ (.*):(.*) ]]; then target_repo=${BASH_REMATCH[1]} target_package=${BASH_REMATCH[2]} fi source_repo_path=$(config_get "$source_repo") target_repo_path=$(config_get "$target_repo") source_package_path="$source_repo_path/$source_package" target_package_path="$target_repo_path/$target_package" if [[ $source_repo == "default" ]]; then source_display_name="$source_package" else source_display_name="$source_repo:$source_package" fi if [[ $target_repo == "default" ]]; then target_display_name="$target_package" else target_display_name="$target_repo:$target_package" fi [[ $source_repo_path ]] || abort "source repo not found: $source_repo" [[ $target_repo_path ]] || abort "target repo not found: $target_repo" [[ -d $source_package_path ]] || abort "source package not found: $source_repo:$source_package" if [[ -d $target_package_path ]]; then if [[ $force ]]; then rm -rf "$target_package_path" else abort "target package already exists: $target_repo:$target_package\nrun again with --force to copy anyway" fi fi say "copy" "$source_display_name to $target_display_name" mkdir -p "$(dirname "$target_package_path")" cp -R "$source_package_path" "$target_package_path" } # :command.function rush_info_command() { # src/info_command.sh package=${args[package]} repo="default" if [[ $package =~ (.*):(.*) ]]; then repo=${BASH_REMATCH[1]} package=${BASH_REMATCH[2]} fi repo_path=$(config_get "$repo") package_path="$repo_path/$package" infofile="$package_path/info" [[ $repo_path ]] || abort "repo not found: $repo" [[ -d $package_path ]] || abort "package not found: $repo:$package" [[ -f $infofile ]] || abort "infofile not found: $infofile" cat "$infofile" } # :command.function rush_list_command() { # src/list_command.sh list_display_item() { package="$1" infofile="$2" repo="$3" simple=${args[--simple]} width=$((${COLUMNS:-80} + 9)) [[ "$repo" != "default" ]] && package="$repo:$package" if [[ $simple ]]; then printf "%s\n" "$package" else info=$(head -1 "$infofile" 2>/dev/null) padded_package=$(printf "%-20s" "$package") message="$(green "$padded_package") $info" printf "%.${width}s\n" "$message" fi } list_show_repo() { local repo_or_package="$1" local search="${args[--search]}" local simple=${args[--simple]} local all=${args[--all]} local repo="$repo_or_package" local package glob repo_path infofile regex package_name if [[ $repo_or_package =~ (.*):(.*) ]]; then repo=${BASH_REMATCH[1]} package=${BASH_REMATCH[2]} fi repo_path=$(config_get "$repo") if [[ ! $repo_path ]]; then package="$repo" repo="default" repo_path=$(config_get "$repo") fi if [[ $package ]]; then glob=("$repo_path"/"$package"/**/info) else if [[ $all ]]; then glob_files=$(find "$repo_path" -type f -name 'info' | sort) else glob_files=$(find "$repo_path" -maxdepth 2 -type f -name 'info' | sort) fi readarray -t glob < <(echo "${glob_files[@]}") fi if [[ ${glob[0]} =~ .*\*.* ]]; then infofile="$repo_path/$package/info" if [[ -f "$infofile" ]]; then list_display_item "$package" "$infofile" "$repo" elif [[ ! $simple ]]; then red "nothing in $repo repo" fi else for infofile in "${glob[@]}"; do if [[ $search ]]; then regex="$repo_path/(.*${search}.*)/info" else regex="$repo_path/(.*)/info" fi if [[ $infofile =~ $regex ]]; then package_name="${BASH_REMATCH[1]}" list_display_item "$package_name" "$infofile" "$repo" fi done fi } repo_or_package=${args[repo_or_package]} if [[ $repo_or_package ]]; then list_show_repo "$repo_or_package" else for k in $(config_keys); do list_show_repo "$k" done fi } # :command.function rush_search_command() { # src/search_command.sh search_repo() { repo="$1" text="$2" set +e repo_path=$(config_get "$repo") prefix='' [[ "$repo" != "default" ]] && prefix="$repo:" blue "Matching packages:\n" find "$repo_path" -type d -not -path '*/\.*' | grep --color=always "$text" | sed "s#${repo_path}/#${prefix}#g" | sed 's#/info##' blue "\nMatching info files:\n" grep --color=always --initial-tab --recursive --ignore-case --include "info" \ "$text" "$repo_path" | sort | sed "s#${repo_path}/#${prefix}#g" | sed 's#/info##' echo } if is_busybox_grep; then abort "cannot run with BusyBox grep.\nplease install GNU grep:\napk add --no-cache grep" fi text=${args[text]} for k in $(config_keys); do search_repo "$k" "$text" done } # :command.function rush_edit_command() { # src/edit_command.sh package=${args[package]} file=${args[file]:-main} repo="default" edit=${EDITOR:-vi} if [[ $package =~ (.*):(.*) ]]; then repo=${BASH_REMATCH[1]} package=${BASH_REMATCH[2]} fi repo_path=$(config_get "$repo") package_path="$repo_path/$package" file_path="$package_path/$file" [[ $repo_path ]] || abort "repo not found: $repo" [[ -d $package_path ]] || abort "package not found: $repo:$package" [[ -f $file_path ]] || abort "file not found: $file_path" "$edit" "$file_path" } # :command.function rush_show_command() { # src/show_command.sh package=${args[package]} file=${args[file]} repo="default" if [[ $package =~ (.*):(.*) ]]; then repo=${BASH_REMATCH[1]} package=${BASH_REMATCH[2]} fi repo_path=$(config_get "$repo") package_path="$repo_path/$package" file_path="$package_path/$file" [[ $repo_path ]] || abort "repo not found: $repo" [[ -d $package_path ]] || abort "package not found: $repo:$package" if [[ $file ]]; then [[ -f $file_path ]] || abort "file not found: $file_path" cat "$file_path" else shopt -s dotglob for f in "$package_path"/*; do if [[ -f "$f" ]]; then green "$(basename "$f")" cat "$f" echo echo fi done shopt -u dotglob fi } # :command.function rush_completions_command() { # src/completions_command.sh send_completions } # :command.parse_requirements parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --version | -v) version_command exit ;; --help | -h) long_usage=yes rush_usage exit ;; *) break ;; esac done # :command.environment_variables_filter env_var_names+=("RUSH_CONFIG") env_var_names+=("RUSH_ROOT") # :command.command_filter action=${1:-} case $action in -*) ;; add | a) action="add" shift rush_add_parse_requirements "$@" shift $# ;; remove | r) action="remove" shift rush_remove_parse_requirements "$@" shift $# ;; clone) action="clone" shift rush_clone_parse_requirements "$@" shift $# ;; pull | p | download | update) action="pull" shift rush_pull_parse_requirements "$@" shift $# ;; push | upload) action="push" shift rush_push_parse_requirements "$@" shift $# ;; config | c) action="config" shift rush_config_parse_requirements "$@" shift $# ;; default) action="default" shift rush_default_parse_requirements "$@" shift $# ;; get | g) action="get" shift rush_get_parse_requirements "$@" shift $# ;; undo | u) action="undo" shift rush_undo_parse_requirements "$@" shift $# ;; snatch) action="snatch" shift rush_snatch_parse_requirements "$@" shift $# ;; copy) action="copy" shift rush_copy_parse_requirements "$@" shift $# ;; info | i) action="info" shift rush_info_parse_requirements "$@" shift $# ;; list | l | ls) action="list" shift rush_list_parse_requirements "$@" shift $# ;; search | s) action="search" shift rush_search_parse_requirements "$@" shift $# ;; edit | e) action="edit" shift rush_edit_parse_requirements "$@" shift $# ;; show) action="show" shift rush_show_parse_requirements "$@" shift $# ;; completions) action="completions" shift rush_completions_parse_requirements "$@" shift $# ;; # :command.command_fallback "") rush_usage >&2 exit 1 ;; *) action="get" rush_get_parse_requirements "$@" shift $# ;; esac # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple printf "invalid argument: %s\n" "$key" >&2 exit 1 ;; esac done } # :command.parse_requirements rush_add_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_add_usage exit ;; *) break ;; esac done # :command.command_filter action="add" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['repo']+x} ]]; then args['repo']=$1 shift # :argument.case elif [[ -z ${args['path']+x} ]]; then args['path']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['repo']+x} ]]; then printf "missing required argument: REPO\nusage: rush add REPO PATH\n" >&2 exit 1 fi if [[ -z ${args['path']+x} ]]; then printf "missing required argument: PATH\nusage: rush add REPO PATH\n" >&2 exit 1 fi } # :command.parse_requirements rush_remove_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_remove_usage exit ;; *) break ;; esac done # :command.command_filter action="remove" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --purge | -p) # :flag.case_no_arg args['--purge']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['repo']+x} ]]; then args['repo']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['repo']+x} ]]; then printf "missing required argument: REPO\nusage: rush remove REPO [OPTIONS]\n" >&2 exit 1 fi } # :command.parse_requirements rush_clone_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_clone_usage exit ;; *) break ;; esac done # :command.dependencies_filter if command -v git >/dev/null 2>&1; then deps['git']="$(command -v git | head -n1)" else printf "missing dependency: git\n" >&2 exit 1 fi # :command.command_filter action="clone" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --ssh | -s) # :flag.case_no_arg args['--ssh']=1 shift ;; # :flag.case --default | -d) # :flag.case_no_arg args['--default']=1 shift ;; # :flag.case --name | -n) # :flag.case_arg if [[ -n ${2+x} ]]; then args['--name']="$2" shift shift else printf "%s\n" "--name requires an argument: --name, -n NAME" >&2 exit 1 fi ;; # :flag.case --shallow | -w) # :flag.case_no_arg args['--shallow']=1 shift ;; # :flag.case --ignore | -i) # :flag.case_no_arg args['--ignore']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['github_user']+x} ]]; then args['github_user']=$1 shift # :argument.case elif [[ -z ${args['path']+x} ]]; then args['path']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['github_user']+x} ]]; then printf "missing required argument: GITHUB_USER\nusage: rush clone GITHUB_USER [PATH] [OPTIONS]\n" >&2 exit 1 fi } # :command.parse_requirements rush_pull_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_pull_usage exit ;; *) break ;; esac done # :command.dependencies_filter if command -v git >/dev/null 2>&1; then deps['git']="$(command -v git | head -n1)" else printf "missing dependency: git\n" >&2 exit 1 fi # :command.command_filter action="pull" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['repo']+x} ]]; then args['repo']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done } # :command.parse_requirements rush_push_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_push_usage exit ;; *) break ;; esac done # :command.dependencies_filter if command -v git >/dev/null 2>&1; then deps['git']="$(command -v git | head -n1)" else printf "missing dependency: git\n" >&2 exit 1 fi # :command.command_filter action="push" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --all | -a) # :flag.case_no_arg args['--all']=1 shift ;; # :flag.case --message | -m) # :flag.case_arg if [[ -n ${2+x} ]]; then args['--message']="$2" shift shift else printf "%s\n" "--message requires an argument: --message, -m TEXT" >&2 exit 1 fi ;; # :flag.case --chmod | -x) # :flag.case_no_arg args['--chmod']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['repo']+x} ]]; then args['repo']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.default_assignments [[ -n ${args['repo']:-} ]] || args['repo']="default" [[ -n ${args['--message']:-} ]] || args['--message']="automatic commit" } # :command.parse_requirements rush_config_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_config_usage exit ;; *) break ;; esac done # :command.command_filter action="config" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --edit | -e) # :flag.case_no_arg args['--edit']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple printf "invalid argument: %s\n" "$key" >&2 exit 1 ;; esac done } # :command.parse_requirements rush_default_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_default_usage exit ;; *) break ;; esac done # :command.command_filter action="default" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['repo']+x} ]]; then args['repo']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['repo']+x} ]]; then printf "missing required argument: REPO\nusage: rush default REPO\n" >&2 exit 1 fi } # :command.parse_requirements rush_get_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_get_usage exit ;; *) break ;; esac done # :command.command_filter action="get" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --clone | -c) # :flag.case_no_arg args['--clone']=1 shift ;; # :flag.case --force | -f) # :flag.case_no_arg args['--force']=1 shift ;; # :flag.case --verbose | -v) # :flag.case_no_arg args['--verbose']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['package']+x} ]]; then args['package']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['package']+x} ]]; then printf "missing required argument: PACKAGE\nusage: rush [get] PACKAGE [OPTIONS]\n" >&2 exit 1 fi } # :command.parse_requirements rush_undo_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_undo_usage exit ;; *) break ;; esac done # :command.command_filter action="undo" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --verbose | -v) # :flag.case_no_arg args['--verbose']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['package']+x} ]]; then args['package']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['package']+x} ]]; then printf "missing required argument: PACKAGE\nusage: rush undo PACKAGE [OPTIONS]\n" >&2 exit 1 fi } # :command.parse_requirements rush_snatch_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_snatch_usage exit ;; *) break ;; esac done # :command.command_filter action="snatch" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --force | -f) # :flag.case_no_arg args['--force']=1 shift ;; # :flag.case --verbose | -v) # :flag.case_no_arg args['--verbose']=1 shift ;; # :flag.case --undo | -u) # :flag.case_no_arg args['--undo']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['github_user']+x} ]]; then args['github_user']=$1 shift # :argument.case elif [[ -z ${args['package']+x} ]]; then args['package']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['github_user']+x} ]]; then printf "missing required argument: GITHUB_USER\nusage: rush snatch GITHUB_USER PACKAGE [OPTIONS]\n" >&2 exit 1 fi if [[ -z ${args['package']+x} ]]; then printf "missing required argument: PACKAGE\nusage: rush snatch GITHUB_USER PACKAGE [OPTIONS]\n" >&2 exit 1 fi } # :command.parse_requirements rush_copy_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_copy_usage exit ;; *) break ;; esac done # :command.command_filter action="copy" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --force | -f) # :flag.case_no_arg args['--force']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['source_package']+x} ]]; then args['source_package']=$1 shift # :argument.case elif [[ -z ${args['target_package']+x} ]]; then args['target_package']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['source_package']+x} ]]; then printf "missing required argument: SOURCE_PACKAGE\nusage: rush copy SOURCE_PACKAGE [TARGET_PACKAGE] [OPTIONS]\n" >&2 exit 1 fi } # :command.parse_requirements rush_info_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_info_usage exit ;; *) break ;; esac done # :command.command_filter action="info" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['package']+x} ]]; then args['package']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['package']+x} ]]; then printf "missing required argument: PACKAGE\nusage: rush info PACKAGE\n" >&2 exit 1 fi } # :command.parse_requirements rush_list_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_list_usage exit ;; *) break ;; esac done # :command.command_filter action="list" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in # :flag.case --simple | -s) # :flag.case_no_arg args['--simple']=1 shift ;; # :flag.case --all | -a) # :flag.case_no_arg args['--all']=1 shift ;; -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['repo_or_package']+x} ]]; then args['repo_or_package']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done } # :command.parse_requirements rush_search_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_search_usage exit ;; *) break ;; esac done # :command.command_filter action="search" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['text']+x} ]]; then args['text']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['text']+x} ]]; then printf "missing required argument: TEXT\nusage: rush search TEXT\n" >&2 exit 1 fi } # :command.parse_requirements rush_edit_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_edit_usage exit ;; *) break ;; esac done # :command.command_filter action="edit" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['package']+x} ]]; then args['package']=$1 shift # :argument.case elif [[ -z ${args['file']+x} ]]; then args['file']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['package']+x} ]]; then printf "missing required argument: PACKAGE\nusage: rush edit PACKAGE [FILE]\n" >&2 exit 1 fi # :command.default_assignments [[ -n ${args['file']:-} ]] || args['file']="main" } # :command.parse_requirements rush_show_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_show_usage exit ;; *) break ;; esac done # :command.command_filter action="show" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple # :argument.case if [[ -z ${args['package']+x} ]]; then args['package']=$1 shift # :argument.case elif [[ -z ${args['file']+x} ]]; then args['file']=$1 shift else printf "invalid argument: %s\n" "$key" >&2 exit 1 fi ;; esac done # :command.required_args_filter if [[ -z ${args['package']+x} ]]; then printf "missing required argument: PACKAGE\nusage: rush show PACKAGE [FILE]\n" >&2 exit 1 fi } # :command.parse_requirements rush_completions_parse_requirements() { # :command.fixed_flags_filter while [[ $# -gt 0 ]]; do case "${1:-}" in --help | -h) long_usage=yes rush_completions_usage exit ;; *) break ;; esac done # :command.command_filter action="completions" # :command.parse_requirements_while while [[ $# -gt 0 ]]; do key="$1" case "$key" in -?*) printf "invalid option: %s\n" "$key" >&2 exit 1 ;; *) # :command.parse_requirements_case # :command.parse_requirements_case_simple printf "invalid argument: %s\n" "$key" >&2 exit 1 ;; esac done } # :command.initialize initialize() { version="0.7.14" long_usage='' set -e # src/initialize.sh CONFIG_FILE="${RUSH_CONFIG:-$HOME/rush.ini}" RUSH_ROOT="${RUSH_ROOT:-$HOME/rush-repos}" } # :command.run run() { declare -A args=() declare -A deps=() declare -a other_args=() declare -a env_var_names=() declare -a input=() normalize_input "$@" parse_requirements "${input[@]}" case "$action" in "add") rush_add_command ;; "remove") rush_remove_command ;; "clone") rush_clone_command ;; "pull") rush_pull_command ;; "push") rush_push_command ;; "config") rush_config_command ;; "default") rush_default_command ;; "get") rush_get_command ;; "undo") rush_undo_command ;; "snatch") rush_snatch_command ;; "copy") rush_copy_command ;; "info") rush_info_command ;; "list") rush_list_command ;; "search") rush_search_command ;; "edit") rush_edit_command ;; "show") rush_show_command ;; "completions") rush_completions_command ;; esac } initialize run "$@"