LifePlay-Revival/Tools/CheckIntegrity.ps1

88 lines
3.8 KiB
PowerShell
Raw Normal View History

<#
.SYNOPSIS
Tests statiques d'integrite T-STAT-02 a T-STAT-04 (Docs/Migration/03_Plan_Migration_Tests.md).
.DESCRIPTION
-Modules : Content/Modules 5.5 identique a 4.27 (liste et MD5).
-Env : environnement de developpement identique au manifeste du lot L0.
-Ref427 : arbre 4.27 inchange depuis l'empreinte de reference.
-InitRef427 : cree l'empreinte de reference 4.27 (a faire une seule fois, en L0).
Code de sortie 1 si un test echoue.
.EXAMPLE
.\Tools\CheckIntegrity.ps1 -Modules -Env -Ref427
#>
param(
[switch]$Modules,
[switch]$Env,
[switch]$Ref427,
[switch]$InitRef427,
[string]$ProjectRoot = (Split-Path $PSScriptRoot -Parent),
[string]$Root427 = 'D:\Game\LifePlay-master 4.27',
[string]$BackupRoot = 'D:\Game\LifePlay_Backup_5.5'
)
$ErrorActionPreference = 'Stop'
$refCsv = Join-Path $ProjectRoot 'Docs\Migration\etat\L0_ref427.csv'
$failed = 0
function Hash-Tree([string]$Base, [string[]]$Rel) {
foreach ($r in $Rel) {
$p = Join-Path $Base $r
if (-not (Test-Path $p)) { continue }
Get-ChildItem $p -File -Recurse -Force | ForEach-Object {
[pscustomobject]@{ Rel = $_.FullName.Substring($Base.TrimEnd('\').Length + 1); MD5 = (Get-FileHash $_.FullName -Algorithm MD5).Hash }
}
}
}
function Report([string]$Name, [object[]]$Diffs, [int]$Total) {
if ($Diffs) {
$script:failed++
"ECHEC $Name : $(@($Diffs).Count) ecart(s) sur $Total"
$Diffs | Select-Object -First 20 | ForEach-Object { " $_" }
} else { "OK $Name : $Total fichier(s) conformes" }
}
$refSet = @('Source', 'Config', 'LifePlay.uproject', 'Content\BPs', 'Content\Structs', 'Plugins\ModdingExtra\Source', 'Plugins\StreetMap\Source')
if ($InitRef427) {
if (Test-Path $refCsv) { throw "Empreinte deja presente : $refCsv (supprimer volontairement pour la refaire)" }
Hash-Tree $Root427 $refSet | Export-Csv $refCsv -NoTypeInformation -Encoding UTF8
"Empreinte 4.27 ecrite : $refCsv"
}
if ($Modules) {
$a = Hash-Tree $Root427 @('Content\Modules'); $b = Hash-Tree $ProjectRoot @('Content\Modules')
$ha = @{}; $a | ForEach-Object { $ha[$_.Rel] = $_.MD5 }
$hb = @{}; $b | ForEach-Object { $hb[$_.Rel] = $_.MD5 }
$keys = @($ha.Keys) + @($hb.Keys) | Sort-Object -Unique
$d = $keys | Where-Object { $ha[$_] -ne $hb[$_] } | ForEach-Object { if (-not $ha[$_]) { "en plus en 5.5 : $_" } elseif (-not $hb[$_]) { "absent en 5.5 : $_" } else { "different : $_" } }
Report 'T-STAT-02 Modules = 4.27' $d $keys.Count
}
if ($Env) {
$man = Join-Path $BackupRoot 'L0\manifest.csv'
$rows = Import-Csv $man | Where-Object { $_.Rel -match '^(\.claude\\|\.mcp\.json$|Saved\\Backups\\|Saved\\SaveGames\\)' }
$d = foreach ($r in $rows) {
$p = Join-Path $ProjectRoot $r.Rel
if (-not (Test-Path -LiteralPath $p)) { "absent : $($r.Rel)" }
elseif ((Get-FileHash -LiteralPath $p -Algorithm MD5).Hash -ne $r.MD5) {
# Les .sav changent quand on joue : signales mais non bloquants
if ($r.Rel -like 'Saved\SaveGames\*') { Write-Host " (info) sauvegarde de jeu modifiee : $($r.Rel)" } else { "modifie : $($r.Rel)" }
}
}
Report 'T-STAT-03 environnement = L0' $d @($rows).Count
}
if ($Ref427) {
if (-not (Test-Path $refCsv)) { throw "Pas d'empreinte 4.27 : lancer -InitRef427 d'abord" }
$ref = Import-Csv $refCsv
$cur = @{}; Hash-Tree $Root427 $refSet | ForEach-Object { $cur[$_.Rel] = $_.MD5 }
$d = @($ref | Where-Object { $cur[$_.Rel] -ne $_.MD5 } | ForEach-Object { "modifie ou absent : $($_.Rel)" })
$known = @{}; $ref | ForEach-Object { $known[$_.Rel] = 1 }
$d += @($cur.Keys | Where-Object { -not $known[$_] } | ForEach-Object { "nouveau : $_" })
Report 'T-STAT-04 arbre 4.27 inchange' $d @($ref).Count
}
if ($failed) { exit 1 }