mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 18:36:55 +00:00
feat(scripts): add agent-worktree library with derive_slug (ref #83)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6f4bd948a3
commit
c74e71d890
22
scripts/lib/agent-worktree-lib.sh
Normal file
22
scripts/lib/agent-worktree-lib.sh
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# shellcheck shell=bash
|
||||
# scripts/lib/agent-worktree-lib.sh
|
||||
# Helpers for scripts/agent-worktree.sh. Sourced, never executed.
|
||||
|
||||
set -uo pipefail
|
||||
|
||||
# Slugify a free-text title into a branch-safe slug.
|
||||
# Rules: lowercase, ASCII-fold via iconv, non-[a-z0-9] -> '-', collapse runs,
|
||||
# trim leading/trailing '-', max 40 chars, fallback 'issue' when empty.
|
||||
derive_slug() {
|
||||
local raw="${1:-}"
|
||||
local s
|
||||
s=$(printf '%s' "$raw" | iconv -f UTF-8 -t ASCII//TRANSLIT 2>/dev/null || printf '%s' "$raw")
|
||||
s=$(printf '%s' "$s" | tr '[:upper:]' '[:lower:]')
|
||||
s=$(printf '%s' "$s" | sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//')
|
||||
if [[ ${#s} -gt 40 ]]; then
|
||||
s="${s:0:40}"
|
||||
s="${s%-}"
|
||||
fi
|
||||
if [[ -z "$s" ]]; then s="issue"; fi
|
||||
printf '%s' "$s"
|
||||
}
|
||||
77
scripts/tests/test-agent-worktree.sh
Executable file
77
scripts/tests/test-agent-worktree.sh
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env bash
|
||||
# Test harness for scripts/agent-worktree.sh
|
||||
# Each `test_*` function is auto-discovered and run in a subshell.
|
||||
set -uo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
LIB="$REPO_ROOT/scripts/lib/agent-worktree-lib.sh"
|
||||
SCRIPT="$REPO_ROOT/scripts/agent-worktree.sh"
|
||||
GH_MOCK="$REPO_ROOT/scripts/tests/fixtures/gh-mock.sh"
|
||||
|
||||
pass=0
|
||||
fail=0
|
||||
failed_names=()
|
||||
|
||||
run_test() {
|
||||
local name="$1"
|
||||
local out
|
||||
if out=$(set -e; "$name" 2>&1); then
|
||||
echo "OK $name"
|
||||
pass=$((pass+1))
|
||||
else
|
||||
echo "FAIL $name"
|
||||
echo "$out" | sed 's/^/ /'
|
||||
fail=$((fail+1))
|
||||
failed_names+=("$name")
|
||||
fi
|
||||
}
|
||||
|
||||
assert_eq() {
|
||||
local expected="$1" actual="$2" label="${3:-value}"
|
||||
if [[ "$expected" != "$actual" ]]; then
|
||||
echo "$label mismatch: expected '$expected' got '$actual'" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_contains() {
|
||||
local haystack="$1" needle="$2"
|
||||
if [[ "$haystack" != *"$needle"* ]]; then
|
||||
echo "expected to contain '$needle' in: $haystack" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Tests below
|
||||
|
||||
test_derive_slug_basic() {
|
||||
source "$LIB"
|
||||
assert_eq "add-tier-manifest-helper-for-apt-staging" "$(derive_slug 'Add tier-manifest helper for APT staging')" "basic slug"
|
||||
}
|
||||
|
||||
test_derive_slug_accents() {
|
||||
source "$LIB"
|
||||
assert_eq "migration-verification-a-valider" "$(derive_slug 'Migration vérification à valider')" "accents"
|
||||
}
|
||||
|
||||
test_derive_slug_truncate_40() {
|
||||
source "$LIB"
|
||||
local out
|
||||
out=$(derive_slug 'this title is intentionally far too long to fit in forty characters')
|
||||
assert_eq "40" "${#out}" "length"
|
||||
assert_eq "this-title-is-intentionally-far-too-long" "$out" "truncated value"
|
||||
}
|
||||
|
||||
test_derive_slug_empty_falls_back() {
|
||||
source "$LIB"
|
||||
assert_eq "issue" "$(derive_slug '')" "empty input"
|
||||
assert_eq "issue" "$(derive_slug '日本語のみ')" "all non-ASCII"
|
||||
}
|
||||
|
||||
# Auto-discover and run
|
||||
mapfile -t tests < <(declare -F | awk '{print $3}' | grep '^test_')
|
||||
for t in "${tests[@]}"; do run_test "$t"; done
|
||||
|
||||
echo "---"
|
||||
echo "passed: $pass failed: $fail"
|
||||
exit $((fail > 0))
|
||||
Loading…
Reference in New Issue
Block a user