#!/bin/bash set -euo pipefail IFS=$'\n' error() { printf 'Error: %s\n' "$1" >&2 exit 1 } arguments() { if [ "$1" -ne "$2" ]; then error "expected $1 argument(s), got $2" fi } valid_repo_name() { # If you modify this, make sure that "git-shell-commands" cannot be accessed. # Currently this is ensured by forbidding / and enforcing a .git suffix. case "$1" in *" "*) error "name may not contain spaces"; ;; *"*"*) error "name may not contain asterisks (*)"; ;; *'\'*) error 'name may not contain backslashes (\)'; ;; *'/'*) error "name may not contain slashes (/)"; ;; *\'*) error "name may not contain apostrophes (')"; ;; *\"*) error 'name may not contain quotes (")'; ;; *$'\t'*) error "name may not contain tabs"; ;; *$'\n'*) error "name may not contain newlines"; ;; .*) error "name may not start with a dot"; ;; .git|"") error "name may not be empty"; ;; *.git) printf '%s' "$1"; ;; *) printf '%s' "$1.git"; ;; esac } repo_name_new() { # Do not remove the extra `|| exit 1`! # Due to bash weirdness, `exit 1` does not propagate through more than one $(…) even with set -e local repo_name="$(valid_repo_name "$1")" || exit 1 # `test` dereferences symlinks, so explicit -L is necessary if [ -e "$repo_name" -o -L "$repo_name" ]; then error "'$repo_name' already exists." fi printf '%s' "$repo_name" } repo_name_existing() { # Do not remove the extra `|| exit 1`! # Due to bash weirdness, `exit 1` does not propagate through more than one $(…) even with set -e local repo_name="$(valid_repo_name "$1")" || exit 1 # `test` dereferences symlinks, so explicit -L is necessary if ! [ -e "$repo_name" -o -L "$repo_name" ]; then error "'$repo_name' does not exist." fi printf '%s' "$repo_name" }