# gov_profile_launcher_v1.1.ps1 param() function Ensure-Dir([string]$p){ if($p -and !(Test-Path $p)){ New-Item -ItemType Directory -Force -Path $p | Out-Null } } function Ask-YesNo([string]$q){ while($true){ $a=Read-Host ($q+' (O/N)'); if($a -in @('O','o','Y','y')){return $true}; if($a -in @('N','n')){return $false} } } function Run-Profile([string]$profile,[string]$mode){ $root="\\DS-918\chatgpt\ChatGPT-Gouvernance-Projets\_registry" $logs=Join-Path $root 'logs'; Ensure-Dir $logs $ts=Get-Date -Format 'yyyyMMdd_HHmmss' $log=Join-Path $logs ('run_'+$profile+'_'+$mode+'_'+$ts+'.txt') if($profile -eq 'HUB'){ $script=Join-Path $root 'scripts\rebuild_bootpack_full_hub_v1.1.ps1' } elseif($profile -eq 'SEEDBOX'){ $script=Join-Path $root 'scripts\rebuild_bootpack_full_seedbox_v1.1.ps1' } else { Write-Host "[ERR] Profil inconnu: $profile"; return } if(!(Test-Path $script)){ Write-Host "[ERR] Script introuvable: $script"; return } if($mode -eq 'Write'){ if(-not (Ask-YesNo "Confirmer l'écriture réelle pour $profile")){ Write-Host "Annulé."; return } } $arg=@('-NoProfile','-ExecutionPolicy','Bypass','-File',$script); if($mode -eq 'Preview'){$arg+='-Preview'}else{$arg+='-Write'} & 'powershell.exe' @arg 2>&1 | Tee-Object -FilePath $log | Out-Null if(Test-Path $log){ Get-Content -LiteralPath $log -Tail 60; 'Log -> '+$log | Write-Host } else { Write-Host "[WARN] Log non trouvé: $log" } } function Audit-Manifest(){ $bp="\\DS-918\chatgpt\ChatGPT-Gouvernance-Projets\_registry\bootpack\bootpack.txt" if(!(Test-Path $bp)){ Write-Host "[ERR] BootPack introuvable: $bp"; return } $raw = Get-Content -LiteralPath $bp -Raw -Encoding UTF8 $blk = [regex]::Match($raw,'(?ms)^\[SYNC_MANIFEST\]\s*(.*?)(?=^\[|\Z)').Groups[1].Value if(-not $blk){ Write-Host "[ERR] Section [SYNC_MANIFEST] absente."; return } $infile = [regex]::Match($blk,'(?mi)^\s*MANIFEST_SHA256\s*:\s*([0-9a-f]+)\s*$').Groups[1].Value.ToLower() $coreLines=@(); foreach($ln in ($blk -split "`r?`n")){ if($ln -match '^\s*MANIFEST_SHA256\s*:'){continue}; $coreLines += $ln.TrimEnd() } $core=[string]::Join("`r`n",$coreLines) $sha=[BitConverter]::ToString([Security.Cryptography.SHA256]::Create().ComputeHash([Text.Encoding]::UTF8.GetBytes($core))).Replace('-','').ToLower() 'InFile = '+$infile | Write-Host 'Recalc = '+$sha | Write-Host 'STATUS = '+($(if($infile -eq $sha){'MATCH'}else{'DIFF'})) | Write-Host } function Fix-Manifest(){ $root="\\DS-918\chatgpt\ChatGPT-Gouvernance-Projets\_registry" $fix =Join-Path $root 'scripts\fix_manifest_sha_v1.1.ps1' if(!(Test-Path $fix)){ Write-Host "[ERR] fix_manifest_sha_v1.1.ps1 introuvable."; return } $logs=Join-Path $root 'logs'; Ensure-Dir $logs $ts=Get-Date -Format 'yyyyMMdd_HHmmss'; $log=Join-Path $logs ('run_fix_manifest_'+$ts+'.txt') & 'powershell.exe' -NoProfile -ExecutionPolicy Bypass -File $fix -Write 2>&1 | Tee-Object -FilePath $log | Out-Null Get-Content -LiteralPath $log -Tail 30; 'Log -> '+$log | Write-Host } function Show-Menu(){ Clear-Host Write-Host "=== GOV PROFILE LAUNCHER v1.1 ===" Write-Host "1) HUB - Preview" Write-Host "2) HUB - Write (commit)" Write-Host "3) SEEDBOX - Preview" Write-Host "4) SEEDBOX - Write (commit)" Write-Host "5) Audit MANIFEST (recalc vs fichier)" Write-Host "6) Corriger MANIFEST_SHA (SAFE-WRITE)" Write-Host "0) Quitter" Write-Host "" } while($true){ Show-Menu $c=Read-Host "Choix" switch($c){ '1' { Run-Profile -profile 'HUB' -mode 'Preview' ; Pause } '2' { Run-Profile -profile 'HUB' -mode 'Write' ; Pause } '3' { Run-Profile -profile 'SEEDBOX' -mode 'Preview' ; Pause } '4' { Run-Profile -profile 'SEEDBOX' -mode 'Write' ; Pause } '5' { Audit-Manifest ; Pause } '6' { Fix-Manifest ; Pause } '0' { break } default { Write-Host "Choix invalide." ; Start-Sleep -Seconds 1 } } }