param( [string[]]$WatchPaths = @( "plugins/1c/agent", "core/deploy/docker/1c-agent/compose.yaml", "scripts/deploy_onec_agent_test.ps1", "scripts/smoke_onec_agent_api.py" ), [int]$PollSeconds = 5, [int]$DebounceSeconds = 2, [int]$MaxCycles = 0, [switch]$WithTurnCheck, [switch]$NoBuild, [int]$HealthTimeoutSec = 60, [int]$SmokeTimeoutSec = 5 ) $ErrorActionPreference = "Stop" $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path $repoRoot = Split-Path -Parent $scriptDir $deployScript = Join-Path $scriptDir "deploy_onec_agent_test.ps1" function Resolve-WatchPath { param([string]$Path) if ([System.IO.Path]::IsPathRooted($Path)) { return $Path } return Join-Path $repoRoot $Path } function Get-Signature { param([string[]]$Paths) $entries = @() foreach ($path in $Paths) { $path = Resolve-WatchPath ($path.Trim()) if (-not (Test-Path -LiteralPath $path)) { Write-Host "[warn] path not found: $path" continue } $item = Get-Item -LiteralPath $path if ($item.PSIsContainer) { $items = Get-ChildItem -LiteralPath $path -Recurse -File -Force | Where-Object { $parts = $_.FullName -split "[\\/]" $parts -notcontains ".git" -and $parts -notcontains "__pycache__" -and $parts -notcontains ".pytest_cache" -and $parts -notcontains ".ruff_cache" -and $parts -notcontains ".venv" } | ForEach-Object { "$($_.FullName)|$($_.Length)|$($_.LastWriteTimeUtc.Ticks)" } $entries += $items } else { $parts = $item.FullName -split "[\\/]" if ( $parts -notcontains ".git" -and $parts -notcontains "__pycache__" -and $parts -notcontains ".pytest_cache" -and $parts -notcontains ".ruff_cache" -and $parts -notcontains ".venv" ) { $entries += "$($item.FullName)|$($item.Length)|$($item.LastWriteTimeUtc.Ticks)" } } } return @($entries | Sort-Object -Unique) } function Invoke-Deploy { param() $deployArgs = @( "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", $deployScript, "-HealthTimeoutSec", $HealthTimeoutSec, "-SmokeTimeoutSec", $SmokeTimeoutSec ) if ($WithTurnCheck) { $deployArgs += "-WithTurnCheck" } if ($NoBuild) { $deployArgs += "-NoBuild" } Write-Host "[run] deploy: $deployScript" & powershell @deployArgs if ($LASTEXITCODE -ne 0) { throw "onec-agent deploy script exited with code $LASTEXITCODE" } } Write-Host "[watch] onec-agent hot-deploy watcher started" Write-Host "[watch] paths: $($WatchPaths -join ', ')" Write-Host "[watch] poll=${PollSeconds}s, debounce=${DebounceSeconds}s, no-build=$NoBuild" $prev = Get-Signature -Paths $WatchPaths $lastChange = Get-Date try { Invoke-Deploy $cycles = 0 while ($MaxCycles -eq 0 -or $cycles -lt $MaxCycles) { Start-Sleep -Seconds $PollSeconds $cycles += 1 $curr = Get-Signature -Paths $WatchPaths if ((Compare-Object -ReferenceObject $prev -DifferenceObject $curr -SyncWindow 0).Count -eq 0) { continue } if ((((Get-Date) - $lastChange).TotalSeconds) -lt $DebounceSeconds) { continue } $lastChange = Get-Date Write-Host "[watch] change detected, redeploying onec-agent..." Invoke-Deploy $prev = $curr } } catch { Write-Error $_ throw }