aboutsummaryrefslogtreecommitdiffstats
path: root/.extras
diff options
context:
space:
mode:
Diffstat (limited to '.extras')
-rwxr-xr-x.extras/test-build96
-rw-r--r--.extras/test-logic.sh26
2 files changed, 122 insertions, 0 deletions
diff --git a/.extras/test-build b/.extras/test-build
index 4d3f158..fa24fa6 100755
--- a/.extras/test-build
+++ b/.extras/test-build
@@ -132,10 +132,106 @@ EOF
fi
}
+# =============================================================================
+# SBo tree lookup
+# =============================================================================
+# In this tool there is one active tree per run, but the resolver reads an array
+# named SBO_TREE_ROOTS so the ported logic and its self-check match sbo-batch-test.
+# main() sets SBO_TREE_ROOTS=("$ACTIVE_TREE") after require_config.
+declare -a SBO_TREE_ROOTS=()
+
+find_slackbuild_dir() {
+ local prog="$1" root d
+ for root in "${SBO_TREE_ROOTS[@]}"; do
+ [[ -d "$root" ]] || continue
+ for d in "$root"/*/"$prog"; do
+ if [[ -d "$d" && -f "$d/$prog.info" ]]; then
+ echo "$d"; return 0
+ fi
+ done
+ done
+ return 1
+}
+
+category_of() { basename "$(dirname "$1")"; }
+pkg_key() { echo "$(category_of "$1")/$(basename "$1")"; }
+
+read_requires() {
+ local info="$1"
+ # shellcheck disable=SC1090
+ ( set +u; source "$info"; echo "${REQUIRES:-}" )
+}
+
+version_of() {
+ local dir="$1"
+ local info="$dir/$(basename "$dir").info"
+ [[ -f "$info" ]] || return
+ local v; v="$(grep -m1 '^VERSION=' "$info" | cut -d'"' -f2)"
+ echo "$v"
+}
+
+# =============================================================================
+# DEPENDENCY RESOLUTION (topo sort + cycle detection, LOCAL tree only)
+# =============================================================================
+declare -a RESOLVED_ORDER=()
+declare -A UNMET=()
+declare -a CYCLES=()
+declare -A HAS_README=()
+declare -A _vstate=()
+
+# Is a prog already present in the container base? Overridden at build time to
+# consult the image; in resolution we treat "in base" as a callback so the pure
+# topo logic stays testable. Default: not in base (self-check has no base db).
+installed_in_base() { return 1; }
+
+_resolve_visit() {
+ local dir="$1" parent="$2"
+ local key; key="$(basename "$dir")"
+
+ if [[ "${_vstate[$dir]:-}" == "1" ]]; then return 0; fi
+ if [[ "${_vstate[$dir]:-}" == "0" ]]; then
+ CYCLES+=("cycle involving $key (pulled in via $parent)")
+ return 1
+ fi
+ _vstate["$dir"]=0
+
+ local info="$dir/$(basename "$dir").info"
+ local req tok depdir rc=0
+ req="$(read_requires "$info")"
+ for tok in $req; do
+ if [[ "$tok" == "%README%" ]]; then
+ HAS_README["$dir"]=1
+ continue
+ fi
+ if depdir="$(find_slackbuild_dir "$tok")"; then
+ _resolve_visit "$depdir" "$key" || rc=1
+ elif installed_in_base "$tok"; then
+ :
+ else
+ UNMET["$tok"]="needed by $key"
+ rc=1
+ fi
+ done
+
+ _vstate["$dir"]=1
+ RESOLVED_ORDER+=("$dir")
+ return $rc
+}
+
+resolve_target() {
+ local dir="$1"
+ RESOLVED_ORDER=()
+ CYCLES=()
+ UNMET=()
+ _vstate=()
+ _resolve_visit "$dir" "(top)"
+}
+
main() {
parse_args "$@"
init_color
require_config
+ SBO_TREE_ROOTS=("$ACTIVE_TREE")
}
main "$@"
diff --git a/.extras/test-logic.sh b/.extras/test-logic.sh
index 81a0841..027fdb9 100644
--- a/.extras/test-logic.sh
+++ b/.extras/test-logic.sh
@@ -44,6 +44,32 @@ VERSION_ID="15.0"; select_version_paths
[[ "$ACTIVE_TREE" == "/trees/stable" ]] && ok "15.0 -> stable tree" || bad "stable tree wrong: [$ACTIVE_TREE]"
[[ "$ACTIVE_IMAGE" == "sbo-testbuild:15.0" ]] && ok "15.0 -> stable image" || bad "stable image wrong: [$ACTIVE_IMAGE]"
+# --- resolution -------------------------------------------------------------
+# Fake SBo tree under one category. mk <prog> "<REQUIRES>".
+mk() { mkdir -p "$T/cat/$1"; echo "REQUIRES=\"$2\"" > "$T/cat/$1/$1.info"; }
+mk c ""
+mk b "c"
+mk a "b %README%"
+mk d "nonexistentpkg"
+mk e "f"
+mk f "e"
+mk g "b"
+
+SBO_TREE_ROOTS=("$T") # resolver reads this global (set by select in real runs)
+
+resolve_target "$T/cat/a"
+order=""; for x in "${RESOLVED_ORDER[@]}"; do order+="$(basename "$x") "; done
+order="${order% }"
+[[ "$order" == "c b a" ]] && ok "topo order c b a" || bad "topo order, got: [$order]"
+[[ "${HAS_README[$T/cat/a]:-}" == "1" ]] && ok "%README% recorded" || bad "%README% not recorded"
+[[ ${#UNMET[@]} -eq 0 ]] && ok "no false unmet" || bad "unexpected unmet"
+
+resolve_target "$T/cat/d"
+[[ ${#UNMET[@]} -eq 1 ]] && ok "unmet-dep caught" || bad "unmet-dep missed"
+
+resolve_target "$T/cat/e"
+[[ ${#CYCLES[@]} -ge 1 ]] && ok "cycle caught" || bad "cycle missed"
+
echo
echo "$pass passed, $fail failed"
[[ $fail -eq 0 ]] || exit 1