feat: support parallel legacy and sandbox extensions

This commit is contained in:
Meik
2026-07-13 15:09:21 +02:00
parent b8ad580ae5
commit 58dcc9f943
89 changed files with 10102 additions and 123 deletions

85
tools/Sync-TfsLegacy.ps1 Normal file
View File

@@ -0,0 +1,85 @@
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory = $true)]
[string]$TfsExportRoot,
[Parameter(Mandatory = $true)]
[string]$Changeset,
[string]$RepositoryRoot,
[switch]$AllowDirtyTargets
)
$ErrorActionPreference = 'Stop'
if ([string]::IsNullOrWhiteSpace($RepositoryRoot)) {
$RepositoryRoot = Split-Path -Parent $PSScriptRoot
}
$repositoryRoot = [System.IO.Path]::GetFullPath($RepositoryRoot)
$tfsExportRoot = [System.IO.Path]::GetFullPath($TfsExportRoot)
$statePath = Join-Path $repositoryRoot 'sync\tfs-state.json'
$files = [ordered]@{
'F4SDM42WebApi\F4SDHelperService.cs' = 'Legacy\F4SDM42WebApi\F4SDHelperService.cs'
'F4SDM42WebApi\F4SDM42WebApiController.cs' = 'Legacy\F4SDM42WebApi\F4SDM42WebApiController.cs'
'F4SDM42WebApi\cM42LogEntry.cs' = 'Legacy\F4SDM42WebApi\cM42LogEntry.cs'
'F4SDM42WebApi\Properties\AssemblyInfo.cs' = 'Legacy\F4SDM42WebApi\Properties\AssemblyInfo.cs'
'F4SDHelper\Properties\AssemblyInfo.cs' = 'Legacy\F4SDHelper\Properties\AssemblyInfo.cs'
}
if (-not (Test-Path -LiteralPath (Join-Path $repositoryRoot '.git'))) {
throw "Repository root is not a Git worktree: $repositoryRoot"
}
foreach ($sourceRelative in $files.Keys) {
$sourcePath = Join-Path $tfsExportRoot $sourceRelative
if (-not (Test-Path -LiteralPath $sourcePath)) {
throw "Required TFS source file not found: $sourcePath"
}
}
if (-not $AllowDirtyTargets) {
$targetPaths = @($files.Values)
$status = & git -C $repositoryRoot status --porcelain -- $targetPaths
if ($LASTEXITCODE -ne 0) {
throw 'Could not inspect the Git worktree.'
}
if ($status) {
throw "Legacy sync targets contain uncommitted changes. Commit or stash them first:`n$($status -join [Environment]::NewLine)"
}
}
$utf8WithBom = [System.Text.UTF8Encoding]::new($true)
$hashes = [ordered]@{}
foreach ($entry in $files.GetEnumerator()) {
$sourcePath = Join-Path $tfsExportRoot $entry.Key
$targetPath = Join-Path $repositoryRoot $entry.Value
$content = [System.IO.File]::ReadAllText($sourcePath)
$content = [regex]::Replace($content, "`r?`n", "`r`n")
if ($PSCmdlet.ShouldProcess($targetPath, "Import TFS changeset $Changeset")) {
[System.IO.File]::WriteAllText($targetPath, $content, $utf8WithBom)
}
$hashes[$entry.Value.Replace('\', '/')] = (Get-FileHash -LiteralPath $sourcePath -Algorithm SHA256).Hash
}
$baseCommit = (& git -C $repositoryRoot rev-parse HEAD).Trim()
$state = [ordered]@{
LastImportedChangeset = $Changeset
ImportedAtUtc = [DateTime]::UtcNow.ToString('o')
SourceRoot = $tfsExportRoot
BaseGitCommit = $baseCommit
Files = $hashes
}
if ($PSCmdlet.ShouldProcess($statePath, 'Update TFS import state')) {
[System.IO.File]::WriteAllText(
$statePath,
($state | ConvertTo-Json -Depth 5),
$utf8WithBom)
}
Write-Host "Imported TFS changeset $Changeset into the Legacy sources."
Write-Host 'Review and commit this import on sync/tfs-legacy, then merge it into the development branch.'
Write-Host 'Publishing the final result back to TFS remains a manual Visual Studio step.'