127 lines
4.6 KiB
PowerShell
127 lines
4.6 KiB
PowerShell
# scrie_backstop_skills.ps1 - scrie blocul backstop de rutare a skill-urilor in AGENTS.md si CLAUDE.md
|
|
# ale fiecarui proiect ROA. Sursa unica: backstop_skills.txt (langa acest script).
|
|
# Idempotent: a doua rulare nu schimba nimic. -DryRun doar listeaza ce ar face.
|
|
# Utilizare:
|
|
# powershell -File COMUN\utile\scrie_backstop_skills.ps1 -Root D:\ROA
|
|
# powershell -File COMUN\utile\scrie_backstop_skills.ps1 -Root D:\ROA -DryRun
|
|
param(
|
|
[string]$Root = 'D:\ROA',
|
|
[switch]$DryRun
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$MarkerStart = '<!-- roa-skills:start -->'
|
|
$MarkerEnd = '<!-- roa-skills:end -->'
|
|
$TitluAgents = '# AGENTS.md'
|
|
$NumeSarite = @('COMUNROA', 'UTIL')
|
|
$Utf8FaraBom = New-Object System.Text.UTF8Encoding($false)
|
|
|
|
$sursa = Join-Path $PSScriptRoot 'backstop_skills.txt'
|
|
if (-not (Test-Path -LiteralPath $sursa -PathType Leaf)) {
|
|
Write-Output ('scrie_backstop_skills: nu gasesc blocul canonic ' + $sursa + ' - nimic de facut.')
|
|
exit 0
|
|
}
|
|
$bloc = ([IO.File]::ReadAllText($sursa)).Replace("`r`n", "`n").TrimEnd("`n")
|
|
|
|
function Ia-Sectiune {
|
|
# sectiunea marcata, cu terminatorii de linie dati
|
|
param([string]$nl)
|
|
return $MarkerStart + $nl + $bloc.Replace("`n", $nl) + $nl + $MarkerEnd
|
|
}
|
|
|
|
function Ia-Terminator {
|
|
param([string]$Continut)
|
|
if ($Continut.Contains("`r`n")) { return "`r`n" }
|
|
if ($Continut.Contains("`n")) { return "`n" }
|
|
return "`r`n"
|
|
}
|
|
|
|
function Ia-Encoding {
|
|
# pastreaza BOM-ul original daca exista, altfel scrie UTF-8 fara BOM
|
|
param([string]$Cale)
|
|
$b = [IO.File]::ReadAllBytes($Cale)
|
|
if ($b.Length -ge 3 -and $b[0] -eq 0xEF -and $b[1] -eq 0xBB -and $b[2] -eq 0xBF) {
|
|
return (New-Object System.Text.UTF8Encoding($true))
|
|
}
|
|
return $Utf8FaraBom
|
|
}
|
|
|
|
function Continut-Marcat {
|
|
# noul continut, sau $null daca nu e nevoie de nicio schimbare (idempotent)
|
|
param([string]$Continut, [string]$nl)
|
|
$sect = Ia-Sectiune $nl
|
|
$si = $Continut.IndexOf($MarkerStart)
|
|
$ei = $Continut.IndexOf($MarkerEnd)
|
|
if ($si -ge 0 -and $ei -gt $si) {
|
|
$nou = $Continut.Substring(0, $si) + $sect + $Continut.Substring($ei + $MarkerEnd.Length)
|
|
} else {
|
|
$nou = $Continut.TrimEnd("`r", "`n") + $nl + $nl + $sect + $nl
|
|
}
|
|
if ($nou -eq $Continut) { return $null }
|
|
return $nou
|
|
}
|
|
|
|
if (-not (Test-Path -LiteralPath $Root -PathType Container)) {
|
|
Write-Output ('scrie_backstop_skills: nu gasesc radacina ' + $Root + ' - nimic de facut.')
|
|
exit 0
|
|
}
|
|
|
|
$proiecte = @(Get-ChildItem -LiteralPath $Root -Directory -ErrorAction SilentlyContinue | Sort-Object Name)
|
|
$gasite = 0; $create = 0; $actualizate = 0; $ok = 0; $sarite = 0
|
|
|
|
foreach ($p in $proiecte) {
|
|
if ($NumeSarite -contains $p.Name) { continue }
|
|
if (-not (Test-Path -LiteralPath (Join-Path $p.FullName 'COMUN') -PathType Container)) { continue }
|
|
$areSvn = Test-Path -LiteralPath (Join-Path $p.FullName '.svn') -PathType Container
|
|
$areGit = Test-Path -LiteralPath (Join-Path $p.FullName '.git') -PathType Container
|
|
if (-not ($areSvn -or $areGit)) { continue }
|
|
|
|
$gasite++
|
|
Write-Output ('Proiect: ' + $p.Name)
|
|
|
|
foreach ($nume in @('AGENTS.md', 'CLAUDE.md')) {
|
|
$cale = Join-Path $p.FullName $nume
|
|
|
|
if (-not (Test-Path -LiteralPath $cale -PathType Leaf)) {
|
|
if ($nume -eq 'CLAUDE.md') {
|
|
Write-Output (' ' + $nume + ' sarit - lipseste')
|
|
$sarite++
|
|
continue
|
|
}
|
|
$nl = "`r`n"
|
|
$nou = $TitluAgents + $nl + $nl + (Ia-Sectiune $nl) + $nl
|
|
if ($DryRun) {
|
|
Write-Output (' ' + $nume + ' ar crea')
|
|
} else {
|
|
[IO.File]::WriteAllText($cale, $nou, $Utf8FaraBom)
|
|
Write-Output (' ' + $nume + ' creat')
|
|
}
|
|
$create++
|
|
continue
|
|
}
|
|
|
|
$raw = [IO.File]::ReadAllText($cale)
|
|
$nl = Ia-Terminator $raw
|
|
$nou = Continut-Marcat -Continut $raw -nl $nl
|
|
if ($null -eq $nou) {
|
|
Write-Output (' ' + $nume + ' ok')
|
|
$ok++
|
|
continue
|
|
}
|
|
if ($DryRun) {
|
|
Write-Output (' ' + $nume + ' ar actualiza')
|
|
} else {
|
|
[IO.File]::WriteAllText($cale, $nou, (Ia-Encoding $cale))
|
|
Write-Output (' ' + $nume + ' actualizat')
|
|
}
|
|
$actualizate++
|
|
}
|
|
}
|
|
|
|
Write-Output ''
|
|
$eticheta = 'scrie_backstop_skills'
|
|
if ($DryRun) { $eticheta = $eticheta + ' (DryRun)' }
|
|
Write-Output ($eticheta + ': ' + $gasite + ' proiecte, ' + $create + ' create, ' + $actualizate + ' actualizate, ' + $ok + ' neschimbate, ' + $sarite + ' sarite')
|
|
exit 0
|