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:
CyberMind-FR 2026-05-12 09:49:02 +02:00
parent 6f4bd948a3
commit c74e71d890
2 changed files with 99 additions and 0 deletions

View 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"
}

View 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))