- git_sync.ps1 nou: conversie recursiva bin->text in arbore (staging temp, incremental, orfani, RoundtripExempt, DbfList cu date, anti-dialog cfg) - vfp_filemap.ps1: mapari .pjx->.pj2 si .dbf->.db2 - txt2vcx.ps1: CacheRoot implicit = ProjectRoot (text in-arbore) + cfg anti-dialog in staging - test_roundtrip.ps1: parametrizat per proiect, restaurare din backup temp (nu git checkout) - test_git_sync.ps1 nou: incremental, orfani, esec partial, protectie binar, scutire roundtrip - CLAUDE.md: fluxul nou documentat Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
82 lines
3.5 KiB
PowerShell
82 lines
3.5 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Harta comuna bin<->memo<->text pentru conversiile VFP (FoxBin2Prg), dot-sourced de
|
|
vcx2txt.ps1 (Bin2Prg) si txt2vcx.ps1 (Prg2Bin), ca sa nu existe doua copii ale hartii.
|
|
|
|
.DESCRIPTION
|
|
Defineste $script:VfpFileMap: extensie-binar (lowercase, cu punct) -> @(extensie-memo, extensie-text).
|
|
Si o functie inversa Get-VfpBinExtensionForTextExtension pentru txt2vcx.ps1 (text -> binar).
|
|
#>
|
|
|
|
$script:VfpFileMap = @{
|
|
'.vcx' = @('.vct', '.vc2'); '.scx' = @('.sct', '.sc2'); '.frx' = @('.frt', '.fr2')
|
|
'.lbx' = @('.lbt', '.lb2'); '.mnx' = @('.mnt', '.mn2'); '.dbc' = @('.dct', '.dc2')
|
|
'.pjx' = @('.pjt', '.pj2'); '.dbf' = @('.fpt', '.db2')
|
|
}
|
|
|
|
function Get-VfpBinExtensionForTextExtension {
|
|
<#
|
|
.SYNOPSIS
|
|
Data o extensie text (.vc2, .sc2, ...), intoarce @(extensie-binar, extensie-memo), sau $null daca nu e cunoscuta.
|
|
#>
|
|
param([Parameter(Mandatory)][string]$TextExtension)
|
|
$t = $TextExtension.ToLower()
|
|
foreach ($binExt in $script:VfpFileMap.Keys) {
|
|
if ($script:VfpFileMap[$binExt][1] -eq $t) {
|
|
return @($binExt, $script:VfpFileMap[$binExt][0])
|
|
}
|
|
}
|
|
return $null
|
|
}
|
|
|
|
function Invoke-FoxBin2PrgSafe {
|
|
<#
|
|
.SYNOPSIS
|
|
Ruleaza FoxBin2Prg.EXE cu un watchdog de timp, ca sa nu ramana blocat la infinit.
|
|
|
|
.DESCRIPTION
|
|
FoxBin2Prg.EXE poate afisa un MessageBox MODAL nativ al motorului VFP (nu al
|
|
propriului sau error-handler) cand recompilarea textului esueaza (ex. text
|
|
stricat, ENDPROC lipsa) - vazut concret: "Error 1098, Procedure not closed...".
|
|
Parametrul cDontShowErrors='1' NU suprima acest dialog (acela controleaza doar
|
|
raportarea de erori proprie a FoxBin2Prg, nu eroarea nativa de compilare VFP).
|
|
Fara acest watchdog, un rulaj automat/CI ar ramane agatat la infinit asteptand
|
|
un om sa apese OK. Orice timeout se trateaza ca ESEC pentru fisierul respectiv.
|
|
|
|
.PARAMETER ExePath
|
|
Calea catre FoxBin2Prg.EXE.
|
|
|
|
.PARAMETER ExeArgs
|
|
Lista de argumente pozitionale, in ordinea folosita de FoxBin2Prg (inclusiv
|
|
string-urile goale intre ele, ca in apelul cu "&").
|
|
|
|
.PARAMETER TimeoutSeconds
|
|
Cat asteapta procesul sa termine normal inainte sa-l omoare (implicit 60s -
|
|
conversiile uzuale dureaza sub o secunda; un timeout mare inseamna aproape
|
|
sigur un dialog modal blocat).
|
|
|
|
.OUTPUTS
|
|
PSCustomObject cu TimedOut (bool) si ExitCode (int; -1 daca a fost omorat la timeout).
|
|
#>
|
|
param(
|
|
[Parameter(Mandatory)][string]$ExePath,
|
|
[Parameter(Mandatory)][AllowEmptyCollection()][AllowEmptyString()][string[]]$ExeArgs,
|
|
[int]$TimeoutSeconds = 60
|
|
)
|
|
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
|
$psi.FileName = $ExePath
|
|
$psi.Arguments = ($ExeArgs | ForEach-Object { '"' + ($_ -replace '"', '\"') + '"' }) -join ' '
|
|
$psi.UseShellExecute = $false
|
|
|
|
$proc = [System.Diagnostics.Process]::Start($psi)
|
|
$finished = $proc.WaitForExit($TimeoutSeconds * 1000)
|
|
if (-not $finished) {
|
|
Write-Warning "Invoke-FoxBin2PrgSafe: TIMEOUT dupa $TimeoutSeconds s (probabil MessageBox modal blocat) - omor procesul (PID $($proc.Id)) si eventualele lui ferestre/copii."
|
|
try { & taskkill /PID $proc.Id /T /F 2>&1 | Out-Null } catch {}
|
|
try { if (-not $proc.HasExited) { $proc.Kill() } } catch {}
|
|
Start-Sleep -Milliseconds 300
|
|
return [PSCustomObject]@{ TimedOut = $true; ExitCode = -1 }
|
|
}
|
|
return [PSCustomObject]@{ TimedOut = $false; ExitCode = $proc.ExitCode }
|
|
}
|