sync-index.ps1 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <#
  2. .SYNOPSIS
  3. 按【发布仓里真实存在的包】重算 index.json 的 size / sha256。
  4. .DESCRIPTION
  5. 为什么必须有这一步:
  6. 构建机上的 gallery 源(TeamAAS-2.1\gallery)与发布仓(本目录)是两个独立的目录,
  7. 长期各自打包、各自推送 —— 两边同名包常常不是同一份文件。
  8. 而打包时会按【本地源】全量 REGEN 索引,若把这份索引直接推到发布仓,
  9. 客户端就会拿本地源记录的 size/sha256 去校验发布仓里的另一个文件,
  10. 安装时报 "大小不匹配:期望 X 字节,实际 Y 字节"。
  11. 因此:每次往发布仓放包之后、提交索引之前,必须跑一次本脚本,
  12. 让索引里的 size/sha256 与发布仓里实际的文件严格一致。
  13. 用法:
  14. .\sync-index.ps1 # 校正并打印改动数量
  15. .\sync-index.ps1 -Check # 只检查,不写文件(适合在提交前做校验/输出不符条目数)
  16. .NOTES
  17. 只改 size / sha256 两个字段,其余元数据(名称/描述/依赖/版本历史)保持原样。
  18. 编码按原文件的 BOM 状态原样写回,避免把 UTF-8 内容写坏。
  19. #>
  20. param(
  21. [switch]$Check
  22. )
  23. $ErrorActionPreference = 'Stop'
  24. $root = $PSScriptRoot
  25. $idxPath = Join-Path $root 'index.json'
  26. if (-not (Test-Path $idxPath)) { throw "未找到索引文件:$idxPath" }
  27. # 原样保持 BOM 状态
  28. $bytes = [IO.File]::ReadAllBytes($idxPath)
  29. $hasBom = ($bytes.Length -ge 3 -and $bytes[0] -eq 239 -and $bytes[1] -eq 187 -and $bytes[2] -eq 191)
  30. $text = [IO.File]::ReadAllText($idxPath, [Text.Encoding]::UTF8)
  31. # 发布仓里真实存在的包
  32. $files = @{}
  33. foreach ($p in (Get-ChildItem (Join-Path $root 'packages') -Recurse -Filter '*.zip' -ErrorAction SilentlyContinue)) {
  34. $rel = $p.FullName.Substring($root.Length).TrimStart('\', '/') -replace '\\', '/'
  35. $files[$rel] = $p
  36. }
  37. # 索引里引用到的包路径
  38. $refs = [regex]::Matches($text, '"downloadUrl":\s*"([^"]+)"') |
  39. ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique
  40. $fixed = 0
  41. $missing = @()
  42. foreach ($rel in $refs) {
  43. if (-not $files.ContainsKey($rel)) { $missing += $rel; continue }
  44. $f = $files[$rel]
  45. $sha = (Get-FileHash $f.FullName -Algorithm SHA256).Hash.ToLower()
  46. $size = $f.Length
  47. $esc = [regex]::Escape($rel)
  48. # 结构固定为:downloadUrl → sha256 → size
  49. $pattern = '("downloadUrl":\s*"' + $esc + '",\s*"sha256":\s*")[0-9a-fA-F]*(",\s*"size":\s*)\d+'
  50. $new = [regex]::Replace($text, $pattern, ('${1}' + $sha + '${2}' + $size))
  51. if ($new -ne $text) { $fixed++ }
  52. $text = $new
  53. }
  54. if ($Check) {
  55. Write-Host ("不符条目: " + $fixed + " 处")
  56. } else {
  57. [IO.File]::WriteAllText($idxPath, $text, (New-Object Text.UTF8Encoding($hasBom)))
  58. Write-Host ("索引已按发布仓实际包校正: " + $fixed + " 处(BOM=" + $hasBom + ")")
  59. }
  60. if ($missing.Count -gt 0) {
  61. Write-Host "警告:索引中有 $($missing.Count) 个条目指向发布仓不存在的包(客户端安装会 404):" -ForegroundColor Yellow
  62. $missing | Sort-Object -Unique | ForEach-Object { Write-Host (" " + $_) -ForegroundColor Yellow }
  63. }
  64. if ($Check -and $fixed -gt 0) { exit 1 }
  65. exit 0