alliance-boreale/migrate-alliance-boreale-v2.sh

358 lines
10 KiB
Bash
Raw Normal View History

2026-03-09 18:23:06 -04:00
#!/usr/bin/env bash
set -Eeuo pipefail
# ============================================================================
# migrate-alliance-boreale-v2.sh
#
# Migration prudente vers une structure canonique du dépôt Alliance Boréale.
#
# Principes :
# - DRY_RUN=1 par défaut
# - ne supprime rien
# - n'écrase rien silencieusement
# - journalise tout
# - évite les auto-déplacements de dossier
#
# Usage :
# bash migrate-alliance-boreale-v2.sh
# DRY_RUN=0 bash migrate-alliance-boreale-v2.sh
# ============================================================================
ROOT="${1:-.}"
cd "$ROOT"
DRY_RUN="${DRY_RUN:-1}"
STAMP="$(date +%Y%m%d-%H%M%S)"
LOG_DIR=".migration"
LOG_FILE="${LOG_DIR}/migration-v2-${STAMP}.log"
mkdir -p "$LOG_DIR"
log() {
echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOG_FILE"
}
run() {
if [[ "$DRY_RUN" == "1" ]]; then
log "DRY-RUN: $*"
else
log "RUN: $*"
eval "$@" | tee -a "$LOG_FILE"
fi
}
exists() {
[[ -e "$1" ]]
}
ensure_dir() {
local d="$1"
[[ -d "$d" ]] || run "mkdir -p \"$d\""
}
safe_mv() {
local src="$1"
local dst="$2"
if [[ ! -e "$src" ]]; then
log "SKIP: source absente: $src"
return 0
fi
if [[ "$src" == "$dst" ]]; then
log "SKIP: source et destination identiques: $src"
return 0
fi
ensure_dir "$(dirname "$dst")"
if [[ -e "$dst" ]]; then
local backup="${dst}.pre-migration-${STAMP}"
log "CONFLIT: destination existe: $dst"
run "mv \"$dst\" \"$backup\""
fi
run "mv \"$src\" \"$dst\""
}
safe_mkdir_tree() {
for d in "$@"; do
ensure_dir "$d"
done
}
move_if_exists() {
local src="$1"
local dst="$2"
exists "$src" && safe_mv "$src" "$dst" || log "SKIP: absent: $src"
}
quarantine_if_exists() {
local src="$1"
local bucket="$2"
if exists "$src"; then
ensure_dir "$bucket"
safe_mv "$src" "$bucket/$(basename "$src")"
fi
}
create_readme_if_absent() {
local path="$1"
local content="$2"
if [[ ! -e "$path" ]]; then
ensure_dir "$(dirname "$path")"
if [[ "$DRY_RUN" == "1" ]]; then
log "DRY-RUN: création de $path"
else
printf "%s\n" "$content" > "$path"
log "RUN: création de $path"
fi
fi
}
log "Début migration v2"
log "ROOT=$ROOT"
log "DRY_RUN=$DRY_RUN"
# ----------------------------------------------------------------------------
# 1) Créer uniquement les branches structurelles sûres
# ----------------------------------------------------------------------------
log "Création de lossature cible"
safe_mkdir_tree \
docs \
infrastructure \
operations \
archives \
tooling \
security \
docs/decisions \
docs/diffusion \
archives/pre-migration \
archives/legacy-docs \
archives/obsolete
# Répertoires feuilles qui ne reçoivent pas un mv de dossier entier existant
safe_mkdir_tree \
docs/decisions/adr \
docs/rfc \
docs/diffusion/conferences \
docs/diffusion/site \
docs/diffusion/visuels \
docs/diffusion/recrutement \
operations/runbooks \
operations/evidence \
operations/procedures \
operations/checklists \
infrastructure/opentofu \
infrastructure/cloud-init \
infrastructure/netbox \
infrastructure/templates/proxmox
# ----------------------------------------------------------------------------
# 2) Déplacer les blocs racine évidents
# ----------------------------------------------------------------------------
log "Déplacement des blocs racine évidents"
move_if_exists "ansible" "infrastructure/ansible"
move_if_exists "templates" "infrastructure/templates"
move_if_exists "evidence" "operations/evidence"
move_if_exists "configure" "tooling/configure"
# ----------------------------------------------------------------------------
# 3) Réorganiser docs/ par familles
# ----------------------------------------------------------------------------
if exists "docs"; then
log "Réorganisation de docs/"
# Dossiers historiques -> familles cibles
move_if_exists "docs/00-fondements" "docs/fondements"
move_if_exists "docs/10-architecture" "docs/architecture"
move_if_exists "docs/40-ecosystemes" "docs/ecosystemes"
move_if_exists "docs/constitution" "docs/gouvernance"
move_if_exists "docs/20-rag" "docs/corpus-a-integrer"
move_if_exists "docs/vieustoq" "archives/legacy-docs/vieustoq"
# engineering / guides / opération
move_if_exists "docs/engineering" "docs/guides-engineering"
move_if_exists "docs/guides" "docs/guides"
move_if_exists "docs/opération" "operations/procedures"
# pile opérateur -> recentrage
move_if_exists "docs/pile opérateur/adr" "docs/decisions/adr"
move_if_exists "docs/pile opérateur/pol" "docs/politiques"
move_if_exists "docs/pile opérateur/runbooks" "operations/runbooks"
move_if_exists "docs/pile opérateur/evidence" "operations/evidence/pile-operateur"
move_if_exists "docs/pile opérateur/configs" "operations/procedures/pile-operateur-configs"
# Ce qui reste du dossier "pile opérateur" part en quarantaine s'il existe encore
quarantine_if_exists "docs/pile opérateur/README.md" "archives/pre-migration/docs-pile-operateur"
quarantine_if_exists "docs/pile opérateur" "archives/pre-migration"
# annexes -> corpus à intégrer
move_if_exists "docs/50-annexes" "docs/corpus-a-integrer-annexes"
# assets / diffusion
move_if_exists "docs/assets" "docs/diffusion/visuels/assets"
# fichiers de diffusion
move_if_exists "docs/Alliance_Boreale_Conferences.pptx" "docs/diffusion/conferences/Alliance_Boreale_Conferences.pptx"
move_if_exists "docs/Conference_01_Rideau_ou_Coffre_Fort.pptx" "docs/diffusion/conferences/Conference_01_Rideau_ou_Coffre_Fort.pptx"
move_if_exists "docs/Conference_02_Colonisation_Numerique.pptx" "docs/diffusion/conferences/Conference_02_Colonisation_Numerique.pptx"
move_if_exists "docs/2026-02-03 - Présentation d'Alliance Boréale - Rencontres Linux.odp" "docs/diffusion/conferences/2026-02-03-Rencontres-Linux.odp"
move_if_exists "docs/alliance_boreale_site.html" "docs/diffusion/site/alliance_boreale_site.html"
move_if_exists "docs/alliance_boreale_recrutement.docx" "docs/diffusion/recrutement/alliance_boreale_recrutement.docx"
# fichiers racine documentaires à classer proprement
move_if_exists "docs/00_Etat_Depot_Vivant_v1.md" "docs/gouvernance/00_Etat_Depot_Vivant_v1.md"
move_if_exists "docs/00_Glossaire_biomimetique_autopoietique_v3.md" "docs/modele-glossaire.md"
move_if_exists "docs/00_Modele_8_couches_biomimetique_autopoietique_v3.md" "docs/modele-8-couches.md"
move_if_exists "docs/00_Nomenclature_v4.md" "docs/nomenclature-v4.md"
move_if_exists "docs/06 - Controles_Conformite_Label_Prestige_par_Couche_v1.0.md" "docs/politiques/06-Controles_Conformite_Label_Prestige_par_Couche_v1.0.md"
# divers à trier plus tard
for f in \
"docs/index.md" \
"docs/linkedin_post.md" \
"docs/TODO.md" \
"docs/TRANSMISSION.md"
do
if exists "$f"; then
move_if_exists "$f" "docs/corpus-a-integrer/$(basename "$f")"
fi
done
fi
# ----------------------------------------------------------------------------
# 4) Corriger certaines branches créées implicitement
# ----------------------------------------------------------------------------
log "Consolidation des branches documentaires"
# Si gouvernance n'existe pas encore après déplacement depuis constitution
ensure_dir "docs/gouvernance"
ensure_dir "docs/corpus-a-integrer"
ensure_dir "docs/politiques"
# Si les fichiers modèle ont été déplacés en racine docs, on leur donne une maison
ensure_dir "docs/modele"
move_if_exists "docs/modele-glossaire.md" "docs/modele/00_Glossaire_biomimetique_autopoietique_v3.md"
move_if_exists "docs/modele-8-couches.md" "docs/modele/00_Modele_8_couches_biomimetique_autopoietique_v3.md"
move_if_exists "docs/nomenclature-v4.md" "docs/modele/00_Nomenclature_v4.md"
# Si on a guides-engineering, le ranger sous guides
if exists "docs/guides-engineering"; then
ensure_dir "docs/guides"
move_if_exists "docs/guides-engineering" "docs/guides/engineering"
fi
# Si corpus-a-integrer-annexes existe, le ranger sous corpus-a-integrer
if exists "docs/corpus-a-integrer-annexes"; then
ensure_dir "docs/corpus-a-integrer"
move_if_exists "docs/corpus-a-integrer-annexes" "docs/corpus-a-integrer/annexes"
fi
# ----------------------------------------------------------------------------
# 5) Doubles probables -> quarantaine prudente
# ----------------------------------------------------------------------------
log "Mise en quarantaine des doublons probables"
ensure_dir "archives/pre-migration/duplicates"
for f in \
"docs/fondements/00-manifeste.md" \
"docs/fondements/00 - Manifeste.md" \
"docs/corpus-a-integrer/03_Cadre_Conformite_Label_Prestige(1).md" \
"docs/corpus-a-integrer/devis(2).md"
do
if exists "$f"; then
move_if_exists "$f" "archives/pre-migration/duplicates/$(basename "$f")"
fi
done
# ----------------------------------------------------------------------------
# 6) README dorientation
# ----------------------------------------------------------------------------
create_readme_if_absent "docs/README.md" \
"# Documentation canonique
Ce dossier contient la documentation de référence de l'Alliance Boréale.
Branches principales :
- fondements
- modele
- architecture
- gouvernance
- decisions
- politiques
- ecosystemes
- guides
- corpus-a-integrer
- diffusion
"
create_readme_if_absent "infrastructure/README.md" \
"# Infrastructure
Contient l'implémentation opératoire :
- ansible
- opentofu
- cloud-init
- templates
- netbox
"
create_readme_if_absent "operations/README.md" \
"# Operations
Contient :
- runbooks
- evidence
- procedures
- checklists
"
create_readme_if_absent "archives/README.md" \
"# Archives
Contient :
- legacy
- variantes remplacées
- artefacts déplacés pendant migration
"
# ----------------------------------------------------------------------------
# 7) Rapport final
# ----------------------------------------------------------------------------
log "Migration v2 terminée"
log "Journal: $LOG_FILE"
cat <<EOF
Terminé.
Mode actuel :
DRY_RUN=${DRY_RUN}
Commande conseillée d'abord :
DRY_RUN=1 bash $(basename "$0")
Puis exécution réelle :
DRY_RUN=0 bash $(basename "$0")
Ensuite :
git status
find docs infrastructure operations archives -maxdepth 2 -type d | sort
Zones à réviser manuellement :
- docs/corpus-a-integrer/
- archives/pre-migration/duplicates/
- archives/legacy-docs/
EOF