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 2cf7a15fb4b93a44af0f74b7f55d4859c388f83d
parent 33159585fb24630afa415a243a6090cfb4bece2f
Author: Fred Großkopf <fred@kuandu.systems>
Date:   Thu, 17 Sep 2026 16:35:31 +0200

Migrate generate command

Diffstat:
Mgitpages-cmd.sh | 236++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Dgitpages-regenerate.sh | 70----------------------------------------------------------------------
Dgitpages.sh | 147-------------------------------------------------------------------------------
Atest-gitpages-generate.sh | 163+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest-gitpages-regenerate.sh | 72++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
5 files changed, 409 insertions(+), 279 deletions(-)

diff --git a/gitpages-cmd.sh b/gitpages-cmd.sh @@ -3,6 +3,7 @@ set -eu SCRIPT_DIR="$(dirname "$0")" +DEFAULT_CONFIG="/etc/gitpages.conf" usage() { cat << EOF @@ -49,6 +50,126 @@ EOF exit 1 } +# --- Helper Functions --- +get_config_val() { + awk -F '=' -v key="$1" ' + $1 ~ /^[[:space:]]*[a-zA-Z0-9_]+[[:space:]]*$/ && $1 == key { + gsub(/[[:space:]]+$/, "", $2); + gsub(/^[[:space:]]+/, "", $2); + print $2; + exit; + } + ' "$CONFIG" +} + +error() { + printf 'error: %s\n' "$1" >&2 + exit 1 +} +info() { printf 'info: %s\n' "$1"; } +sed_escape() { printf '%s\n' "$1" | sed 's/[\\/&]/\\&/g'; } + +check_deps() { + command -v stagit > /dev/null 2>&1 || error "stagit not found" + command -v stagit-index > /dev/null 2>&1 || error "stagit-index not found" + command -v git > /dev/null 2>&1 || error "git not found" +} + +# --- Core Logic --- +generate_repo_html() { + rm -rf "$STAGING_DIR" + mkdir -p "$STAGING_DIR" + cd "$STAGING_DIR" + stagit "$REPO_SRC" > /dev/null 2>&1 +} + +process_repo_titles() { + [ -n "${REPO_TITLE_DESC:-}" ] || return 0 + esc_desc=$(sed_escape "$REPO_TITLE_DESC") + find "$STAGING_DIR" -name "*.html" -type f -exec sed -i \ + "s| - $REPO_BASE - [^<]*| - $REPO_BASE$esc_desc|g" {} + +} + +generate_index() { + # 1. Verify destination path exists + [ -d "$WEB_ROOT/$GIT_HTML" ] || { + printf 'Error: %s/html not found\n' "$WEB_ROOT" + return 1 + } + + # 2. Use a subshell to avoid persistent cd and ensure we run from the right place + ( + cd "$WEB_ROOT/$GIT_HTML" || exit 1 + + # 3. Check if we have repositories before running the command + # Use 'find' to safely handle the list of repos + repos=$(find "$SRC_DIR" -maxdepth 1 -name "*.git") + + if [ -n "$repos" ]; then + stagit-index $repos > index.html + else + printf 'No repositories found in %s\n' "$SRC_DIR" + fi + ) +} + +process_index() { + [ -f "$WEB_ROOT/$GIT_HTML/index.html" ] || return 0 + [ -n "${INDEX_TITLE:-}" ] && { + esc_title=$(sed_escape "$INDEX_TITLE") + sed -i "s|<title>Repositories</title>|<title>$esc_title</title>|g" "$WEB_ROOT/$GIT_HTML/index.html" + } + [ -n "${INDEX_DESC:-}" ] && { + esc_desc=$(sed_escape "$INDEX_DESC") + sed -i "s|<span class=\"desc\">Repositories</span>|<span class=\"desc\">$esc_desc</span>|g" "$WEB_ROOT/$GIT_HTML/index.html" + } +} + +deploy_assets() { + [ -d "${ASSETS_DIR:-}" ] || return 0 + mkdir -p "$STAGING_DIR" + for f in "$ASSETS_DIR"/*; do + [ -f "$f" ] && cp -L "$f" "$STAGING_DIR/$(basename "$f")" + done +} + +swap_target_dir() { + rm -rf "$TARGET_DIR" 2> /dev/null || true + mv "$STAGING_DIR" "$TARGET_DIR" || error "could not move staging into place" +} + +generate_repo() { + CONFIG="$1" + REPO_SRC="$2" + + [ -r "$CONFIG" ] || error "config $CONFIG not readable" + WEB_ROOT=$(get_config_val "WEB_ROOT") + GIT_HTML=$(get_config_val "GIT_HTML") + GIT_RAW=$(get_config_val "GIT_RAW") + INDEX_TITLE=$(get_config_val "INDEX_TITLE") + INDEX_DESC=$(get_config_val "INDEX_DESCRIPTION") + REPO_TITLE_DESC=$(get_config_val "REPO_TITLE_DESCRIPTION") + ASSETS_DIR=$(get_config_val "ASSETS_DIR") + + check_deps + + REPO_BASE=$(basename "$REPO_SRC" ".git") + SRC_DIR="$WEB_ROOT/$GIT_RAW" + VAR_DIR="${GITPAGES_VAR_DIR:-/var/gitpages}" + TARGET_DIR="$WEB_ROOT/$GIT_HTML/$REPO_BASE" + STAGING_DIR="$VAR_DIR/staging/$REPO_BASE" + + # Execution + generate_repo_html + deploy_assets + process_repo_titles + swap_target_dir + generate_index + process_index + + info "Generation complete for $REPO_BASE" +} + cmd_setup() { "$SCRIPT_DIR/gitpages-init-repos.sh" "$@" } @@ -62,53 +183,80 @@ cmd_mirror() { } 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 + repo="" + config="" - 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 + while [ "$#" -gt 0 ]; do + case "$1" in + -h) + printf 'usage: gitpages generate [-c config] [REPO]\n' + return 0 + ;; + -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 + + [ -n "$config" ] || config="$DEFAULT_CONFIG" + + if [ -n "$repo" ]; then + generate_repo "$config" "$repo" + else + generate_all "$config" + fi +} + +generate_all() { + CONFIG="$1" + + [ -r "$CONFIG" ] || error "config $CONFIG not readable" + + WEB_ROOT=$(get_config_val "WEB_ROOT") + GIT_SRC=$(get_config_val "GIT_SRC") + GIT_RAW=$(get_config_val "GIT_RAW") + + [ -n "$WEB_ROOT" ] || error "WEB_ROOT missing in config" + [ -n "$GIT_SRC" ] || error "GIT_SRC missing in config" + [ -n "$GIT_RAW" ] || error "GIT_RAW missing in config" + + [ -d "$WEB_ROOT" ] || error "WEB_ROOT directory $WEB_ROOT does not exist" + [ -d "$GIT_SRC" ] || error "GIT_SRC directory $GIT_SRC does not exist" + + GIT_RAW_DIR="$WEB_ROOT/$GIT_RAW" + + info "1/2 Mirroring repos $GIT_SRC → $GIT_RAW_DIR" + "$SCRIPT_DIR/gitpages-mirror-git.sh" "$GIT_SRC" "$GIT_RAW_DIR" || + error "Mirroring failed" + + info "2/2 Generating HTML for all repos in $GIT_RAW_DIR" + + for repo in "$GIT_RAW_DIR"/*.git; do + [ -e "$repo" ] || continue + + info "Processing: $(basename "$repo")" + generate_repo "$CONFIG" "$repo" + done } + [ $# -gt 0 ] || usage command="$1" diff --git a/gitpages-regenerate.sh b/gitpages-regenerate.sh @@ -1,70 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2026 Fred Großkopf -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -set -eu - -# Ensure a stable environment -PATH=/usr/local/bin:/usr/bin:/bin:$PATH - -error() { - printf 'error: %s\n' "$1" >&2 - exit 1 -} - -# Consistent awk-based config retrieval -get_config_val() { - awk -F '=' -v key="$1" '$1 == key {gsub(/[[:space:]]/, "", $2); print $2}' "$2" | tail -n 1 -} - -main() { - CONFIG_PATH="/etc/gitpages.conf" - - # Optional -c argument parsing - if [ "${1:-}" = "-c" ]; then - [ $# -lt 2 ] && { printf "usage: $(basename "$0") [-c config]\n"; exit 1; } - CONFIG_PATH="$2" - shift 2 - fi - - [ -f "$CONFIG_PATH" ] || error "Config file $CONFIG_PATH not found" - - # Retrieve values - WEB_ROOT=$(get_config_val "WEB_ROOT" "$CONFIG_PATH") - GIT_SRC=$(get_config_val "GIT_SRC" "$CONFIG_PATH") - GIT_RAW=$(get_config_val "GIT_RAW" "$CONFIG_PATH") - - if [ -z "$WEB_ROOT" ] || [ -z "$GIT_SRC" ] || [ -z "$GIT_RAW" ]; then - error "WEB_ROOT, GIT_SRC or GIT_RAW missing in config" - fi - [ -d "$WEB_ROOT" ] || error "WEB_ROOT directory $WEB_ROOT does not exist" - [ -d "$GIT_SRC" ] || error "GIT_SRC directory $GIT_SRC does not exist" - - GIT_RAW_DIR="$WEB_ROOT/$GIT_RAW" - - printf 'info: 1/2 Mirroring repos %s → %s\n' "$GIT_SRC" "$GIT_RAW_DIR" - gitpages-mirror-git.sh "$GIT_SRC" "$GIT_RAW_DIR" || error "Mirroring failed" - - printf 'info: 2/2 Generating HTML for all repos in %s\n' "$GIT_RAW_DIR" - - # Iterate over each .git directory and call gitpages.sh - for repo in "$GIT_RAW_DIR"/*.git; do - [ -e "$repo" ] || continue - printf ' Processing: %s\n' "$(basename "$repo")" - gitpages.sh -c "$CONFIG_PATH" "$repo" || error "HTML generation failed for $repo" - done -} - -main "$@" diff --git a/gitpages.sh b/gitpages.sh @@ -1,147 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2026 Fred Großkopf -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -set -eu - -DEFAULT_CONFIG="/etc/gitpages.conf" - -# --- Secure Config Parser --- -get_config_val() { - awk -F '=' -v key="$1" ' - $1 ~ /^[[:space:]]*[a-zA-Z0-9_]+[[:space:]]*$/ && $1 == key { - gsub(/[[:space:]]+$/, "", $2); - gsub(/^[[:space:]]+/, "", $2); - print $2; - exit; - } - ' "$CONFIG" -} - -# --- Utility Functions --- -error() { printf 'error: %s\n' "$1" >&2; exit 1; } -info() { printf 'info: %s\n' "$1"; } -sed_escape() { printf '%s\n' "$1" | sed 's/[\\/&]/\\&/g'; } - -# --- Validation --- -check_deps() { - command -v stagit > /dev/null 2>&1 || error "stagit not found" - command -v stagit-index > /dev/null 2>&1 || error "stagit-index not found" - command -v git > /dev/null 2>&1 || error "git not found" -} - -# --- Core Logic --- -generate_repo_html() { - rm -rf "$STAGING_DIR" - mkdir -p "$STAGING_DIR" - cd "$STAGING_DIR" - stagit "$REPO_SRC" >/dev/null 2>&1 -} - -process_repo_titles() { - [ -n "${REPO_TITLE_DESC:-}" ] || return 0 - esc_desc=$(sed_escape "$REPO_TITLE_DESC") - find "$STAGING_DIR" -name "*.html" -type f -exec sed -i \ - "s| - $REPO_BASE - [^<]*| - $REPO_BASE$esc_desc|g" {} + -} - -generate_index() { - # 1. Verify destination path exists - [ -d "$WEB_ROOT/$GIT_HTML" ] || { printf 'Error: %s/html not found\n' "$WEB_ROOT"; return 1; } - - # 2. Use a subshell to avoid persistent cd and ensure we run from the right place - ( - cd "$WEB_ROOT/$GIT_HTML" || exit 1 - - # 3. Check if we have repositories before running the command - # Use 'find' to safely handle the list of repos - repos=$(find "$SRC_DIR" -maxdepth 1 -name "*.git") - - if [ -n "$repos" ]; then - stagit-index $repos > index.html - else - printf 'No repositories found in %s\n' "$SRC_DIR" - fi - ) -} - -process_index() { - [ -f "$WEB_ROOT/$GIT_HTML/index.html" ] || return 0 - [ -n "${INDEX_TITLE:-}" ] && { - esc_title=$(sed_escape "$INDEX_TITLE") - sed -i "s|<title>Repositories</title>|<title>$esc_title</title>|g" "$WEB_ROOT/$GIT_HTML/index.html" - } - [ -n "${INDEX_DESC:-}" ] && { - esc_desc=$(sed_escape "$INDEX_DESC") - sed -i "s|<span class=\"desc\">Repositories</span>|<span class=\"desc\">$esc_desc</span>|g" "$WEB_ROOT/$GIT_HTML/index.html" - } -} - -deploy_assets() { - [ -d "${ASSETS_DIR:-}" ] || return 0 - mkdir -p "$STAGING_DIR" - for f in "$ASSETS_DIR"/*; do - [ -f "$f" ] && cp -L "$f" "$STAGING_DIR/$(basename "$f")" - done -} - -swap_target_dir() { - rm -rf "$TARGET_DIR" 2>/dev/null || true - mv "$STAGING_DIR" "$TARGET_DIR" || error "could not move staging into place" -} - -main() { - CONFIG="$DEFAULT_CONFIG" - while getopts ":c:h" opt; do - case "$opt" in - c) CONFIG="$OPTARG" ;; - h) printf 'usage: gitpages.sh [-c config] SRC\n'; exit 0 ;; - *) exit 1 ;; - esac - done - shift $((OPTIND - 1)) - [ $# -eq 1 ] || error "usage: gitpages.sh [-c config] SRC" - - # Load configuration - [ -r "$CONFIG" ] || error "config $CONFIG not readable" - WEB_ROOT=$(get_config_val "WEB_ROOT") - GIT_HTML=$(get_config_val "GIT_HTML") - GIT_RAW=$(get_config_val "GIT_RAW") - INDEX_TITLE=$(get_config_val "INDEX_TITLE") - INDEX_DESC=$(get_config_val "INDEX_DESCRIPTION") - REPO_TITLE_DESC=$(get_config_val "REPO_TITLE_DESCRIPTION") - ASSETS_DIR=$(get_config_val "ASSETS_DIR") - - # Setup environment context - check_deps - REPO_SRC="$1" - REPO_BASE=$(basename "$REPO_SRC" ".git") - SRC_DIR="$WEB_ROOT/$GIT_RAW" - VAR_DIR="${GITPAGES_VAR_DIR:-/var/gitpages}" - TARGET_DIR="$WEB_ROOT/$GIT_HTML/$REPO_BASE" - STAGING_DIR="$VAR_DIR/staging/$REPO_BASE" - - # Execution - generate_repo_html - deploy_assets - process_repo_titles - swap_target_dir - generate_index - process_index - - info "Generation complete for $REPO_BASE" -} - -main "$@" diff --git a/test-gitpages-generate.sh b/test-gitpages-generate.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd) +SCRIPT="$SCRIPT_DIR/gitpages-cmd.sh" + +TEST_ROOT=$(mktemp -d) +trap 'rm -rf "$TEST_ROOT"' EXIT + +WEB_ROOT="$TEST_ROOT/web" +GIT_SRC="$TEST_ROOT/src" +GIT_RAW="$WEB_ROOT/raw" +GIT_HTML="$WEB_ROOT/git" +ASSETS_DIR="$TEST_ROOT/assets" +GITPAGES_VAR_DIR="$TEST_ROOT/var" +CONFIG="$TEST_ROOT/gitpages.conf" + +export GITPAGES_VAR_DIR + +mkdir -p \ + "$GIT_SRC" \ + "$GIT_RAW" \ + "$GIT_HTML" \ + "$ASSETS_DIR" \ + "$GITPAGES_VAR_DIR" + +# +# Mock stagit and stagit-index. +# +mkdir -p "$TEST_ROOT/bin" +export PATH="$TEST_ROOT/bin:$PATH" + +cat > "$TEST_ROOT/bin/stagit" <<'EOF' +#!/bin/sh +set -eu + +# generate_repo_html() has already cd'ed into the staging directory. +touch index.html +EOF + +cat > "$TEST_ROOT/bin/stagit-index" <<'EOF' +#!/bin/sh +set -eu + +printf '%s\n' '<html><body>Repositories</body></html>' +EOF + +chmod +x \ + "$TEST_ROOT/bin/stagit" \ + "$TEST_ROOT/bin/stagit-index" + +# +# Configuration. +# +cat > "$CONFIG" <<EOF +WEB_ROOT=$WEB_ROOT +GIT_SRC=$GIT_SRC +GIT_RAW=raw +GIT_HTML=git +ASSETS_DIR=$ASSETS_DIR +EOF + +fail() { + printf 'FAIL: %s\n' "$1" >&2 + exit 1 +} + +assert_dir() { + [ -d "$1" ] || fail "$2" +} + +assert_file() { + [ -f "$1" ] || fail "$2" +} + +# +# Create a real bare repository in GIT_SRC. +# +create_repo() { + name="$1" + work="$TEST_ROOT/work-$name" + + mkdir -p "$work" + + ( + cd "$work" + + git init >/dev/null + git config user.name "Test User" + git config user.email "test@example.com" + + printf 'test\n' > README + git add README + git commit -m "Initial commit" >/dev/null + + git clone --bare . "$GIT_SRC/$name.git" >/dev/null + ) + + git --git-dir="$GIT_SRC/$name.git" \ + symbolic-ref HEAD refs/heads/main +} + +echo "Testing $SCRIPT generate" + +# +# Test: generate all repositories +# +echo "=== Test: generate all repositories ===" + +create_repo myrepo + +"$SCRIPT" generate -c "$CONFIG" + +assert_dir \ + "$GIT_RAW/myrepo.git" \ + "myrepo.git was mirrored" + +assert_dir \ + "$GIT_HTML/myrepo" \ + "HTML directory was generated" + +assert_file \ + "$GIT_HTML/myrepo/index.html" \ + "repository index.html was generated" + +assert_file \ + "$GIT_HTML/index.html" \ + "repository index was generated" + +echo "PASS: generate all repositories" + +# +# Test: generate a single repository +# +echo "=== Test: generate single repository ===" + +rm -rf "$GIT_HTML/myrepo" + +"$SCRIPT" generate -c "$CONFIG" "$GIT_RAW/myrepo.git" + +assert_dir \ + "$GIT_HTML/myrepo" \ + "HTML directory was generated for single repository" + +assert_file \ + "$GIT_HTML/myrepo/index.html" \ + "repository index.html was generated for single repository" + +echo "PASS: generate single repository" + +# +# Test: unknown option +# +echo "=== Test: invalid arguments ===" + +if "$SCRIPT" generate -c "$CONFIG" -x >/dev/null 2>&1; then + fail "unknown option was accepted" +fi + +echo "PASS: invalid arguments" + +echo "All generate tests passed." diff --git a/test-gitpages-regenerate.sh b/test-gitpages-regenerate.sh @@ -10,26 +10,38 @@ # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS; WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -set -e +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd) +SCRIPT="$SCRIPT_DIR/gitpages-cmd.sh" # Configuration TEST_DIR=$(realpath "$(mktemp -d)") CONFIG_FILE="$TEST_DIR/gitpages.conf" GIT_SRC="$TEST_DIR/src" GIT_RAW="$TEST_DIR/raw" +GIT_HTML="$TEST_DIR/git" ASSETS_DIR="$TEST_DIR/assets" +GITPAGES_VAR_DIR="$TEST_DIR/var" + +export GITPAGES_VAR_DIR + +cleanup() { + rm -rf "$TEST_DIR" +} -# Mock dependencies so we don't need real binaries +trap cleanup EXIT INT TERM + +# Mock dependencies so we don't need stagit installed. mkdir -p "$TEST_DIR/bin" export PATH="$TEST_DIR/bin:$PATH" -# The mock script correctly uses the filename as the identifier mock_bin() { - cat << EOF > "$TEST_DIR/bin/$1" + cat > "$TEST_DIR/bin/$1" <<EOF #!/bin/sh echo "MOCK: $1 called with \$*" exit 0 @@ -37,29 +49,53 @@ EOF chmod +x "$TEST_DIR/bin/$1" } -# Generate mocks -mock_bin gitpages-mirror-git.sh -mock_bin gitpages.sh -mock_bin git mock_bin stagit mock_bin stagit-index # Setup test environment -mkdir -p "$GIT_SRC" "$GIT_RAW" "$ASSETS_DIR" +mkdir -p \ + "$GIT_SRC" \ + "$GIT_RAW" \ + "$GIT_HTML" \ + "$ASSETS_DIR" \ + "$GITPAGES_VAR_DIR" -# Create at least one dummy repo file so the loop in gitpages-regenerate.sh triggers -touch "$GIT_RAW/myrepo.git" +# Create a real bare repository in GIT_SRC. +# +# The real mirror command will copy this repository to GIT_RAW. +git init --bare "$GIT_SRC/myrepo.git" >/dev/null +git --git-dir="$GIT_SRC/myrepo.git" \ + symbolic-ref HEAD refs/heads/main # Create test config -cat <<EOF > "$CONFIG_FILE" +cat > "$CONFIG_FILE" <<EOF WEB_ROOT=$TEST_DIR GIT_SRC=$GIT_SRC GIT_RAW=raw +GIT_HTML=git +ASSETS_DIR=$ASSETS_DIR EOF -echo "Running test on gitpages-regenerate.sh..." -./gitpages-cmd.sh generate -c "$CONFIG_FILE" +echo "Testing $SCRIPT generate" + +echo "=== Test: generate all repositories ===" + +"$SCRIPT" generate -c "$CONFIG_FILE" + +# The real mirror should have copied the repository. +[ -d "$GIT_RAW/myrepo.git" ] || { + echo "FAIL: myrepo.git was not mirrored" >&2 + exit 1 +} + +echo "PASS: myrepo.git was mirrored" + +# Generation should have created the repository HTML directory. +[ -d "$GIT_HTML/myrepo" ] || { + echo "FAIL: myrepo HTML directory was not generated" >&2 + exit 1 +} + +echo "PASS: myrepo HTML directory was generated" -# Clean up -rm -rf "$TEST_DIR" -echo "PASS: Init script executed successfully." +echo "All generate tests passed."