Files

143 lines
5.6 KiB
PowerShell

# Create-And-Propagate.ps1
# ========================
# SUPERWEAPON: Atomically create a PA interface AND replace its MC equivalent everywhere.
#
# This function:
# 1. Writes a new file (typically a platform-api interface)
# 2. Scans all .java files in a target directory
# 3. For each file, performs Symbol-Swap style replacement:
# - Replaces old type name with new type name
# - Removes old MC import
# - Adds new PA import
# 4. Creation and propagation happen in ONE call -- no partial states.
#
# USAGE:
# . tools/migration/Create-And-Propagate.ps1
#
# Create-And-Propagate `
# -FilePath 'platform-api/src/main/java/noppes/npcs/api/handler/IMessageService.java' `
# -Content $interfaceCode `
# -TargetDirectory 'core/src/main/java' `
# -Swaps @(
# @('ChatComponentText', 'IMessageService', 'net.minecraft.util.ChatComponentText', 'noppes.npcs.api.handler.IMessageService'),
# @('ChatComponentTranslation', 'IMessageService', 'net.minecraft.util.ChatComponentTranslation', 'noppes.npcs.api.handler.IMessageService')
# )
#
# PARAMS:
# -FilePath Relative path (from ProjectRoot) for the new file to create.
# -Content String content of the new file.
# -TargetDirectory Relative path (from ProjectRoot) to scan for propagation. All .java files
# in this directory (recursively) will have swaps applied.
# -Swaps Array of 4-element arrays: @(oldSymbol, newSymbol, oldImport, newImport).
# Same format as Symbol-Swap.ps1.
# -ProjectRoot Absolute project root (auto-detected from script location if not provided)
#
# OUTPUT:
# Returns hashtable with 'Created' (file path) and 'Modified' (array of modified files).
# Prints log to stdout.
function Create-And-Propagate {
param(
[Parameter(Mandatory=$true)]
[string]$FilePath,
[Parameter(Mandatory=$true)]
[string]$Content,
[Parameter(Mandatory=$true)]
[string]$TargetDirectory,
[Parameter(Mandatory=$true)]
[array]$Swaps,
[string]$ProjectRoot
)
# Auto-detect ProjectRoot from script location if not provided
if (-not $ProjectRoot) {
$ProjectRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
}
# Guard against PowerShell single-element array flattening
if ($Swaps.Count -gt 0 -and $Swaps[0] -is [string]) {
$Swaps = @(,$Swaps)
}
Write-Host ""
Write-Host "============================================"
Write-Host " CREATE-AND-PROPAGATE -- Atomic PA Creator"
Write-Host "============================================"
Write-Host "New file: $FilePath"
Write-Host "Target dir: $TargetDirectory"
Write-Host "Swaps: $($Swaps.Count)"
foreach ($s in $Swaps) {
Write-Host " $($s[0]) -> $($s[1])"
}
Write-Host "============================================"
Write-Host ""
# Step 1: Create the new file
$fullPath = Join-Path $ProjectRoot $FilePath
$dir = Split-Path $fullPath -Parent
if (!(Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }
[IO.File]::WriteAllText($fullPath, $Content)
Write-Host " CREATED: $FilePath"
# Step 2: Propagate swaps across target directory
$fullTargetDir = Join-Path $ProjectRoot $TargetDirectory
if (!(Test-Path $fullTargetDir)) {
Write-Host "ERROR: Target directory not found: $fullTargetDir"
return @{ Created = $FilePath; Modified = @() }
}
$files = Get-ChildItem -Recurse -Filter '*.java' -Path $fullTargetDir
$modified = [System.Collections.ArrayList]::new()
foreach ($f in $files) {
$fileContent = [IO.File]::ReadAllText($f.FullName)
$original = $fileContent
$fileSwapped = $false
# PHASE 1: Remove all old imports FIRST (before symbol replacement mangles them)
foreach ($swap in $Swaps) {
$oldImp = $swap[2]
if ($oldImp -and ($fileContent -match "import\s+(?:static\s+)?$([regex]::Escape($oldImp))\s*;")) {
$fileContent = $fileContent -replace "import\s+(?:static\s+)?$([regex]::Escape($oldImp))\s*;\r?\n", ''
}
}
# PHASE 2: Replace symbols in code body
foreach ($swap in $Swaps) {
$oldSym = $swap[0]; $newSym = $swap[1]
if ($fileContent -match [regex]::Escape($oldSym)) {
$fileContent = $fileContent -replace [regex]::Escape($oldSym), $newSym
$fileSwapped = $true
}
}
# PHASE 3: Add new imports (if swap happened, not empty, and not already present)
foreach ($swap in $Swaps) {
$newImp = $swap[3]
if ($newImp -and $fileSwapped -and !($fileContent -match "import\s+$([regex]::Escape($newImp))\s*;")) {
$fileContent = $fileContent -replace '(package\s+[^;]+;\s*\r?\n)', "`$1import $newImp;`n"
}
}
if ($fileContent -ne $original) {
[IO.File]::WriteAllText($f.FullName, $fileContent)
[void]$modified.Add($f.FullName.Substring($fullTargetDir.Length + 1))
Write-Host " PROPAGATED: $($f.Name)"
}
}
Write-Host ""
Write-Host "============================================"
Write-Host " CREATE-AND-PROPAGATE SUMMARY"
Write-Host "============================================"
Write-Host "File created: $FilePath"
Write-Host "Files propagated: $($modified.Count) / $($files.Count)"
Write-Host "============================================"
return @{ Created = $FilePath; Modified = $modified.ToArray() }
}