358 lines
No EOL
10 KiB
Bash
Executable file
358 lines
No EOL
10 KiB
Bash
Executable file
#!/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 l’ossature 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 d’orientation
|
||
# ----------------------------------------------------------------------------
|
||
|
||
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 |