Files
Björn RundenandClaude Opus 5.5 7f6b8ebe07 Basis aus 2nd-brain für LPIC-Prüfungsvorbereitung übernommen
Regeln, Standards, Kontextstruktur und Werkzeuge übernommen; 2nd-brain-
Inhalte (Stacks, Ansible-Inventar, Architektur, Knowledge) entfernt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 21:56:53 +01:00

108 lines
3.9 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
#-------------------------------------------------------------------------------
## @file kb_index.sh
## @brief Erzeugt ai/context/knowledge/INDEX.md aus dem Frontmatter aller Einträge
## und prüft die Pflichtfelder (id, title, type, status, updated, owner)
## @author <AUTOR – aus ai/context/responsible.md>
## @owner <VERANTWORTLICH – aus ai/context/responsible.md>
## @assist KI-unterstützt (Claude), geprüft von <AUTOR>
## @version 1.0.0 (07.10.2026)
##
## @usage kb_index.sh [Optionen]
## @options
## @OPTIONS@
## @exit 0 = ok · 1 = Fehler / Index veraltet (--check) · 2 = Aufruffehler
#-------------------------------------------------------------------------------
set -Eeuo pipefail
SCRIPT_PATH="$(readlink -f -- "${BASH_SOURCE[0]}")"
SCRIPT_DIR="${SCRIPT_PATH%/*}"
SCRIPT_NAME="${SCRIPT_PATH##*/}"
# shellcheck source=_functions.sh
source "${SCRIPT_DIR}/_functions.sh" || { echo "FEHLER: ${SCRIPT_DIR}/_functions.sh fehlt" >&2; exit 1; }
B_OPTS+=(
"c|check|flag|0|nur prüfen: Pflichtfelder ok und INDEX.md aktuell?"
"k|kbdir|value:DIR|../ai/context/knowledge|Wurzel der Knowledge-DB (relativ = zum Script)"
)
b_init "$@"
set -- "${ARGS[@]}"
REQUIRED=(id title type status updated owner)
## @brief Liest einen Frontmatter-Wert (einzeilig) aus einer Markdown-Datei
## @param $1 Datei
## @param $2 Schlüssel
## @return 0; Wert auf stdout (leer, wenn nicht vorhanden)
fm_get() {
awk -v key="$2" '
NR == 1 && $0 != "---" { exit }
NR > 1 && $0 == "---" { exit }
NR > 1 {
k = $0; sub(/:.*/, "", k)
if (k == key) { v = $0; sub(/^[^:]*:[ \t]*/, "", v); sub(/[ \t]+#.*$/, "", v); gsub(/^"|"$/, "", v); print v; exit }
}' "$1"
}
## @brief Baut den Index-Inhalt und meldet fehlende Pflichtfelder
## @param $1 KB-Wurzel
## @return 0 ok, 1 mindestens ein Eintrag unvollständig; Markdown auf stdout
build_index() {
local kb="$1" f rel dir last_dir="" key val rc=0 n=0
local -A ids=()
printf '# Knowledge-Index\n\n'
printf '> Automatisch erzeugt von `bin/kb_index.sh` – nicht von Hand bearbeiten.\n'
printf '> Format der Einträge: [README.md](README.md)\n'
while IFS= read -r f; do
rel="${f#"$kb"/}"; dir="${rel%%/*}"
[[ "$dir" == "$rel" ]] && dir="."
for key in "${REQUIRED[@]}"; do
[[ -n "$(fm_get "$f" "$key")" ]] || { berror "${rel}: Pflichtfeld '${key}' fehlt"; rc=1; }
done
val="$(fm_get "$f" id)"
if [[ -n "$val" ]]; then
[[ -n "${ids[$val]:-}" ]] && { berror "${rel}: id '${val}' doppelt (auch ${ids[$val]})"; rc=1; }
ids[$val]="$rel"
fi
if [[ "$dir" != "$last_dir" ]]; then
printf '\n## %s\n\n| id | Titel | Status | Stand | Tags |\n|---|---|---|---|---|\n' "$dir"
last_dir="$dir"
fi
printf '| %s | [%s](%s) | %s | %s | %s |\n' "$val" "$(fm_get "$f" title)" "$rel" \
"$(fm_get "$f" status)" "$(fm_get "$f" updated)" "$(fm_get "$f" tags | tr -d '[]')"
(( ++n ))
done < <(find "$kb" -type f -name '*.md' ! -name 'README.md' ! -name 'INDEX.md' ! -name '_*' | LC_ALL=C sort)
(( n )) || printf '\n_(noch keine Einträge)_\n'
bdebug "${n} Einträge gelesen"
return "$rc"
}
## @brief Hauptablauf
## @return 0 ok, 1 Fehler / veraltet
main() {
(( $# == 0 )) || bdie "Keine Positionsargumente erwartet" 2
local kb rc=0 new
kb="$(readlink -f -- "$(b_abspath "$OPTION_KBDIR")")"
[[ -d "$kb" ]] || { berror "KB-Verzeichnis fehlt: $kb"; return 1; }
b_tmpdir
new="${B_TMP_DIR}/INDEX.md"
build_index "$kb" > "$new" || rc=1
if (( OPTION_CHECK )); then
if ! cmp -s "$new" "${kb}/INDEX.md"; then
berror "INDEX.md ist veraltet – bin/kb_index.sh ausführen"; rc=1
fi
(( rc )) || becho "Knowledge-DB ok"
return "$rc"
fi
if cmp -s "$new" "${kb}/INDEX.md"; then
becho "INDEX.md unverändert"
else
brun cp -- "$new" "${kb}/INDEX.md"
becho "INDEX.md aktualisiert"
fi
return "$rc"
}
main "$@"