Created
April 26, 2025 20:54
-
-
Save WoLfulus/194c5b2ecf12320671718132edf13479 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# Watch for changes | |
# | |
function watch { | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory = $true)] | |
[string[]]$Watch, | |
[Parameter(Mandatory = $true)] | |
[scriptblock]$Action | |
) | |
function Resolve-GlobPattern { | |
param ( | |
[string]$Pattern | |
) | |
$isGlob = $Pattern -match '[*?]' | |
if (-not $isGlob) { | |
return @($Pattern) | |
} | |
$isRecursive = $Pattern -match '\*\*' | |
if (-not $isRecursive) { | |
$items = Get-ChildItem $Pattern -File -ErrorAction SilentlyContinue | |
return $items | |
} | |
$items = Get-ChildItem $Pattern -Recurse -ErrorAction SilentlyContinue | %{ $_.FullName } | |
return @($items); | |
} | |
$filesToWatch = @() | |
foreach ($pattern in $Watch) { | |
$resolvedFiles = Resolve-GlobPattern -Pattern $pattern | |
$filesToWatch += $resolvedFiles | |
} | |
$filesToWatch = $filesToWatch | Select-Object -Unique | |
Write-Host "Watching $($filesToWatch.Count) files for changes..." -ForegroundColor Cyan | |
$filesToWatch | ForEach-Object { Write-Host " - $_" -ForegroundColor Cyan } | |
Write-Host "" | |
# Keep track of last write times | |
$lastWriteTimes = @{} | |
$filesToWatch | ForEach-Object { | |
if (Test-Path -Path $_) { | |
$lastWriteTimes[$_] = (Get-Item -Path $_).LastWriteTime | |
} | |
} | |
# First execution | |
$executionScope = New-Module -ScriptBlock { | |
param($scriptBlock, $filesToWatch) | |
$global:ChangedFiles = $filesToWatch | |
& $scriptBlock | |
Remove-Variable -Name ChangedFiles -Scope Global -ErrorAction SilentlyContinue | |
} -ArgumentList $Action, $filesToWatch | |
Write-Host "" | |
try { | |
while ($true) { | |
$changedFiles = @() | |
foreach ($file in $filesToWatch) { | |
if (Test-Path -Path $file) { | |
$currentWriteTime = (Get-Item -Path $file).LastWriteTime | |
if ($lastWriteTimes.ContainsKey($file) -and $currentWriteTime -gt $lastWriteTimes[$file]) { | |
$changedFiles += $file | |
$lastWriteTimes[$file] = $currentWriteTime | |
} | |
elseif (-not $lastWriteTimes.ContainsKey($file)) { | |
$changedFiles += $file | |
$lastWriteTimes[$file] = $currentWriteTime | |
} | |
} | |
elseif ($lastWriteTimes.ContainsKey($file)) { | |
$changedFiles += $file | |
$lastWriteTimes.Remove($file) | |
} | |
} | |
# If files have changed, execute the action | |
if ($changedFiles.Count -gt 0) { | |
Clear-Host | |
Write-Host "`nChanges detected in $($changedFiles.Count) files:" -ForegroundColor Yellow | |
$changedFiles | ForEach-Object { Write-Host " - $_" -ForegroundColor Yellow } | |
Write-Host "" | |
$executionScope = New-Module -ScriptBlock { | |
param($scriptBlock, $changedFiles) | |
$global:ChangedFiles = $changedFiles | |
& $scriptBlock | |
Remove-Variable -Name ChangedFiles -Scope Global -ErrorAction SilentlyContinue | |
} -ArgumentList $Action, $changedFiles | |
Write-Host "" | |
} | |
# Check for new files that match the patterns | |
$newFilesToWatch = @() | |
foreach ($pattern in $Watch) { | |
$resolvedFiles = Resolve-GlobPattern -Pattern $pattern | |
$newFilesToWatch += $resolvedFiles | |
} | |
$newFilesToWatch = $newFilesToWatch | Select-Object -Unique | |
# Add new files to watch list | |
foreach ($file in $newFilesToWatch) { | |
if (-not $filesToWatch.Contains($file)) { | |
$filesToWatch += $file | |
if (Test-Path -Path $file) { | |
$lastWriteTimes[$file] = (Get-Item -Path $file).LastWriteTime | |
} | |
Write-Host "Now watching new file: $file" -ForegroundColor Cyan | |
} | |
} | |
Start-Sleep -Milliseconds 1000 | |
} | |
} | |
catch { | |
Write-Error "Error in watch function: $_" | |
} | |
finally { | |
Write-Host "Watch stopped." -ForegroundColor Cyan | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment