gitpages

A collection of scripts to securely webhost and publish git repositories.
git clone https://scm.kuandu.systems/git-raw/gitpages.git
Log | Files | Refs | README | LICENSE

commit 33159585fb24630afa415a243a6090cfb4bece2f
parent bf6b9fe025e2cdf45d376cd29f628a962c56e0e6
Author: Fred Großkopf <fred@kuandu.systems>
Date:   Thu, 17 Sep 2026 15:41:54 +0200

Adds new gitpages-cmd.sh

which acts as a dispatcher for the old commands.

Diffstat:
Agitpages-cmd.sh | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest-gitpages-init-repos.sh | 2+-
Mtest-gitpages-mirror-git.sh | 20++++++++++----------
Mtest-gitpages-regenerate.sh | 2+-
Mtest-gitpages-update.sh | 2+-
Mtest-gitpages.sh | 6+++---
6 files changed, 149 insertions(+), 16 deletions(-)

diff --git a/gitpages-cmd.sh b/gitpages-cmd.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +set -eu + +SCRIPT_DIR="$(dirname "$0")" + +usage() { + cat << EOF +gitpages - generate static Git web pages using stagit + +Usage: + gitpages setup SRC + gitpages queue REPO + gitpages process_queue + gitpages mirror SRC DST + gitpages generate [REPO] + +Arguments: + SRC + Source directory containing bare Git repositories. + These are the repositories that Git clients push to. + + DST + Destination directory containing web-facing bare Git repositories. + These repositories are served via HTTP (for example git-raw/). + + REPO + Path to a single bare Git repository. + +Commands: + setup SRC + Prepare repositories for gitpages: + install hooks and configure metadata. + + queue REPO + Add a repository to the update queue. + + process_queue + Process queued repository updates. + + mirror SRC DST + Mirror bare repositories from SRC to DST. + + generate [REPO] + Generate stagit HTML pages. + If REPO is omitted, generate pages for all repositories. + +EOF + exit 1 +} + +cmd_setup() { + "$SCRIPT_DIR/gitpages-init-repos.sh" "$@" +} + +cmd_process_queue() { + "$SCRIPT_DIR/gitpages-update.sh" "$@" +} + +cmd_mirror() { + "$SCRIPT_DIR/gitpages-mirror-git.sh" "$@" +} + +cmd_generate() { + repo="" + config="" + + while [ "$#" -gt 0 ]; do + case "$1" in + -h) + "$SCRIPT_DIR/gitpages.sh" -h + return + ;; + -c) + [ "$#" -ge 2 ] || { + printf 'ERROR: -c requires a config file\n' >&2 + exit 1 + } + config="$2" + shift 2 + ;; + -*) + printf 'ERROR: unknown option: %s\n' "$1" >&2 + exit 1 + ;; + *) + [ -z "$repo" ] || { + printf 'ERROR: too many arguments\n' >&2 + exit 1 + } + repo="$1" + shift + ;; + esac + done + + if [ -n "$repo" ]; then + if [ -n "$config" ]; then + "$SCRIPT_DIR/gitpages.sh" "$repo" -c "$config" + else + "$SCRIPT_DIR/gitpages.sh" "$repo" + fi + else + if [ -n "$config" ]; then + "$SCRIPT_DIR/gitpages-regenerate.sh" -c "$config" + else + "$SCRIPT_DIR/gitpages-regenerate.sh" + fi + fi +} + +[ $# -gt 0 ] || usage + +command="$1" +shift + +case "$command" in + setup) + cmd_setup "$@" + ;; + process_queue) + cmd_process_queue "$@" + ;; + mirror) + cmd_mirror "$@" + ;; + generate) + cmd_generate "$@" + ;; + *) + usage + ;; +esac diff --git a/test-gitpages-init-repos.sh b/test-gitpages-init-repos.sh @@ -54,7 +54,7 @@ run_gitpages_init() { printf '%s\n' "Description for bar" printf '%s\n' "user@bar.org" printf '%s\n' "https://bar.example.com" - ) | ./gitpages-init-repos.sh "$TARGET" + ) | ./gitpages-cmd.sh setup "$TARGET" } inspect_repos() { diff --git a/test-gitpages-mirror-git.sh b/test-gitpages-mirror-git.sh @@ -16,7 +16,7 @@ set -eu -SCRIPT_NAME="./gitpages-mirror-git.sh" +SCRIPT_NAME="./gitpages-cmd.sh" check_script() { if [ ! -x "$SCRIPT_NAME" ]; then @@ -81,24 +81,24 @@ assert_server_info() { } test_args() { - assert_fails 1 "Wrong number of arguments" "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR" extra_arg + assert_fails 1 "Wrong number of arguments" "$SCRIPT_NAME" "mirror" "$SRC_DIR" "$DST_DIR" extra_arg } test_bad_src_file() { bad_src="$TEST_BASE/bad_src" touch "$bad_src" - assert_fails 2 "Source is file" "$SCRIPT_NAME" "$bad_src" "$DST_DIR" + assert_fails 2 "Source is file" "$SCRIPT_NAME" "mirror" "$bad_src" "$DST_DIR" } test_bad_dst() { bad_dst="$TEST_BASE/bad_dst" touch "$bad_dst" && chmod 444 "$bad_dst" - assert_fails 3 "Destination not writable" "$SCRIPT_NAME" "$SRC_DIR" "$bad_dst" + assert_fails 3 "Destination not writable" "$SCRIPT_NAME" "mirror" "$SRC_DIR" "$bad_dst" } test_empty_src() { rm -rf "$SRC_DIR"/* - assert_fails 4 "Empty source directory" "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR" + assert_fails 4 "Empty source directory" "$SCRIPT_NAME" "mirror" "$SRC_DIR" "$DST_DIR" } test_full_sync() { @@ -107,7 +107,7 @@ test_full_sync() { (cd "$SRC_DIR/myrepo.git" && git init --bare . >/dev/null 2>&1) (cd "$SRC_DIR/otherrepo" && git init >/dev/null 2>&1) - "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR" + "$SCRIPT_NAME" mirror "$SRC_DIR" "$DST_DIR" assert_repo_copied "$DST_DIR/myrepo.git" "Bare repo copied" assert_repo_skipped "$DST_DIR/otherrepo" "Skipped non-bare" @@ -120,7 +120,7 @@ test_single_repo() { mkdir -p "$SRC_DIR/myrepo.git" (cd "$SRC_DIR/myrepo.git" && git init --bare . >/dev/null 2>&1) - "$SCRIPT_NAME" "$SRC_DIR/myrepo.git" "$DST_DIR" + "$SCRIPT_NAME" mirror "$SRC_DIR/myrepo.git" "$DST_DIR" assert_repo_copied "$DST_DIR/myrepo.git" "Single repo copied" assert_bare_repo "$DST_DIR/myrepo.git" "Single mode: bare repo" @@ -128,15 +128,15 @@ test_single_repo() { } test_root_protection() { - assert_fails 7 "Root protection" "$SCRIPT_NAME" "$SRC_DIR" "/" + assert_fails 7 "Root protection" "$SCRIPT_NAME" "mirror" "$SRC_DIR" "/" } test_non_repo_dir() { - assert_fails 8 "Non-repo directory" "$SCRIPT_NAME" "$TEST_BASE" "$DST_DIR" + assert_fails 8 "Non-repo directory" "$SCRIPT_NAME" "mirror" "$TEST_BASE" "$DST_DIR" } main() { - printf 'Testing %s\n' "$SCRIPT_NAME" + printf 'Testing %s\n' "$SCRIPT_NAME mirror" check_script setup diff --git a/test-gitpages-regenerate.sh b/test-gitpages-regenerate.sh @@ -58,7 +58,7 @@ GIT_RAW=raw EOF echo "Running test on gitpages-regenerate.sh..." -./gitpages-regenerate.sh -c "$CONFIG_FILE" +./gitpages-cmd.sh generate -c "$CONFIG_FILE" # Clean up rm -rf "$TEST_DIR" diff --git a/test-gitpages-update.sh b/test-gitpages-update.sh @@ -57,7 +57,7 @@ GIT_RAW=$GIT_RAW EOF echo "Running test on gitpages-update.sh..." -./gitpages-update.sh -c "$CONFIG_FILE" +./gitpages-cmd.sh process_queue -c "$CONFIG_FILE" # Verify: queue directory should be empty (no job files left) files=$(find "$GITPAGES_QUEUE_DIR" -type f | wc -l) diff --git a/test-gitpages.sh b/test-gitpages.sh @@ -17,7 +17,7 @@ set -e # --- Configuration --- -SCRIPT_NAME="./gitpages.sh" +SCRIPT_NAME="./gitpages-cmd.sh" TEST_DIR=$(realpath "$(mktemp -d)") # --- Cleanup --- @@ -65,8 +65,8 @@ echo "<!-- dummy style -->" > "$TEST_DIR/assets/style.css" # --- Execution --- export GITPAGES_VAR_DIR="$TEST_DIR" -echo "Running $SCRIPT_NAME on $REPO_DIR" -"$SCRIPT_NAME" -c "$CONFIG_FILE" "$REPO_DIR" +echo "Running $SCRIPT_NAME generate on $REPO_DIR" +"$SCRIPT_NAME" generate -c "$CONFIG_FILE" "$REPO_DIR" # --- Verification --- EXPECTED_REPO_DIR="$GIT_HTML_DIR/$REPO_NAME"