TH1/Tools/GitCheckpoint.ps1

373 lines
14 KiB
PowerShell

param(
[switch]$StagedOnly,
[switch]$Strict
)
$ErrorActionPreference = "Stop"
$repoRoot = git rev-parse --show-toplevel 2>$null
if (-not $repoRoot) {
throw "Not inside a git repository."
}
$repoRoot = [System.IO.Path]::GetFullPath($repoRoot.Trim())
Set-Location $repoRoot
function Get-GitPath([string]$Line) {
if ($Line.Length -lt 4) {
return $null
}
$path = $Line.Substring(3).Trim()
if ($path -match ' -> ') {
$path = ($path -split ' -> ')[-1].Trim()
}
return $path -replace '\\', '/'
}
function Test-PathLike([string]$Path, [string[]]$Patterns) {
foreach ($pattern in $Patterns) {
if ($Path -like $pattern) {
return $true
}
}
return $false
}
$advisoryExportPatterns = @(
'Unity/Assets/Resources/Export/*',
'Unity/Assets/BundleResources/Export/*',
'Tools/Multilingual.xlsx',
'Tools/MultilingualTxt.txt'
)
$buildArtifactPatterns = @(
'Unity/Assets/StreamingAssets/HybridCLR/*',
'Unity/Assets/StreamingAssets/Bundles/*',
'HybridCLRData/*',
'Library/*',
'Temp/*',
'Logs/*',
'Obj/*',
'Build/*',
'Builds/*'
)
$largeGraphifyPatterns = @(
'graphify-out/graph.json',
'graphify-out/.graphify_python',
'graphify-out/needs_update',
'graphify-out/cache/*',
'graphify-out/converted/*',
'graphify-out/obsidian/*',
'Unity/graphify-out/graph.json',
'Unity/graphify-out/.graphify_python',
'Unity/graphify-out/needs_update',
'Unity/graphify-out/cache/*',
'Unity/graphify-out/converted/*',
'Unity/graphify-out/obsidian/*'
)
$statusLines = @(git status --short)
$paths = @()
foreach ($line in $statusLines) {
$path = Get-GitPath $line
if ($path) {
$paths += $path
}
}
if ($StagedOnly) {
$paths = @(git diff --cached --name-only | ForEach-Object { $_ -replace '\\', '/' })
}
Write-Host "Repository: $repoRoot"
Write-Host ""
Write-Host "Status:"
if ($statusLines.Count -eq 0) {
Write-Host " clean"
} else {
$statusLines | ForEach-Object { Write-Host " $_" }
}
Write-Host ""
Write-Host "Diff stat:"
if ($StagedOnly) {
git diff --cached --stat
} else {
git diff --stat
}
$advisoryGenerated = @($paths | Where-Object { Test-PathLike $_ $advisoryExportPatterns } | Sort-Object -Unique)
$artifacts = @($paths | Where-Object { Test-PathLike $_ $buildArtifactPatterns } | Sort-Object -Unique)
$stagedDeletes = @(git diff --cached --name-status | Where-Object { $_ -match '^D\s+' } | ForEach-Object {
($_ -replace '^D\s+', '') -replace '\\', '/'
})
$stagedDeleteSet = @{}
foreach ($path in $stagedDeletes) {
$stagedDeleteSet[$path] = $true
}
$graphifyLarge = @($paths | Where-Object {
(Test-PathLike $_ $largeGraphifyPatterns) -and -not $stagedDeleteSet.ContainsKey($_)
} | Sort-Object -Unique)
$graphifyLargeDeletes = @($paths | Where-Object {
(Test-PathLike $_ $largeGraphifyPatterns) -and $stagedDeleteSet.ContainsKey($_)
} | Sort-Object -Unique)
$touchedScripts = @($paths | Where-Object { $_ -like 'Unity/Assets/Scripts/*' })
$touchedAot = @($paths | Where-Object { $_ -like 'Unity/Assets/Scripts/*AOT*' -or $_ -like 'Unity/Assets/Scripts/*HybridCLR*' -or $_ -like 'Unity/Assets/Scripts/*YooAsset*' })
$touchedEditor = @($paths | Where-Object { $_ -like 'Unity/Assets/Scripts/*Editor*' -or $_ -like 'Unity/Assets/Editor/*' })
$touchedConfig = @($paths | Where-Object { $_ -like 'ExcelExport/*' -or $_ -like 'Unity/Assets/Scripts/TH1_Config/*' })
$touchedTools = @($paths | Where-Object { $_ -like 'Tools/*' })
$touchedCultureUpgradeConfig = @($paths | Where-Object {
$_ -eq 'Unity/Assets/BundleResources/DataAssets/UnitTypeDataAssets.asset' -or
$_ -eq 'Unity/Assets/BundleResources/Export/UnitTypeDataAssets.asset' -or
$_ -eq 'Tools/CheckCultureUpgradeUnitConfig.ps1'
})
$touchedAunnTwinSkill = @($paths | Where-Object {
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/HakureiNorwayHeroSkill.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Unit/UnitLogic.cs' -or
$_ -eq 'Tools/CheckAunnTwinAutoPetrify.ps1'
})
$touchedAunnPetrifiedDefenseAura = @($paths | Where-Object {
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/HakureiNorwayHeroSkill.cs' -or
$_ -eq 'Unity/Assets/BundleResources/DataAssets/UnitTypeDataAssets.asset' -or
$_ -eq 'Unity/Assets/BundleResources/Export/UnitTypeDataAssets.asset' -or
$_ -eq 'Unity/Assets/BundleResources/DataAssets/SkillDataAssets.asset' -or
$_ -eq 'Unity/Assets/BundleResources/Export/Multilingual.asset' -or
$_ -eq 'Tools/CheckAunnPetrifiedDefenseAura.ps1'
})
$touchedSuikaFallingSplashAnimation = @($paths | Where-Object {
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/HakureiNorwayHeroSkill.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Action/ActionLogic.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Unit/UnitLogic.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Anim/FragmentManager.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Anim/Fragments/FragmentData.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Anim/Fragments/FragmentSkillEffect.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Anim/UnitAtomAnim/UnitAtomAnim.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Anim/UnitAtomAnim/UnitAtomAnimData.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Anim/UnitAtomAnim/UnitAtomAnimMove.cs' -or
$_ -eq 'Tools/CheckSuikaFallingSplashAnimation.ps1'
})
$touchedMomijiHunterMovement = @($paths | Where-Object {
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Unit/UnitLogic.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Data/UnitData.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/MomijiHunterSkill.cs' -or
$_ -eq 'Tools/CheckMomijiHunterMovement.ps1'
})
$touchedMokouRevivedMoveKill = @($paths | Where-Object {
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Unit/UnitLogic.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/MokouFrenchReviveSkill.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Logic/Skill/AllSkill/MokouFrenchMoveKillSkill.cs' -or
$_ -eq 'Unity/Assets/Scripts/TH1_Anim/Fragments/FragmentMoveKill.cs' -or
$_ -eq 'Tools/CheckMokouRevivedMoveKill.ps1'
})
$touchedSkillDataAssets = @($paths | Where-Object {
$_ -eq 'Unity/Assets/BundleResources/DataAssets/SkillDataAssets.asset' -or
$_ -eq 'Unity/Assets/BundleResources/Export/SkillDataAssets.asset' -or
$_ -eq 'Unity/Assets/BundleResources/Export/Multilingual.asset' -or
$_ -eq 'Tools/MultilingualTxt.txt' -or
$_ -eq 'Tools/CheckSkillDataAssetsIntegrity.ps1'
})
$touchedUnityDataAssetReferences = @($paths | Where-Object {
$_ -like 'Unity/Assets/BundleResources/DataAssets/*.asset' -or
$_ -like 'Unity/Assets/BundleResources/Export/*.asset' -or
$_ -eq 'Tools/CheckUnityAssetReferenceIntegrity.ps1'
})
Write-Host ""
Write-Host "Guardrails:"
$hasAdvisoryIssue = $false
$hasBlockingIssue = $false
if ($advisoryGenerated.Count -gt 0) {
$hasAdvisoryIssue = $true
Write-Host " NOTICE: generated/export/localization files changed:"
$advisoryGenerated | ForEach-Object { Write-Host " $_" }
Write-Host " These are allowed in normal TH1 content iteration; confirm they are intentional."
}
if ($artifacts.Count -gt 0) {
$hasBlockingIssue = $true
Write-Host " WARNING: build/package artifacts changed:"
$artifacts | ForEach-Object { Write-Host " $_" }
}
if ($graphifyLarge.Count -gt 0) {
$hasBlockingIssue = $true
Write-Host " WARNING: large graphify artifacts changed:"
$graphifyLarge | ForEach-Object { Write-Host " $_" }
}
if ($graphifyLargeDeletes.Count -gt 0) {
Write-Host " NOTICE: large graphify artifacts are being removed from Git tracking:"
$graphifyLargeDeletes | ForEach-Object { Write-Host " $_" }
}
if (-not $hasAdvisoryIssue -and -not $hasBlockingIssue) {
Write-Host " no generated/export or artifact paths detected"
}
if ($touchedCultureUpgradeConfig.Count -gt 0) {
Write-Host ""
Write-Host "Culture upgrade config check:"
$cultureCheckPath = Join-Path $repoRoot "Tools/CheckCultureUpgradeUnitConfig.ps1"
try {
if ($paths -contains 'Unity/Assets/BundleResources/Export/UnitTypeDataAssets.asset') {
& $cultureCheckPath -CheckExport
} else {
& $cultureCheckPath
}
} catch {
$hasBlockingIssue = $true
Write-Host " WARNING: culture upgrade config guardrail failed:"
Write-Host " $($_.Exception.Message)"
}
}
if ($touchedAunnTwinSkill.Count -gt 0) {
Write-Host ""
Write-Host "Aunn twin auto-petrify check:"
$aunnCheckPath = Join-Path $repoRoot "Tools/CheckAunnTwinAutoPetrify.ps1"
try {
& $aunnCheckPath
} catch {
$hasBlockingIssue = $true
Write-Host " WARNING: Aunn twin auto-petrify guardrail failed:"
Write-Host " $($_.Exception.Message)"
}
}
if ($touchedAunnPetrifiedDefenseAura.Count -gt 0) {
Write-Host ""
Write-Host "Aunn Lv3 petrified-defense aura check:"
$aunnAuraCheckPath = Join-Path $repoRoot "Tools/CheckAunnPetrifiedDefenseAura.ps1"
try {
if ($paths -contains 'Unity/Assets/BundleResources/Export/UnitTypeDataAssets.asset' -or
$paths -contains 'Unity/Assets/BundleResources/Export/Multilingual.asset') {
& $aunnAuraCheckPath -CheckExport
} else {
& $aunnAuraCheckPath
}
} catch {
$hasBlockingIssue = $true
Write-Host " WARNING: Aunn Lv3 petrified-defense aura guardrail failed:"
Write-Host " $($_.Exception.Message)"
}
}
if ($touchedSuikaFallingSplashAnimation.Count -gt 0) {
Write-Host ""
Write-Host "Suika falling splash animation check:"
$suikaFallingSplashCheckPath = Join-Path $repoRoot "Tools/CheckSuikaFallingSplashAnimation.ps1"
try {
& $suikaFallingSplashCheckPath
} catch {
$hasBlockingIssue = $true
Write-Host " WARNING: Suika falling splash animation guardrail failed:"
Write-Host " $($_.Exception.Message)"
}
}
if ($touchedMomijiHunterMovement.Count -gt 0) {
Write-Host ""
Write-Host "Momiji hunter movement check:"
$momijiHunterMovementCheckPath = Join-Path $repoRoot "Tools/CheckMomijiHunterMovement.ps1"
try {
& $momijiHunterMovementCheckPath
} catch {
$hasBlockingIssue = $true
Write-Host " WARNING: Momiji hunter movement guardrail failed:"
Write-Host " $($_.Exception.Message)"
}
}
if ($touchedMokouRevivedMoveKill.Count -gt 0) {
Write-Host ""
Write-Host "Mokou revived move-kill check:"
$mokouRevivedMoveKillCheckPath = Join-Path $repoRoot "Tools/CheckMokouRevivedMoveKill.ps1"
try {
& $mokouRevivedMoveKillCheckPath
} catch {
$hasBlockingIssue = $true
Write-Host " WARNING: Mokou revived move-kill guardrail failed:"
Write-Host " $($_.Exception.Message)"
}
}
if ($touchedSkillDataAssets.Count -gt 0) {
Write-Host ""
Write-Host "SkillDataAssets integrity check:"
$skillDataAssetsCheckPath = Join-Path $repoRoot "Tools/CheckSkillDataAssetsIntegrity.ps1"
try {
if ($paths -contains 'Unity/Assets/BundleResources/Export/SkillDataAssets.asset' -or
$paths -contains 'Unity/Assets/BundleResources/Export/Multilingual.asset' -or
$paths -contains 'Tools/MultilingualTxt.txt') {
& $skillDataAssetsCheckPath -CheckExport
} else {
& $skillDataAssetsCheckPath
}
} catch {
$hasBlockingIssue = $true
Write-Host " WARNING: SkillDataAssets integrity guardrail failed:"
Write-Host " $($_.Exception.Message)"
}
}
if ($touchedUnityDataAssetReferences.Count -gt 0) {
Write-Host ""
Write-Host "Unity asset reference check:"
$assetReferenceCheckPath = Join-Path $repoRoot "Tools/CheckUnityAssetReferenceIntegrity.ps1"
try {
& $assetReferenceCheckPath
} catch {
$hasBlockingIssue = $true
Write-Host " WARNING: Unity asset reference guardrail failed:"
Write-Host " $($_.Exception.Message)"
}
}
Write-Host ""
Write-Host "Suggested verification:"
if ($touchedScripts.Count -gt 0) {
Write-Host " dotnet build Unity/TH1.Hotfix.csproj --no-restore"
}
if ($touchedAot.Count -gt 0) {
Write-Host " dotnet build Unity/TH1.AOT.csproj --no-restore"
}
if ($touchedEditor.Count -gt 0) {
Write-Host " dotnet build Unity/TH1.Editor.csproj --no-restore"
Write-Host " dotnet build Unity/TH1.Logic.Editor.csproj --no-restore"
Write-Host " dotnet build Unity/TH1.Steam.Editor.csproj --no-restore"
}
if ($touchedConfig.Count -gt 0) {
Write-Host " dotnet build ExcelExport/ExcelExport.csproj --no-restore"
}
if ($touchedTools.Count -gt 0) {
Write-Host " run the changed tool script with a safe smoke-test command"
}
if ($touchedCultureUpgradeConfig.Count -gt 0) {
Write-Host " Tools/CheckCultureUpgradeUnitConfig.ps1"
Write-Host " Tools/CheckCultureUpgradeUnitConfig.ps1 -CheckExport"
}
if ($touchedAunnTwinSkill.Count -gt 0) {
Write-Host " Tools/CheckAunnTwinAutoPetrify.ps1"
}
if ($touchedAunnPetrifiedDefenseAura.Count -gt 0) {
Write-Host " Tools/CheckAunnPetrifiedDefenseAura.ps1"
Write-Host " Tools/CheckAunnPetrifiedDefenseAura.ps1 -CheckExport"
}
if ($touchedSuikaFallingSplashAnimation.Count -gt 0) {
Write-Host " Tools/CheckSuikaFallingSplashAnimation.ps1"
}
if ($touchedMokouRevivedMoveKill.Count -gt 0) {
Write-Host " Tools/CheckMokouRevivedMoveKill.ps1"
}
if ($touchedSkillDataAssets.Count -gt 0) {
Write-Host " Tools/CheckSkillDataAssetsIntegrity.ps1"
Write-Host " Tools/CheckSkillDataAssetsIntegrity.ps1 -CheckExport"
}
if ($touchedUnityDataAssetReferences.Count -gt 0) {
Write-Host " Tools/CheckUnityAssetReferenceIntegrity.ps1"
}
if ($paths.Count -eq 0) {
Write-Host " none; working tree is clean"
}
if ($Strict -and $hasBlockingIssue) {
throw "Git checkpoint guardrail failed. Remove build/package artifacts or large graphify cache files before committing."
}