1
0
forked from a/repotool
repotool/repotool
2024-05-01 19:48:25 -05:00

622 lines
12 KiB
Bash
Executable File

#!/usr/bin/env bash
# This script was generated by bashly 1.1.10 (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
repotool_usage() {
if [[ -n $long_usage ]]; then
printf "repotool - repo tool\n"
echo
else
printf "repotool - repo tool\n"
echo
fi
printf "%s\n" "Usage:"
printf " repotool COMMAND\n"
printf " repotool [COMMAND] --help | -h\n"
printf " repotool --version | -v\n"
echo
# :command.usage_commands
printf "%s\n" "Commands:"
printf " %s gets repo if not found\n" "get"
echo
# :command.long_usage
if [[ -n $long_usage ]]; then
printf "%s\n" "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" "Environment Variables:"
# :environment_variable.usage
printf " %s\n" "REPOTOOL_PATH"
printf " default path to clone to\n"
printf " Default: $HOME/repo\n"
echo
# :environment_variable.usage
printf " %s\n" "DEBUG_LOG"
printf " set to 1 to enable debug logg\n"
printf " Default: 0\n"
echo
fi
}
# :command.usage
repotool_get_usage() {
if [[ -n $long_usage ]]; then
printf "repotool get - gets repo if not found\n"
echo
else
printf "repotool get - gets repo if not found\n"
echo
fi
printf "Alias: g\n"
echo
printf "%s\n" "Usage:"
printf " repotool get REPO [OPTIONS]\n"
printf " repotool get --help | -h\n"
echo
# :command.long_usage
if [[ -n $long_usage ]]; then
printf "%s\n" "Options:"
# :command.usage_flags
# :flag.usage
printf " %s\n" "--ssh-user SSH_USER"
printf " ssh user to clone with.\n"
printf " Default: git\n"
echo
# :flag.usage
printf " %s\n" "--http-user HTTP_USER"
printf " http user to clone with.\n"
printf " Default: \n"
echo
# :flag.usage
printf " %s\n" "--http-pass HTTP_PASS"
printf " http pass to clone with.\n"
printf " Default: \n"
echo
# :flag.usage
printf " %s\n" "--method, -m METHOD"
printf " the method to clone the repo with\n"
printf " Allowed: ssh, https, http\n"
printf " Default: ssh\n"
echo
# :command.usage_fixed_flags
printf " %s\n" "--help, -h"
printf " Show this help\n"
echo
# :command.usage_args
printf "%s\n" "Arguments:"
# :argument.usage
printf " %s\n" "REPO"
printf " URL to repo\n"
echo
# :command.usage_examples
printf "%s\n" "Examples:"
printf " repo get tuxpa.in/a/repotool\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/repotool/stdlib.sh
# ((git|ssh|http(s)?)?|(git@[\w\.]+))(:(//)?)([\w\.@\:/\-~]+)(\.git)?(/)?
valid_url()
{
# matches https://<domain.tld>/<path>
if [[ "$1" =~ ^https?://.*\..*/.*$ ]]; then
echo '1'
return 0
fi
# matches <user>@<domain.*?>:<path>
if [[ "$1" =~ ^(.*?)(:|/)(.+)(\/.+)*$ ]]; then
echo '2'
return 0
fi
echo '-1'
return 0
}
lcat()
{
if [[ -z "$DEBUG_LOG" || "$DEBUG_LOG" == 0 ]]; then
return 0
fi
cat $@ >&2
}
lecho()
{
if [[ -z "$DEBUG_LOG" || "$DEBUG_LOG" == 0 ]]; then
return 0
fi
echo $@ >&2
}
linspect()
{
if [[ -z "$DEBUG_LOG" || "$DEBUG_LOG" == 0 ]]; then
return 0
fi
inspect_args>&2
}
# :command.command_functions
# :command.function
repotool_get_command() {
# src/get_command.sh
linspect
local resp
resp=$(valid_url ${args[repo]})
if [[ $resp == -1 ]]; then
echo "${args[repo]} is not a valid repo"
exit 1
fi
local regex="${deps[perl]} -n -l -e"
local git="${deps[git]}"
local base_path=$REPOTOOL_PATH
local ssh_user;
# the ssh user to clone with
local http_user;
local http_pass;
local domain
local path
#now extract the args we need
# this is where we use perl
if [[ $resp == 1 ]]; then
# TODO: properly extract user and password, if exists.
output=($(echo ${args[repo]} | ${regex} '/^https?:\/\/(?:.*?:)?(.*\..*?)\/(.*?)(\.git)?$/ && print "$1 $2" ' -))
domain=${output[0]}
path=${output[1]}
fi
if [[ $resp == 2 ]]; then
# TODO: properly extract ssh user, if exists.
output=($(echo ${args[repo]} | ${regex} '/^(?:.*?@)?(.*\..*?)(?::|\/)(.*?)(\.git)?$/ && print "$1 $2" ' -))
domain=${output[0]}
path=${output[1]}
fi
if [[ ! -z "${args[--ssh-user]}" && -z "$ssh_user" ]]; then
ssh_user=${args[--ssh-user]}
fi
if [[ ! -z "${args[--http-user]}" && -z "$http_user" ]]; then
http_user=${args[--http-user]}
fi
if [[ ! -z "${args[--http-pass]}" && -z "$http_pass" ]]; then
http_pass=${args[--http-pass]}
fi
if [[ -z "$method" ]]; then
method=${args[--method]}
fi
lcat << EOF
found valid repo target
domain: $domain
path: $path
ssh_user: $ssh_user
method: $method
http_user: $http_user
http_pass: $http_pass
EOF
local target_dir="$base_path/$domain/$path"
if [[ ! -d $target_dir ]]; then
mkdir -p $target_dir
fi
cd $target_dir
local repo_url=""
case $method in
ssh)
repo_url="$ssh_user@$domain:$path"
;;
https | http)
# TODO: support http_user and http_pass
repo_url="$method://$domain/$path.git"
;;
*)
echo "unrecognized clone method $method"
exit 1
esac
local cloned="false"
# we check if we have cloned the repo via the if the .git folder exists
if [[ ! -d .git ]]; then
# check if the remote actually exists
$git ls-remote $repo_url > /dev/null && RC=$? || RC=$?
if [[ $RC == 0 ]]; then
$git clone $repo_url $target_dir >&2
cloned="true"
else
echo "Could not find repo: $repo_url"
exit 1
fi
fi
echo dir=$target_dir domain=$domain path=$path repo_url=$repo_url cloned=$cloned
exit 0
}
# :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
repotool_usage
exit
;;
*)
break
;;
esac
done
# :command.environment_variables_filter
# :command.environment_variables_default
export REPOTOOL_PATH="${REPOTOOL_PATH:-$HOME/repo}"
export DEBUG_LOG="${DEBUG_LOG:-0}"
env_var_names+=("REPOTOOL_PATH")
env_var_names+=("DEBUG_LOG")
# :command.command_filter
action=${1:-}
case $action in
-*) ;;
get | g)
action="get"
shift
repotool_get_parse_requirements "$@"
shift $#
;;
# :command.command_fallback
"")
repotool_usage >&2
exit 1
;;
*)
printf "invalid command: %s\n" "$action" >&2
exit 1
;;
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
repotool_get_parse_requirements() {
# :command.fixed_flags_filter
while [[ $# -gt 0 ]]; do
case "${1:-}" in
--help | -h)
long_usage=yes
repotool_get_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
if command -v perl >/dev/null 2>&1; then
deps['perl']="$(command -v perl | head -n1)"
else
printf "missing dependency: perl\n" >&2
exit 1
fi
# :command.command_filter
action="get"
# :command.parse_requirements_while
while [[ $# -gt 0 ]]; do
key="$1"
case "$key" in
# :flag.case
--ssh-user)
# :flag.case_arg
if [[ -n ${2+x} ]]; then
args['--ssh-user']="$2"
shift
shift
else
printf "%s\n" "--ssh-user requires an argument: --ssh-user SSH_USER" >&2
exit 1
fi
;;
# :flag.case
--http-user)
# :flag.case_arg
if [[ -n ${2+x} ]]; then
args['--http-user']="$2"
shift
shift
else
printf "%s\n" "--http-user requires an argument: --http-user HTTP_USER" >&2
exit 1
fi
;;
# :flag.case
--http-pass)
# :flag.case_arg
if [[ -n ${2+x} ]]; then
args['--http-pass']="$2"
shift
shift
else
printf "%s\n" "--http-pass requires an argument: --http-pass HTTP_PASS" >&2
exit 1
fi
;;
# :flag.case
--method | -m)
# :flag.case_arg
if [[ -n ${2+x} ]]; then
args['--method']="$2"
shift
shift
else
printf "%s\n" "--method requires an argument: --method, -m METHOD" >&2
exit 1
fi
;;
-?*)
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: repotool get REPO [OPTIONS]\n" >&2
exit 1
fi
# :command.default_assignments
[[ -n ${args['--ssh-user']:-} ]] || args['--ssh-user']="git"
[[ -n ${args['--http-user']:-} ]] || args['--http-user']=""
[[ -n ${args['--http-pass']:-} ]] || args['--http-pass']=""
[[ -n ${args['--method']:-} ]] || args['--method']="ssh"
# :command.whitelist_filter
if [[ ${args['--method']:-} ]] && [[ ! ${args['--method']:-} =~ ^(ssh|https|http)$ ]]; then
printf "%s\n" "--method must be one of: ssh, https, http" >&2
exit 1
fi
}
# :command.initialize
initialize() {
version="0.1.0"
long_usage=''
set -e
# :command.environment_variables_default
export REPOTOOL_PATH="${REPOTOOL_PATH:-$HOME/repo}"
export DEBUG_LOG="${DEBUG_LOG:-0}"
}
# :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
"get") repotool_get_command ;;
esac
}
initialize
run "$@"