aboutsummaryrefslogtreecommitdiff
path: root/nix/per-host/git/git-shell-commands/manage
diff options
context:
space:
mode:
Diffstat (limited to 'nix/per-host/git/git-shell-commands/manage')
-rwxr-xr-xnix/per-host/git/git-shell-commands/manage81
1 files changed, 81 insertions, 0 deletions
diff --git a/nix/per-host/git/git-shell-commands/manage b/nix/per-host/git/git-shell-commands/manage
new file mode 100755
index 0000000..01fd52e
--- /dev/null
+++ b/nix/per-host/git/git-shell-commands/manage
@@ -0,0 +1,81 @@
+#!/usr/bin/env bash
+# git-shell-commands(5) subcommand: interactive repo manager.
+# Run: ssh -t git@git.kumardamani.net manage
+# Also symlinked as no-interactive-login, so a bare interactive ssh
+# (ssh -t git@git.kumardamani.net) lands here directly.
+
+cmds=/srv/git/git-shell-commands
+
+valid_name() {
+ case "$1" in
+ ""|*[!a-zA-Z0-9._-]*|*..*) return 1 ;;
+ *) return 0 ;;
+ esac
+}
+
+list_repos() {
+ printf '%-24s %-8s %s\n' REPO STATE DESCRIPTION
+ for repo in /srv/git/*.git; do
+ [ -d "$repo" ] || continue
+ name="${repo##*/}"
+ name="${name%.git}"
+ if [ -f "$repo/git-daemon-export-ok" ]; then
+ state=public
+ else
+ state=private
+ fi
+ desc="$(cat "$repo/description" 2>/dev/null)"
+ case "$desc" in Unnamed*) desc= ;; esac
+ printf '%-24s %-8s %s\n' "$name" "$state" "$desc"
+ done
+}
+
+ask_name() {
+ printf 'repo name: '
+ read -r name
+ if ! valid_name "$name"; then
+ echo "invalid name '$name' (allowed: a-z 0-9 . _ -)" >&2
+ return 1
+ fi
+}
+
+while true; do
+ echo
+ echo "== git repo manager =="
+ echo " l) list repos"
+ echo " c) create repo"
+ echo " p) publish repo"
+ echo " h) hide repo"
+ echo " d) set description"
+ echo " x) delete repo"
+ echo " q) quit"
+ printf '> '
+ read -r choice || break
+ case "$choice" in
+ l) list_repos ;;
+ c) "$cmds/create" ;; # create prompts for name + settings itself
+ p) ask_name && "$cmds/publish" "$name" ;;
+ h) ask_name && "$cmds/hide" "$name" ;;
+ d)
+ ask_name && {
+ printf 'description: '
+ read -r text
+ "$cmds/desc" "$name" "$text"
+ }
+ ;;
+ x)
+ ask_name && [ -d "/srv/git/$name.git" ] && {
+ printf 'type the repo name again to confirm DELETE: '
+ read -r confirm
+ if [ "$confirm" = "$name" ]; then
+ rm -rf "/srv/git/$name.git"
+ echo "deleted '$name'"
+ else
+ echo "aborted"
+ fi
+ }
+ ;;
+ q|quit|exit) break ;;
+ *) echo "unknown choice '$choice'" ;;
+ esac
+done