aboutsummaryrefslogtreecommitdiffstats
path: root/examples/tools/test-clone.sh
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-19 19:49:08 +0200
committerDanilo M. <danix@danix.xyz>2026-10-19 19:49:08 +0200
commitb6965ac87bfffb610bf099812562951cc154738e (patch)
tree0431d2466731a9bc4084843298afb5268ca38985 /examples/tools/test-clone.sh
parent6cb503a50fc49ec26af0f0624141a0c97e75cca4 (diff)
downloaddesktop-assistant-b6965ac87bfffb610bf099812562951cc154738e.tar.gz
desktop-assistant-b6965ac87bfffb610bf099812562951cc154738e.zip
clone tool: clone a public repo into the host's folder
A public URL is cloned into ~/Programming/GIT/<host-folder>/<repo>, the folder chosen by host from ~/.config/desktop-assistant/clone-hosts (github.com, gitlab.com, forge.slackware.nl seeded). An unknown host or an already-cloned repo stops and asks with a concrete action; approving a new host folder appends it to the map, so later clones of that host ask nothing. Update pulls with --ff-only, never clones over the folder. test-clone.sh stubs git and uses a scratch tree and map.
Diffstat (limited to 'examples/tools/test-clone.sh')
-rwxr-xr-xexamples/tools/test-clone.sh95
1 files changed, 95 insertions, 0 deletions
diff --git a/examples/tools/test-clone.sh b/examples/tools/test-clone.sh
new file mode 100755
index 0000000..d84a157
--- /dev/null
+++ b/examples/tools/test-clone.sh
@@ -0,0 +1,95 @@
+#!/bin/bash
+# desktop-assistant tool check: clone.sh against a scratch tree and a stub git.
+# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 as published
+# by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# test-clone.sh: CLONE_ROOT and CLONE_MAP point at a throwaway dir, and git is
+# a stub that records its argv and creates the clone target, so nothing hits
+# the network or the real tree. Prints "ok" or one FAIL line per broken case.
+
+set -u
+here=$(dirname "$0")
+tmp=$(mktemp -d)
+trap 'rm -rf "$tmp"' EXIT
+export CLONE_ROOT=$tmp/git
+export CLONE_MAP=$tmp/clone-hosts
+export GIT_LOG=$tmp/git.log
+: > "$GIT_LOG"
+mkdir -p "$tmp/bin"
+
+cat > "$tmp/bin/git" <<'EOF'
+#!/bin/bash
+printf '%s\n' "$*" >> "$GIT_LOG"
+[ "$1" = clone ] && mkdir -p "${@: -1}"
+exit 0
+EOF
+chmod +x "$tmp/bin/git"
+PATH=$tmp/bin:$PATH
+export PATH
+
+fail=0
+check() { [ "$2" = "$3" ] || { echo "FAIL $1: got '$2', want '$3'"; fail=1; }; }
+contains() { case "$2" in *"$3"*) ;; *) echo "FAIL $1: '$2' lacks '$3'"; fail=1 ;; esac; }
+count() { grep -cF -- "$1" "$GIT_LOG" || true; }
+mapcount() { grep -cF -- "$1" "$CLONE_MAP" || true; }
+
+# Known host, clean copy: seeded map, straight clone, no question.
+out=$("$here/clone.sh" https://github.com/a/b.git)
+check "github clone" "$out" "cloned https://github.com/a/b.git into $CLONE_ROOT/GITHUB/b"
+check "seed" "$(cat "$CLONE_MAP")" \
+ "$(printf '%s\t%s\n' github.com GITHUB gitlab.com GITLAB forge.slackware.nl FORGE)"
+check "clone argv" "$(count "clone -- https://github.com/a/b.git $CLONE_ROOT/GITHUB/b")" "1"
+
+# Trailing slash and .git are not part of the repo name.
+out=$("$here/clone.sh" https://gitlab.com/a/c.git/)
+check "gitlab repo" "$out" "cloned https://gitlab.com/a/c.git into $CLONE_ROOT/GITLAB/c"
+
+# Unknown host: ask, do nothing, name the folder to offer.
+out=$("$here/clone.sh" https://codeberg.org/a/d)
+contains "unknown asks" "$out" "no folder for host codeberg.org"
+contains "unknown label" "$out" "to=CODEBERG"
+check "unknown no clone" "$(count "$CLONE_ROOT/CODEBERG/d")" "0"
+
+# Approved folder: clone there and remember it.
+out=$("$here/clone.sh" https://codeberg.org/a/d CODEBERG)
+check "approved clone" "$out" "cloned https://codeberg.org/a/d into $CLONE_ROOT/CODEBERG/d"
+check "remembered" "$(mapcount 'codeberg.org')" "1"
+check "remembered pair" "$(grep -F 'codeberg.org' "$CLONE_MAP")" \
+ "$(printf 'codeberg.org\tCODEBERG')"
+
+# Next clone of that host asks nothing.
+out=$("$here/clone.sh" https://codeberg.org/a/e)
+check "remembered clone" "$out" "cloned https://codeberg.org/a/e into $CLONE_ROOT/CODEBERG/e"
+
+# Re-approving the same folder does not duplicate the map line.
+"$here/clone.sh" https://codeberg.org/a/f CODEBERG >/dev/null
+check "no duplicate map line" "$(mapcount 'codeberg.org')" "1"
+
+# Already cloned: ask, do not clone again; update pulls.
+out=$("$here/clone.sh" https://github.com/a/b.git)
+contains "already asks" "$out" "already cloned at $CLONE_ROOT/GITHUB/b"
+check "already no reclone" "$(count "clone -- https://github.com/a/b.git")" "1"
+out=$("$here/clone.sh" https://github.com/a/b.git "" 1)
+contains "update says" "$out" "updated $CLONE_ROOT/GITHUB/b"
+check "update argv" "$(count "-C $CLONE_ROOT/GITHUB/b pull --ff-only")" "1"
+
+# Bad input is refused before anything is created.
+"$here/clone.sh" "" >/dev/null 2>&1; check "empty url" "$?" "1"
+"$here/clone.sh" not-a-url >/dev/null 2>&1; check "not a url" "$?" "1"
+"$here/clone.sh" https://github.com/a/.. >/dev/null 2>&1; check "bad repo" "$?" "1"
+"$here/clone.sh" https://codeberg.org/a/z ../escape >/dev/null 2>&1; check "bad to" "$?" "1"
+
+[ $fail = 0 ] && echo "ok"
+exit $fail