# Resolves module dependency tree via proxy.golang.org and fetches sum.golang.org lines. # Appends missing entries to go.sum (run from repo root: pwsh -File scripts/expand-go-sum.ps1). Set-StrictMode -Version 3 $ErrorActionPreference = "Stop" # Escape module path for sum.golang.org / proxy.golang.org (lowercase + %XX for other UTF-8 bytes). function Escape-GoModulePath2([string]$path) { $lower = $path.ToLowerInvariant() $bytes = [System.Text.Encoding]::UTF8.GetBytes($lower) $sb = New-Object System.Text.StringBuilder foreach ($b in $bytes) { $c = [char]$b $ok = ($b -ge 48 -and $b -le 57) -or ($b -ge 97 -and $b -le 122) -or ($c -eq '-') -or ($c -eq '.') -or ($c -eq '_') -or ($c -eq '+') if ($ok) { [void]$sb.Append($c) } else { [void]$sb.AppendFormat("%{0:x2}", $b) } } return $sb.ToString() } function Get-SumdbLines([string]$modPath, [string]$ver) { $enc = Escape-GoModulePath2 $modPath $url = "https://sum.golang.org/lookup/$enc@$ver" $raw = (Invoke-WebRequest -Uri $url -UseBasicParsing).Content $out = New-Object System.Collections.Generic.List[string] foreach ($line in ($raw -split "`n")) { $t = $line.Trim() if ($t -match '^\S+\s+v\S+\s+h1:') { [void]$out.Add($t) } } return $out } function Get-GoMod([string]$modPath, [string]$ver) { $enc = Escape-GoModulePath2 $modPath $url = "https://proxy.golang.org/$enc/@v/$ver.mod" return (Invoke-WebRequest -Uri $url -UseBasicParsing).Content } function Parse-Requires([string]$modText) { $req = @() $inBlock = $false foreach ($line in ($modText -split "`n")) { $t = $line.Trim() if ($t.StartsWith("//")) { continue } if ($t -match '^require\s+\(\s*$') { $inBlock = $true; continue } if ($inBlock) { if ($t -eq ")") { $inBlock = $false; continue } if ($t -match '^(\S+)\s+(v[^\s]+)') { $req += ,@($Matches[1], $Matches[2]) } continue } if ($t -match '^require\s+(\S+)\s+(v[^\s]+)\s*(//.*)?$') { $req += ,@($Matches[1], $Matches[2]) } } return $req } $root = Split-Path -Parent $PSScriptRoot Set-Location $root $queue = [System.Collections.Queue]::new() $seen = @{} $allLines = [System.Collections.Generic.HashSet[string]]::new([StringComparer]::Ordinal) foreach ($line in Get-Content -Path (Join-Path $root "go.sum")) { if ($line.Trim()) { [void]$allLines.Add($line.Trim()) } } function Enqueue([string]$p, [string]$v) { if ([string]::IsNullOrWhiteSpace($p) -or [string]::IsNullOrWhiteSpace($v)) { return } if ($p -notmatch '\.') { return } $k = "$p@$v" if ($seen.ContainsKey($k)) { return } $seen[$k] = $true $queue.Enqueue($k) } # Seed from go.mod direct requires (edit if go.mod changes) Enqueue "github.com/google/uuid" "v1.6.0" Enqueue "github.com/jackc/pgx/v5" "v5.7.2" Enqueue "github.com/prometheus/client_golang" "v1.20.5" Enqueue "modernc.org/sqlite" "v1.34.5" while ($queue.Count -gt 0) { $item = $queue.Dequeue() $p, $v = $item.Split("@", 2) foreach ($ln in (Get-SumdbLines $p $v)) { [void]$allLines.Add($ln) } $modBody = Get-GoMod $p $v foreach ($pair in (Parse-Requires $modBody)) { Enqueue $pair[0] $pair[1] } } $ordered = @($allLines | Sort-Object) $pathSum = Join-Path $root "go.sum" $utf8NoBom = New-Object System.Text.UTF8Encoding $false [System.IO.File]::WriteAllLines($pathSum, $ordered, $utf8NoBom) Write-Host "go.sum written: $($ordered.Count) lines"