Something went wrong. Try again.
Dotfiles for my macos setup
Something went wrong. Try again.
3.3 kB · 156 lines
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157#!/usr/bin/env bash
set -Eeuo pipefail
script_name="git get"version="0.1.0"
usage() { cat <<EOFUsage: $script_name [git clone flags...] <repo>
Config: gj.root Existing directory where repositories are stored as <root>/<host>/<org>/<repo> (e.g. ~/Code/github.com/org/repo).
Examples: $script_name org/repo $script_name gitlab.com/org/repo $script_name https://github.com/org/repo $script_name --depth 1 git@gitlab.com:org/repo.gitEOF}
die() { printf '%s\n' "$*" >&2 exit 1}
require_git() { command -v git >/dev/null 2>&1 || die "git is required on PATH"}
expand_shorthand() { local input=$1
# Full URLs and scp-like syntax pass through untouched. if [[ "$input" =~ ^[a-zA-Z][a-zA-Z0-9+.-]*:// || "$input" == *@*:* ]]; then printf '%s\n' "$input" # org/repo defaults to GitHub. elif [[ "$input" =~ ^[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+$ ]]; then printf 'https://github.com/%s\n' "$input" # host/org/repo works for any remote (e.g. gitlab.com/org/repo). elif [[ "$input" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]+(/[a-zA-Z0-9_.-]+){2,}$ ]]; then printf 'https://%s\n' "$input" else return 1 fi}
parse_repo() { local input=$1 local host path no_scheme
if [[ "$input" =~ ^[a-zA-Z][a-zA-Z0-9+.-]*:// ]]; then no_scheme="${input#*://}" host="${no_scheme%%/*}" path="${no_scheme#*/}" elif [[ "$input" == *@*:* ]]; then host="${input%%:*}" path="${input#*:}" else host="${input%%/*}" path="${input#*/}" fi
# Strip user@ and :port from the host. host="${host##*@}" host="${host%%:*}"
path="${path#/}" path="${path%.git}"
if [[ -z "$host" || -z "$path" || "$path" != */* ]]; then return 1 fi
printf '%s/%s\n' "$host" "$path"}
run_get() { local repo url dest rel local flags=()
if [[ $# -lt 1 ]]; then usage exit 2 fi
root=$(git config --global --get gj.root || true) if [[ -z "$root" ]]; then die "gj.root is not set in git config" fi
root="${root/#\~/$HOME}" if [[ ! -d "$root" ]]; then die "gj.root does not exist: $root" fi
if [[ $# -eq 1 ]]; then repo="$1" else repo="${*: -1}" flags=("${@:1:$#-1}") fi
if ! url=$(expand_shorthand "$repo"); then die "Could not parse repo: $repo" fi repo="$url"
if ! rel=$(parse_repo "$repo"); then die "Could not parse repo: $repo" fi
dest="$root/$rel"
if [[ -e "$dest" ]]; then if [[ -d "$dest/.git" ]]; then git -C "$dest" remote update --prune printf '%s\n' "$dest" return 0 fi die "Destination exists and is not a git repo: $dest" fi
mkdir -p "$(dirname "$dest")" git clone ${flags[@]+"${flags[@]}"} "$repo" "$dest" printf '%s\n' "$dest"}
main() { if [[ $# -lt 1 ]]; then usage exit 2 fi
case "$1" in -h | --help) usage exit 0 ;; --version) printf '%s\n' "$version" exit 0 ;; *) # "get" is accepted for the old `gj get <repo>` form. [[ "$1" == get ]] && shift require_git run_get "$@" ;; esac}
main "$@"