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

test-gitpages-mirror-git.sh (4165B)


      1 #!/bin/sh
      2 #
      3 # Copyright (c) 2026 Fred Großkopf
      4 #
      5 # Permission to use, copy, modify, and/or distribute this software for any
      6 # purpose with or without fee is hereby granted, provided that the above
      7 # copyright notice and this permission notice appear in all copies.
      8 #
      9 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     15 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16 
     17 set -eu
     18 
     19 SCRIPT_NAME="./gitpages-mirror-git.sh"
     20 
     21 check_script() {
     22   if [ ! -x "$SCRIPT_NAME" ]; then
     23     printf 'ERROR: %s not found or not executable\n' "$SCRIPT_NAME" >&2
     24     printf 'Please run:\n  chmod +x git-sync.sh\n  ./test-git-sync.sh\n' >&2
     25     exit 1
     26   fi
     27 }
     28 
     29 TEST_BASE=""
     30 cleanup() {
     31   [ -n "$TEST_BASE" ] && rm -rf "$TEST_BASE"
     32 }
     33 trap cleanup EXIT INT TERM
     34 
     35 error() {
     36   printf 'FAIL: %s\n' "$1" >&2
     37   exit 1
     38 }
     39 
     40 success() {
     41   printf 'PASS: %s\n' "$1"
     42 }
     43 
     44 setup() {
     45   TEST_BASE=$(mktemp -d) || error "Failed to create temp dir"
     46   SRC_DIR="$TEST_BASE/src"
     47   DST_DIR="$TEST_BASE/dst"
     48   mkdir -p "$SRC_DIR" "$DST_DIR"
     49 }
     50 
     51 assert_fails() {
     52   test_num="$1"
     53   test_desc="$2"
     54   shift 2
     55   printf '=== Test %s: %s ===\n' "$test_num" "$test_desc"
     56   "$@" && error "Should fail" || success "Rejects $test_desc"
     57 }
     58 
     59 assert_repo_copied() {
     60   repo="$1"
     61   test_name="$2"
     62   [ -d "$repo" ] && success "$test_name" || error "$test_name"
     63 }
     64 
     65 assert_repo_skipped() {
     66   repo="$1"
     67   test_name="$2"
     68   [ ! -d "$repo" ] && success "$test_name" || error "$test_name"
     69 }
     70 
     71 assert_bare_repo() {
     72   repo="$1"
     73   test_name="$2"
     74   git --git-dir="$repo" rev-parse --is-bare-repository >/dev/null 2>&1 || error "$test_name"
     75 }
     76 
     77 assert_server_info() {
     78   repo="$1"
     79   test_name="$2"
     80   [ -f "$repo/info/refs" ] && success "$test_name" || error "$test_name"
     81 }
     82 
     83 test_args() {
     84   assert_fails 1 "Wrong number of arguments" "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR" extra_arg
     85 }
     86 
     87 test_bad_src_file() {
     88   bad_src="$TEST_BASE/bad_src"
     89   touch "$bad_src"
     90   assert_fails 2 "Source is file" "$SCRIPT_NAME" "$bad_src" "$DST_DIR"
     91 }
     92 
     93 test_bad_dst() {
     94   bad_dst="$TEST_BASE/bad_dst"
     95   touch "$bad_dst" && chmod 444 "$bad_dst"
     96   assert_fails 3 "Destination not writable" "$SCRIPT_NAME" "$SRC_DIR" "$bad_dst"
     97 }
     98 
     99 test_empty_src() {
    100   rm -rf "$SRC_DIR"/*
    101   assert_fails 4 "Empty source directory" "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR"
    102 }
    103 
    104 test_full_sync() {
    105   printf '=== Test 5: Full sync ===\n'
    106   mkdir -p "$SRC_DIR/myrepo.git" "$SRC_DIR/otherrepo"
    107   (cd "$SRC_DIR/myrepo.git" && git init --bare . >/dev/null 2>&1)
    108   (cd "$SRC_DIR/otherrepo" && git init >/dev/null 2>&1)
    109   
    110   "$SCRIPT_NAME" "$SRC_DIR" "$DST_DIR"
    111   
    112   assert_repo_copied "$DST_DIR/myrepo.git" "Bare repo copied"
    113   assert_repo_skipped "$DST_DIR/otherrepo" "Skipped non-bare"
    114   assert_bare_repo "$DST_DIR/myrepo.git" "Destination is bare"
    115   assert_server_info "$DST_DIR/myrepo.git" "update-server-info ran"
    116 }
    117 
    118 test_single_repo() {
    119   printf '=== Test 6: Single repo ===\n'
    120   mkdir -p "$SRC_DIR/myrepo.git"
    121   (cd "$SRC_DIR/myrepo.git" && git init --bare . >/dev/null 2>&1)
    122   
    123   "$SCRIPT_NAME" "$SRC_DIR/myrepo.git" "$DST_DIR"
    124   
    125   assert_repo_copied "$DST_DIR/myrepo.git" "Single repo copied"
    126   assert_bare_repo "$DST_DIR/myrepo.git" "Single mode: bare repo"
    127   assert_server_info "$DST_DIR/myrepo.git" "Single mode: update-server-info ran"
    128 }
    129 
    130 test_root_protection() {
    131   assert_fails 7 "Root protection" "$SCRIPT_NAME" "$SRC_DIR" "/"
    132 }
    133 
    134 test_non_repo_dir() {
    135   assert_fails 8 "Non-repo directory" "$SCRIPT_NAME" "$TEST_BASE" "$DST_DIR"
    136 }
    137 
    138 main() {
    139   printf 'Testing %s\n' "$SCRIPT_NAME"
    140   check_script
    141   setup
    142   
    143   test_args
    144   test_bad_src_file
    145   test_bad_dst
    146   test_empty_src
    147   test_full_sync
    148   test_single_repo
    149   test_root_protection
    150   test_non_repo_dir
    151   
    152   printf '\nALL TESTS PASSED!\n'
    153   printf 'Test environment cleaned up.\n'
    154 }
    155 
    156 [ "${0##*/}" = "test-gitpages-mirror-git.sh" ] && main "$@"