Files
tilbudgivern/scripts/sync-obsidian-vault.sh
2026-08-17 09:12:03 +02:00

175 lines
5.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
vault_root="$repo_root/obsidian-vault"
documents_root="$vault_root/10 Dokumenter"
index_file="$vault_root/00 Start/Dokumentindeks.md"
active_index_file="$vault_root/00 Start/Aktiv dokumentation.md"
manifest_file="$vault_root/00 Start/Kildemanifest.tsv"
mkdir -p "$documents_root" "$(dirname "$index_file")"
# Kun denne mappe er maskinadministreret. Egne noter andre steder i vaulten bevares.
find "$documents_root" -type f -delete
find "$documents_root" -depth -type d -empty -delete
source_list="$(mktemp)"
index_entries="$(mktemp)"
trap 'rm -f "$source_list" "$index_entries"' EXIT
(
cd "$repo_root"
git -c core.quotepath=false ls-files --cached --others --exclude-standard -- \
'*.md' '*.markdown' ':(exclude)obsidian-vault/**'
) | while IFS= read -r source_path; do
# Et tracked dokument kan være slettet i worktree under en arkivflytning.
# Kun eksisterende, ikke-ignorerede kilder må kopieres til vaulten.
if [[ -f "$repo_root/$source_path" ]]; then
printf '%s\n' "$source_path"
fi
done | LC_ALL=C sort > "$source_list"
printf '%s\n\n' \
'# Dokumentindeks' \
'> [!info] Automatisk genereret' \
'> Kør `./scripts/sync-obsidian-vault.sh` fra projektroden for at opdatere kopier og indeks.' \
"Sidst synkroniseret: $(date '+%Y-%m-%d %H:%M:%S %Z')" \
> "$index_file"
printf '%s\n\n' \
'# Aktiv dokumentation' \
'> [!info] Automatisk genereret' \
'> Dette indeks skjuler arkiveret historik. Brug `Dokumentindeks.md` når ældre beslutninger eller fejlforløb skal findes.' \
"Sidst synkroniseret: $(date '+%Y-%m-%d %H:%M:%S %Z')" \
> "$active_index_file"
printf 'source\tvault_path\n' > "$manifest_file"
document_count=0
while IFS= read -r source_path; do
case "$source_path" in
_archive/*|archive/*|docs/archived/*|tmp/*|_temp/*)
section_order=100
section='Arkiv'
relative_path="$source_path"
;;
.claude/*|.codex/*|.github/*|AGENTS.md|CLAUDE.md|GEMINI.md)
section_order=10
section='AI og Codex'
relative_path="$source_path"
;;
docs/architecture*|docs/*ARCHITECTURE*|docs/*SYSTEM*|docs/MISSION.md)
section_order=20
section='Arkitektur'
relative_path="${source_path#docs/}"
;;
docs/features/*)
section_order=30
section='Funktioner'
relative_path="${source_path#docs/features/}"
;;
docs/guides/*)
section_order=40
section='Vejledninger'
relative_path="${source_path#docs/guides/}"
;;
docs/api/*)
section_order=50
section='API'
relative_path="Produkt/${source_path#docs/api/}"
;;
apitest/*)
section_order=50
section='API'
relative_path="Test/${source_path#apitest/}"
;;
docs/deployment/*|docs/*DEPLOYMENT*|docs/*LOGGING*|docs/*BACKUP*|docs/*PORT*|backend/LOGGING.md)
section_order=60
section='Drift og deployment'
relative_path="$source_path"
;;
tests/*)
section_order=70
section='Test og kvalitet'
relative_path="${source_path#tests/}"
;;
docs/status-reports/*|status.md)
section_order=80
section='Status'
relative_path="Rapporter/${source_path#docs/status-reports/}"
;;
docs/summaries/*)
section_order=80
section='Status'
relative_path="Opsummeringer/${source_path#docs/summaries/}"
;;
docs/plans/*|*PLAN.md|*PLAN_*|*IMPLEMENTATION_PLAN*)
section_order=90
section='Planer'
relative_path="$source_path"
;;
backend/scripts/*)
section_order=110
section='Backend-noter'
relative_path="${source_path#backend/scripts/}"
;;
docs/*)
section_order=120
section='Projektdokumentation'
relative_path="${source_path#docs/}"
;;
*)
section_order=130
section='Projektrod og øvrigt'
relative_path="$source_path"
;;
esac
destination="$documents_root/$section/$relative_path"
mkdir -p "$(dirname "$destination")"
cp -p "$repo_root/$source_path" "$destination"
vault_relative="${destination#"$vault_root/"}"
link_target="${vault_relative%.*}"
title="$(basename "${source_path%.*}")"
printf '%03d\t%s\t%s\t%s\t%s\n' \
"$section_order" "$section" "$link_target" "$title" "$source_path" >> "$index_entries"
printf '%s\t%s\n' "$source_path" "$vault_relative" >> "$manifest_file"
document_count=$((document_count + 1))
done < "$source_list"
current_section=''
active_current_section=''
active_document_count=0
archived_document_count=0
while IFS=$'\t' read -r _ section link_target title source_path; do
if [[ "$current_section" != "$section" ]]; then
printf '\n## %s\n\n' "$section" >> "$index_file"
current_section="$section"
fi
printf -- '- [[%s|%s]] — `%s`\n' "$link_target" "$title" "$source_path" >> "$index_file"
if [[ "$section" == 'Arkiv' ]]; then
archived_document_count=$((archived_document_count + 1))
continue
fi
if [[ "$active_current_section" != "$section" ]]; then
printf '\n## %s\n\n' "$section" >> "$active_index_file"
active_current_section="$section"
fi
printf -- '- [[%s|%s]] — `%s`\n' "$link_target" "$title" "$source_path" >> "$active_index_file"
active_document_count=$((active_document_count + 1))
done < <(LC_ALL=C sort -t $'\t' -k1,1n -k5,5 "$index_entries")
printf '\n---\n\n**I alt: %d dokumenter.**\n' "$document_count" >> "$index_file"
printf '\n---\n\n**Aktive dokumenter: %d. Arkiverede dokumenter: %d.**\n' \
"$active_document_count" "$archived_document_count" >> "$active_index_file"
printf 'Synkroniserede %d Markdown-filer til %s\n' "$document_count" "$vault_root"