diff --git a/.cursor/rules/99-lint-markdow.mdc b/.cursor/rules/99-lint-markdow.mdc new file mode 100644 index 0000000..6924c29 --- /dev/null +++ b/.cursor/rules/99-lint-markdow.mdc @@ -0,0 +1,9 @@ +--- +description: +globs: +alwaysApply: true +--- + +# Lint + +respecter strictement les règles de lint du markdown diff --git a/.gitea/ISSUE_TEMPLATE/bug_report.md b/.gitea/ISSUE_TEMPLATE/bug_report.md index da4e36d..987615c 100644 --- a/.gitea/ISSUE_TEMPLATE/bug_report.md +++ b/.gitea/ISSUE_TEMPLATE/bug_report.md @@ -40,11 +40,13 @@ Si applicable, ajoutez une capture d'écran pour expliquer votre problème. ## 📋 Configuration ### Services Actifs + ```bash docker ps ``` ### Variables d'Environnement + ```bash # Bitcoin Core BITCOIN_NETWORK=signet @@ -60,17 +62,20 @@ SDK_RELAY_PORTS=8090-8095 ## 📝 Logs ### Logs Pertinents -``` + +```txt Logs pertinents ici ``` ### Logs d'Erreur -``` + +```txt Logs d'erreur ici ``` ### Logs de Debug -``` + +```txt Logs de debug ici (si RUST_LOG=debug) ``` diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 463a6c1..32f3b5b 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -3,6 +3,8 @@ name: CI - 4NK Node on: push: branches: [ main, develop ] + tags: + - 'v*' pull_request: branches: [ main, develop ] @@ -238,6 +240,17 @@ jobs: echo "Checking links in $file" done + markdownlint: + name: Markdown Lint + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Run markdownlint + run: | + npm --version || (curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs) + npx -y markdownlint-cli@0.42.0 "**/*.md" --ignore "archive/**" + - name: Check documentation structure run: | # Vérifier la présence des fichiers de documentation essentiels @@ -358,7 +371,7 @@ jobs: release-guard: name: Release Guard runs-on: ubuntu-latest - needs: [code-quality, unit-tests, documentation-tests, security-audit, deployment-checks, bash-required] + needs: [code-quality, unit-tests, documentation-tests, markdownlint, security-audit, deployment-checks, bash-required] steps: - name: Checkout code uses: actions/checkout@v3 @@ -386,6 +399,36 @@ jobs: echo "No guard script (ok)" fi + release-create: + name: Create Release (Gitea API) + runs-on: ubuntu-latest + needs: [release-guard] + if: startsWith(github.ref, 'refs/tags/') + env: + RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }} + GITEA_BASE_URL: ${{ vars.GITEA_BASE_URL }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + - name: Validate token and publish release + run: | + set -e + if [ -z "${RELEASE_TOKEN}" ]; then + echo "RELEASE_TOKEN secret is missing" >&2; exit 1; fi + if [ -z "${GITEA_BASE_URL}" ]; then + GITEA_BASE_URL="https://git.4nkweb.com"; fi + TAG="${GITHUB_REF##*/}" + REPO="${GITHUB_REPOSITORY}" + OWNER="${REPO%%/*}" + NAME="${REPO##*/}" + echo "Publishing release ${TAG} to ${GITEA_BASE_URL}/${OWNER}/${NAME}" + curl -sSf -X POST \ + -H "Authorization: token ${RELEASE_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\",\"draft\":false,\"prerelease\":false}" \ + "${GITEA_BASE_URL}/api/v1/repos/${OWNER}/${NAME}/releases" >/dev/null + echo "Release created" + # Job de tests de performance performance-tests: name: Performance Tests diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..4335f3c --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,11 @@ +{ + "MD013": { + "line_length": 200, + "code_blocks": false, + "tables": false, + "headings": false + }, + "MD024": { + "siblings_only": true + } +} diff --git a/AGENTS.md b/AGENTS.md index 2ab4c8a..4575c66 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,7 @@ # AGENTS.md ## Table des matières + - [Introduction](#introduction) - [Principes communs](#principes-communs) - [Agents fondamentaux](#agents-fondamentaux) @@ -16,6 +17,7 @@ --- ## Introduction + Ce document définit les agents, leurs rôles et leurs responsabilités dans le projet `4NK/4NK_node` et, par extension, tout dépôt dérivé de `4NK_project_template`. Il impose une coordination stricte entre code, documentation, tests, dépendances, CI/CD, synchronisation de template et gouvernance open source. Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` (notamment `41-ssh-automation.mdc` et `42-template-sync.mdc`). @@ -23,35 +25,42 @@ Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` --- ## Principes communs + - Langue exclusive : français. - Pas d’exemples de code applicatif injectés dans la base. - Toute contribution doit contenir une introduction et/ou une conclusion. - Interdiction de secrets en clair dans le dépôt. - Confirmation nécessaire avant `push` et `tag`. - Toute modification impactant des éléments normatifs doit mettre à jour la documentation et le changelog. - - Le flux de publication applique un garde de release (tests/doc/build/alignement version/changelog/tag, latest vs wip). +- Le flux de publication applique un garde de release (tests/doc/build/alignement version/changelog/tag, latest vs wip). --- ## Agents fondamentaux ### Agent Fondation (Responsable) -**Missions** + +#### Missions + - Garantir la conformité éditoriale : français, pas d’exemples applicatifs, introduction/conclusion. - Vérifier la cohérence terminologique. -**Artefacts** +#### Artefacts + - Tous fichiers. --- ### Agent Structure (Responsable) -**Missions** + +#### Missions + - Maintenir l’arborescence canonique (incluant `.cursor/`, `.gitea/`, `scripts/`, `docs/SSH_UPDATE.md`). - Archiver le contenu obsolète dans `archive/` avec métadonnées. - Interdire toute suppression non tracée. -**Artefacts** +#### Artefacts + - `archive/`, `docs/**`, `tests/**`, `.cursor/**`, `.gitea/**`, `scripts/**`, `CHANGELOG.md`. --- @@ -59,33 +68,42 @@ Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` ## Agents spécialisés documentation ### Agent Documentation (Responsable) -**Missions** + +#### Missions + - Mettre à jour `docs/**` selon l’impact des changements. - Tenir `docs/INDEX.md` comme table des matières centrale. - Produire des REX techniques dans `archive/` en cas d’investigations multiples. -**Artefacts** +#### Artefacts + - `docs/**`, `README.md`, `archive/**`. --- ### Agent Données CSV (Responsable) -**Missions** + +#### Missions + - Traiter les CSV comme source des modèles de données (en-têtes multi-lignes inclus). - Exiger une définition complète de toutes les colonnes. - Corriger et documenter les incohérences de types. -**Artefacts** +#### Artefacts + - `docs/API.md`, `docs/ARCHITECTURE.md`, `docs/USAGE.md`. --- ### Agent Documents bureautiques (Consulté) -**Missions** + +#### Missions + - Lire `.docx` via `docx2txt`; proposer des alternatives en cas d’échec. - Documenter les imports dans `docs/INDEX.md`. -**Artefacts** +#### Artefacts + - `docs/**`, `archive/**`. --- @@ -93,22 +111,28 @@ Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` ## Agents spécialisés tests ### Agent Tests (Responsable) -**Missions** + +#### Missions + - Couvrir `unit`, `integration`, `connectivity`, `performance`, `external`. - Gérer `tests/logs` et `tests/reports`. - Exiger des tests verts avant commit. -**Artefacts** +#### Artefacts + - `tests/**`, `docs/TESTING.md`. --- ### Agent Performance (Consulté) -**Missions** + +#### Missions + - Réaliser des benchmarks reproductibles. - Valider l’impact performance avant fusion. -**Artefacts** +#### Artefacts + - `tests/performance/`, `tests/reports/`, `docs/TESTING.md`. --- @@ -116,55 +140,70 @@ Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` ## Agents techniques ### Agent Qualité technique (Responsable) -**Missions** + +#### Missions + - Définir et faire respecter les standards de qualité: lint, formatage, conventions de code, revues. - Superviser l’analyse statique (types, duplication, complexité, sécurité basique) et corriger les écarts. - Assurer l’exécution automatique des contrôles qualité dans la CI et bloquer en cas d’échec. -**Artefacts** +#### Artefacts + - `.gitea/workflows/ci.yml` (jobs de lint/format/type-check), `CHANGELOG.md`, `docs/ARCHITECTURE.md` (section standards). --- ### Agent Dépendances (Responsable) -**Missions** + +#### Missions + - Ajouter les dépendances manquantes lorsque justifié. - Vérifier les dernières versions stables. - Documenter les impacts dans `ARCHITECTURE.md`, `CONFIGURATION.md`, `CHANGELOG.md`. -**Artefacts** +#### Artefacts + - `docs/ARCHITECTURE.md`, `docs/CONFIGURATION.md`, `CHANGELOG.md`. --- ### Agent Compilation (Responsable) -**Missions** + +#### Missions + - Compiler très régulièrement et aux étapes critiques. - Bloquer toute progression en cas d’erreurs de build/runtime. -**Artefacts** +#### Artefacts + - Artefacts de build, scripts d’outillage. --- ### Agent Résolution (Responsable) -**Missions** + +#### Missions + - Conduire la boucle de diagnostic complète : reproduction minimale, logs, bissection, hypothèses, tests ciblés, correctif, non-régression. - Produire un REX quand plusieurs hypothèses ont été testées. -**Artefacts** +#### Artefacts + - `tests/**`, `archive/**` --- ### Agent SSH & scripts (Responsable) -**Missions** + +#### Missions + - Garantir la présence et l’usage correct de `scripts/auto-ssh-push.sh`, `scripts/init-ssh-env.sh`, `scripts/setup-ssh-ci.sh`. - Assurer permissions d’exécution, idempotence, journalisation non sensible, gestion d’erreurs robuste. - Interdire secrets en clair, gérer via secrets CI et variables d’environnement. - Exiger la mise à jour de `docs/SSH_UPDATE.md` à toute évolution des scripts ou des flux SSH. -**Artefacts** +#### Artefacts + - `scripts/**`, `.gitea/workflows/ci.yml`, `docs/SSH_UPDATE.md`, `docs/CONFIGURATION.md`, `CHANGELOG.md`. --- @@ -172,12 +211,15 @@ Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` ## Agents frontend ### Agent Frontend (Responsable) -**Missions** + +#### Missions + - Mettre en place `React.lazy`/`Suspense` (code splitting). - Centraliser l’état (Redux ou Context API). - Abstraire les services de données. -**Artefacts** +#### Artefacts + - `docs/ARCHITECTURE.md`, `docs/TESTING.md`. --- @@ -185,81 +227,102 @@ Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` ## Agents open source et CI ### Agent Open Source (Responsable) -**Missions** + +#### Missions + - Maintenir : `LICENSE`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `docs/OPEN_SOURCE_CHECKLIST.md`. - Vérifier l’alignement continu avec `4NK_node`. -**Artefacts** +#### Artefacts + - Fichiers de gouvernance cités ci-dessus. --- ### Agent Gitea (Responsable) -**Missions** + +#### Missions + - Garantir `.gitea/ISSUE_TEMPLATE/*`, `PULL_REQUEST_TEMPLATE.md`, `.gitea/workflows/ci.yml`. - Documenter la configuration distante dans `docs/GITEA_SETUP.md`. - Déclencher les étapes CI pertinentes (tests, lint, sécurité, vérifs `scripts/`). -**Artefacts** +#### Artefacts + - `.gitea/**`, `docs/GITEA_SETUP.md`. --- ### Agent Versionnage (Responsable) -**Missions** + +#### Missions + - Tenir `CHANGELOG.md` comme source unique de vérité. - Proposer un bump sémantique justifié. - Demander confirmation avant push et tag. - - Orchestrer le `release-guard` (CI + scripts) et consigner latest vs wip. +- Orchestrer le `release-guard` (CI + scripts) et consigner latest vs wip. + +#### Artefacts -**Artefacts** - `CHANGELOG.md`, `docs/RELEASE_PLAN.md`, `docs/ROADMAP.md`. --- ### Agent Sécurité (Responsable) -**Missions** + +#### Missions + - Assurer une vigilance continue sécurité sur le code, la config et la CI. - Orchestrer l’audit de sécurité automatisé: `scripts/security/audit.sh` (cargo audit, npm audit, scan secrets). - Interdire l’introduction de secrets en clair et exiger la rotation des secrets CI. - Valider les permissions sensibles (clés, cookies, conf) et la non-exposition d’endpoints privés. - Bloquer toute release si l’audit de sécurité échoue (intégré au `release-guard`). -**Artefacts** +#### Artefacts + - `scripts/security/audit.sh`, `.gitea/workflows/ci.yml` (job `security-audit`), `docs/SECURITY_AUDIT.md`, `docs/CONFIGURATION.md`. --- ### Agent Déploiement (Responsable) -**Missions** + +#### Missions + - Définir et documenter la stratégie de déploiement (environnements, prérequis, secrets, rollbacks). - Vérifier la présence et la cohérence des artefacts de déploiement et des variables d’environnement requises. - Intégrer des contrôles CI « deployment-checks » avant toute release; coordonner avec `release-guard`. -**Artefacts** +#### Artefacts + - `docs/DEPLOYMENT.md`, `.gitea/workflows/ci.yml` (job `deployment-checks`), `CHANGELOG.md`, `docs/RELEASE_PLAN.md`. --- ### Agent Gouvernance du Template (Accountable) -**Missions** + +#### Missions + - Garantir la cohérence d’ensemble du template (règles Cursor, CI, scripts, docs). - Examiner les issues « Template Feedback », arbitrer et prioriser. - Orchestrer la montée de version du template (`TEMPLATE_VERSION`) et le `CHANGELOG.md`. - Communiquer les changements aux projets consommateurs. -**Artefacts** +#### Artefacts + - `.cursor/rules/**`, `.gitea_template/**`, `docs/TEMPLATE_*`, `TEMPLATE_VERSION`, `CHANGELOG.md`. --- ### Agent Adaptation Projet (Responsable) -**Missions** + +#### Missions + - Accompagner l’adaptation locale du template (CI, docs, `AGENTS.md`). - S’assurer que `security-audit` et `release-guard` ne sont pas retirés. - Remonter en feedback toute amélioration générique. -**Artefacts** +#### Artefacts + - `.gitea/workflows/ci.yml`, `docs/INDEX.md`, `docs/SECURITY_AUDIT.md`, `AGENTS.md`, `LOCAL_OVERRIDES.yml` (si utilisé). --- @@ -267,32 +330,40 @@ Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` ## Agents de synchronisation et dérogations ### Agent Synchronisation de template (Accountable) -**Références** + +#### Références + - `.4nk-sync.yml` (manifeste), `TEMPLATE_VERSION` (pointeur), `.gitea/workflows/template-sync.yml` (CI dédiée). - Règles Cursor : `.cursor/rules/42-template-sync.mdc` et `.cursor/rules/10-project-structure.mdc`. -**Missions** +#### Missions + - Assurer l’alignement automatique sur le template pour : `.cursor/**`, `.gitea/**`, `AGENTS.md`, `scripts/**`, `docs/SSH_UPDATE.md`. - Déclencher/valider la PR `[template-sync]` créée par la CI. - Exiger la mise à jour de `CHANGELOG.md` et `docs/INDEX.md` après synchronisation. - Vérifier l’intégrité (`manifest_checksum`, checksums de fichiers si publiés), les permissions, l’absence de secrets. - Mettre à jour `TEMPLATE_VERSION` dans la PR. -**Artefacts** +#### Artefacts + - `.4nk-sync.yml`, `TEMPLATE_VERSION`, `.cursor/**`, `.gitea/**`, `AGENTS.md`, `scripts/**`, `docs/SSH_UPDATE.md`, `CHANGELOG.md`. --- ### Agent Dérogations locales (Responsable) -**Références** + +#### Références + - `LOCAL_OVERRIDES.yml` (facultatif, mais recommandé). -**Missions** +#### Missions + - Enregistrer toute divergence locale dans le périmètre synchronisé (path, raison, propriétaire, échéance). - Faire respecter : seules les dérogations listées et non expirées sont tolérées par la CI. - Auditer périodiquement et résorber les dérogations. -**Artefacts** +#### Artefacts + - `LOCAL_OVERRIDES.yml`, `CHANGELOG.md` (mentionner les dérogations significatives). --- @@ -323,4 +394,5 @@ Les règles opérationnelles détaillées sont précisées dans `.cursor/rules/` Quand tu fais une commande ou un requète complexe, explique là avant de la lancer. ## Conclusion + Ce `AGENTS.md` mis à jour introduit l’**Agent Synchronisation de template** et l’**Agent Dérogations locales**, renforce l’**Agent SSH & scripts**, et rattache l’ensemble aux règles Cursor et à la CI Gitea. La matrice de coordination formalise les validations obligatoires pour chaque type de changement, garantissant cohérence structurelle, qualité documentaire, sécurité, traçabilité et stabilité à long terme sur tous les projets issus de `4NK_project_template`. diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b0d5ca..2331916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,12 +19,15 @@ et ce projet adhère au [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Standards: `docs/QUALITY_STANDARDS.md`, `docs/OPEN_SOURCE_GUIDE.md` - Fallback PowerShell pour tous les agents (`scripts/agents/run.ps1`) et normalisation: bash recommandé, PS en secours - CI: contrôle `bash-required` et prérequis `scripts/agents/run.sh` avant release-guard + - CI: job `markdownlint` pour contrôler les lints Markdown (MD013/MD024/MD036) + - CI: job `release-create` pour publier une release via l’API Gitea (secret `RELEASE_TOKEN`) ### Changed - Documentation projet réécrite à partir des modèles `docs/templates/**` (générique, non applicative) - `docs/INDEX.md` mis à jour (liens Déploiement et SSH) - Alignement documentaire sur 4NK_template (titres, liens Gitea, wording) dans docs/** - Raccourcissement guides: `docs/SECURITY_AUDIT.md`, `docs/RELEASE_PLAN.md`, `docs/ROADMAP.md` (versions génériques concises) + - CI: déclenchement sur tags `v*` pour la publication de release ## [2025.08] - 2025-08-27 @@ -36,7 +39,7 @@ et ce projet adhère au [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Fixed -### Added +### Added (suite) - Infrastructure de tests complète avec organisation par catégorie - Scripts d'exécution automatisés pour les tests - Documentation technique complète (Architecture, API) @@ -44,13 +47,13 @@ et ce projet adhère au [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Scripts de maintenance et nettoyage automatique - Garde de release (Cursor rule + scripts) imposant tests/doc/build/cohérence version/changelog/tag -### Changed +### Changed (suite) - Réorganisation complète de la structure des tests - Amélioration de la documentation avec guides détaillés - Optimisation des scripts de démarrage et redémarrage - CI Gitea: ajout d’un job release-guard (contrôles pré‑push/tag) -### Fixed +### Fixed (suite) - Correction des problèmes de connectivité entre services - Amélioration de la gestion des erreurs dans les tests - Correction des configurations Docker diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 752128d..9bcb8ee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -145,7 +145,7 @@ docs(api): update WebSocket message format test(integration): add multi-relay sync tests ``` -**Types :** +#### Types - `feat` - Nouvelle fonctionnalité - `fix` - Correction de bug - `docs` - Documentation diff --git a/SECURITY.md b/SECURITY.md index eaf56dc..71f4e09 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -8,7 +8,7 @@ Nous prenons la sécurité très au sérieux. Si vous découvrez une vulnérabil **NE PAS** créer d'issue publique pour les vulnérabilités de sécurité. -**À la place :** +#### À la place 1. Envoyez un email à [security@4nkweb.com](mailto:security@4nkweb.com) 2. Incluez "SECURITY VULNERABILITY" dans l'objet 3. Décrivez la vulnérabilité de manière détaillée diff --git a/docs/project/CONFIGURATION.md b/docs/project/CONFIGURATION.md index 5c763e8..cc94cf0 100644 --- a/docs/project/CONFIGURATION.md +++ b/docs/project/CONFIGURATION.md @@ -1,13 +1,23 @@ # Configuration — 4NK_template (projet) ## Variables d’environnement (CI) + - Secrets CI uniquement (pas de secrets en clair) - Variables agents : OPENAI_API_KEY, OPENAI_MODEL, OPENAI_API_BASE, OPENAI_TEMPERATURE + - Secret release: RELEASE_TOKEN (publication des releases via l’API Gitea) + - Variable optionnelle: GITEA_BASE_URL (ex: `https://git.4nkweb.com`) ## Conventions + - Retours de ligne normalisés par CI - Dossiers `tests/logs` et `tests/reports` réservés aux artefacts ## Pré-requis agents + - bash requis (job CI `bash-required`) - Fallback PowerShell utilisable localement + +## Lints Markdown + +- Configuration: `.markdownlint.json` (MD013 à 200 colonnes, MD024 en siblings_only) +- CI: job `markdownlint` exécute `markdownlint-cli` sur tous les `.md` (hors `archive/**`) diff --git a/docs/project/GITEA_SETUP.md b/docs/project/GITEA_SETUP.md index 845306a..24f19d3 100644 --- a/docs/project/GITEA_SETUP.md +++ b/docs/project/GITEA_SETUP.md @@ -10,12 +10,17 @@ - Mise à jour obligatoire de la branche avant merge ## 3. Secrets et variables -- Secrets: `OPENAI_API_KEY` (optionnel), secrets de déploiement -- Variables: paramètres de CI non sensibles +- Secrets: `OPENAI_API_KEY` (optionnel), `RELEASE_TOKEN` (obligatoire pour publier les releases via API Gitea) +- Variables: paramètres de CI non sensibles, ex: `OPENAI_MODEL`, `OPENAI_API_BASE`, `OPENAI_TEMPERATURE`, `GITEA_BASE_URL` + +### Ajouter `RELEASE_TOKEN` +- Aller dans Repository Settings → Secrets → New Repository Secret +- Nom: `RELEASE_TOKEN` ; Valeur: un token personnel avec portée API sur le dépôt +- Le job `release-create` utilisera ce secret lors d’un push de tag `v*` ## 4. Workflows requis - `code-quality`, `unit-tests`, `documentation-tests`, `security-audit` -- `deployment-checks`, `bash-required`, `release-guard` +- `deployment-checks`, `bash-required`, `markdownlint`, `release-guard`, `release-create` - (Optionnels) `agents-smoke`, `openia-agents` ## 5. Processus PR diff --git a/scripts/utils/check_md024.ps1 b/scripts/utils/check_md024.ps1 new file mode 100644 index 0000000..000c6d1 --- /dev/null +++ b/scripts/utils/check_md024.ps1 @@ -0,0 +1,47 @@ +Param( + [string]$Root = "." +) + +$ErrorActionPreference = "Stop" + +$files = Get-ChildItem -Path $Root -Recurse -Filter *.md | Where-Object { $_.FullName -notmatch '\\archive\\' } +$had = $false +foreach ($f in $files) { + try { + $lines = Get-Content -LiteralPath $f.FullName -Encoding UTF8 -ErrorAction Stop + } catch { + Write-Warning ("Impossible de lire: {0} — {1}" -f $f.FullName, $_.Exception.Message) + continue + } + $map = @{} + $firstMap = @{} + $dups = @{} + for ($i = 0; $i -lt $lines.Count; $i++) { + $line = $lines[$i] + if ($line -match '^\s{0,3}#{1,6}\s+(.*)$') { + $t = $Matches[1].Trim() + $norm = ([regex]::Replace($t, '\s+', ' ')).ToLowerInvariant() + if ($map.ContainsKey($norm)) { + if (-not $dups.ContainsKey($norm)) { + $dups[$norm] = New-Object System.Collections.ArrayList + $firstMap[$norm] = $map[$norm] + } + [void]$dups[$norm].Add($i + 1) + } else { + $map[$norm] = $i + 1 + } + } + } + if ($dups.Keys.Count -gt 0) { + $had = $true + Write-Output "=== $($f.FullName) ===" + foreach ($k in $dups.Keys) { + $first = $firstMap[$k] + $others = ($dups[$k] -join ', ') + Write-Output ("Heading: '{0}' first@{1} duplicates@[{2}]" -f $k, $first, $others) + } + } +} +if (-not $had) { + Write-Output "No duplicate headings detected." +}