Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion scripts/fetch-herdr-annotate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ if ($env:HERDR_ANNOTATE_BIN) {
exit 0
}

# .NET rather than Get-FileHash: in Windows PowerShell 5.1, Get-FileHash is a script function of
# Microsoft.PowerShell.Utility, not a compiled cmdlet. A powershell.exe started by a process that
# came from PowerShell 7 inherits a PSModulePath listing PowerShell 7's modules first, loads that
# Core-only Utility manifest instead, and Get-FileHash does not exist. SHA256 from .NET is the
# same in 5.1 and 7 whatever the module path says.
function Get-Sha256Hex {
param([Parameter(Mandatory = $true)][string]$LiteralPath)

$stream = [System.IO.File]::OpenRead($LiteralPath)
try {
$sha256 = [System.Security.Cryptography.SHA256]::Create()
try {
[System.BitConverter]::ToString($sha256.ComputeHash($stream)).Replace("-", "").ToLowerInvariant()
} finally {
$sha256.Dispose()
}
} finally {
$stream.Dispose()
}
}

$architecture = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()
$target = switch ($architecture) {
"X64" { "x86_64-pc-windows-msvc" }
Expand All @@ -51,7 +72,7 @@ try {
$line = Get-Content -LiteralPath (Join-Path $temporary "SHA256SUMS") | Where-Object { $_ -match "\s$([regex]::Escape($asset))$" } | Select-Object -First 1
if (-not $line) { throw "$asset is not listed in $base/SHA256SUMS" }
$expected = ($line -split "\s+")[0].ToLowerInvariant()
$actual = (Get-FileHash -Algorithm SHA256 -LiteralPath (Join-Path $temporary $asset)).Hash.ToLowerInvariant()
$actual = Get-Sha256Hex -LiteralPath (Join-Path $temporary $asset)
if ($actual -ne $expected) { throw "sha256 mismatch for ${asset}: expected $expected, got $actual" }
Copy-Item -Force -LiteralPath (Join-Path $temporary $asset) -Destination "$destination.tmp"
Move-Item -Force -LiteralPath "$destination.tmp" -Destination $destination
Expand Down
23 changes: 22 additions & 1 deletion scripts/fetch-plannotator-tui.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,27 @@ function Install-PlannotatorTui {
}
}

# .NET rather than Get-FileHash: in Windows PowerShell 5.1, Get-FileHash is a script function of
# Microsoft.PowerShell.Utility, not a compiled cmdlet. A powershell.exe started by a process that
# came from PowerShell 7 inherits a PSModulePath listing PowerShell 7's modules first, loads that
# Core-only Utility manifest instead, and Get-FileHash does not exist. SHA256 from .NET is the
# same in 5.1 and 7 whatever the module path says.
function Get-Sha256Hex {
param([Parameter(Mandatory = $true)][string]$LiteralPath)

$stream = [System.IO.File]::OpenRead($LiteralPath)
try {
$sha256 = [System.Security.Cryptography.SHA256]::Create()
try {
[System.BitConverter]::ToString($sha256.ComputeHash($stream)).Replace("-", "").ToLowerInvariant()
} finally {
$sha256.Dispose()
}
} finally {
$stream.Dispose()
}
}

if ($hasLocalOverride) {
if (-not (Test-Path -LiteralPath $localOverride -PathType Leaf)) {
throw "PLANNOTATOR_TUI_BIN is not a file: $localOverride"
Expand Down Expand Up @@ -166,7 +187,7 @@ try {
}
$checksumFields = $matches[0].Trim() -split "\s+"
$expected = $checksumFields[0].ToLowerInvariant()
$actual = (Get-FileHash -Algorithm SHA256 -LiteralPath $downloadedAsset).Hash.ToLowerInvariant()
$actual = Get-Sha256Hex -LiteralPath $downloadedAsset
if ($actual -ne $expected) {
throw "sha256 mismatch for ${asset}: expected $expected, got $actual"
}
Expand Down
17 changes: 17 additions & 0 deletions scripts/test-windows-full-manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@
"stage-plannotator-tui.ps1",
],
]
# The Windows builds run under powershell.exe 5.1, where Get-FileHash is a script function of
# Microsoft.PowerShell.Utility. Started from a PowerShell 7 session, 5.1 inherits a PSModulePath
# that loads PowerShell 7's Core-only Utility manifest instead and Get-FileHash is missing, so the
# fetchers hash with .NET.
WINDOWS_FETCHERS = ["scripts/fetch-herdr-annotate.ps1", "scripts/fetch-plannotator-tui.ps1"]


def fail(path: Path, message: str) -> None:
Expand Down Expand Up @@ -218,6 +223,17 @@ def check_distributed(path: Path, version_path: Path, native_version_path: Path)
check_no_link_capture(path, manifest)


def check_windows_fetchers(root: Path) -> None:
for relative in WINDOWS_FETCHERS:
path = root / relative
text = path.read_text(encoding="utf-8")
for number, line in enumerate(text.splitlines(), 1):
if "Get-FileHash" in line.split("#", 1)[0]:
fail(path, f"line {number} calls Get-FileHash, which 5.1 may not have")
if "Get-Sha256Hex -LiteralPath" not in text:
fail(path, "the download is not checked with Get-Sha256Hex")


def check_development(path: Path) -> None:
manifest = load(path)
check_top_level_windows(path, manifest)
Expand Down Expand Up @@ -411,6 +427,7 @@ def main() -> None:
root / "windows-full" / "herdr-plugin.toml",
root / "herdr-plugin.toml",
)
check_windows_fetchers(root)
lite = root / "lite" / "herdr-plugin.toml"
check_no_link_capture(lite, load(lite))
check_links(root / "links" / "herdr-plugin.toml", root / "herdr-plugin.toml")
Expand Down
Loading