Add portable Linux packaging and verify distribution notices
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#Requires -Version 5.1
|
||||
# Read-only dependency preflight. Does not build, download, or change a Cargo target.
|
||||
function Get-WindowsNotices([string]$Repository, [string]$Target, [string]$NoticeManifest, [string]$LlvmMinGWRoot) {
|
||||
function Get-ArcadiaNotices([string]$Repository, [string]$Target, [string]$NoticeManifest, [string]$LlvmMinGWRoot, [string[]]$RootPackages = @('oa-desktop', 'oa-server')) {
|
||||
if ($RootPackages.Count -eq 0 -or @($RootPackages | Where-Object { $_ -notin @('oa-desktop', 'oa-server') }).Count -gt 0) { throw 'Notice roots must be oa-desktop and/or oa-server.' }
|
||||
if ($LlvmMinGWRoot -and $Target -ne 'x86_64-pc-windows-gnullvm') { throw 'LLVM-MinGW runtime notices apply only to the gnullvm target.' }
|
||||
function Hash-File([string]$Path) {
|
||||
$stream = [IO.File]::OpenRead($Path)
|
||||
$sha = [Security.Cryptography.SHA256]::Create()
|
||||
@@ -10,7 +12,8 @@ function Get-WindowsNotices([string]$Repository, [string]$Target, [string]$Notic
|
||||
function Under-Root([string]$Root, [string]$Relative) {
|
||||
$base = [IO.Path]::GetFullPath($Root).TrimEnd('\', '/') + [IO.Path]::DirectorySeparatorChar
|
||||
$path = [IO.Path]::GetFullPath((Join-Path $base $Relative))
|
||||
if (-not $path.StartsWith($base, [StringComparison]::OrdinalIgnoreCase)) { throw "Notice path escapes source root: $Relative" }
|
||||
$comparison = if ([IO.Path]::DirectorySeparatorChar -eq '/') { [StringComparison]::Ordinal } else { [StringComparison]::OrdinalIgnoreCase }
|
||||
if (-not $path.StartsWith($base, $comparison)) { throw "Notice path escapes source root: $Relative" }
|
||||
if (-not [IO.File]::Exists($path)) { throw "Required notice/source missing: $path" }
|
||||
return $path
|
||||
}
|
||||
@@ -39,6 +42,17 @@ function Get-WindowsNotices([string]$Repository, [string]$Target, [string]$Notic
|
||||
}
|
||||
$lock = Under-Root $Repository 'Cargo.lock'
|
||||
$lockHash = Hash-File $lock
|
||||
# Shared compiler inputs live outside individual crate directories.
|
||||
$workspaceInputs = [ordered]@{}
|
||||
foreach ($relative in @('Cargo.toml', 'Cargo.lock', 'LICENSE', 'docs/openapi.json')) {
|
||||
$workspaceInputs[$relative] = Hash-File (Under-Root $Repository $relative)
|
||||
}
|
||||
foreach ($file in @(Get-ChildItem -LiteralPath (Join-Path $Repository 'build') -Recurse -File | Sort-Object FullName)) {
|
||||
if (($file.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw 'Shared build input reparse point requires review.' }
|
||||
$relative = $file.FullName.Substring([IO.Path]::GetFullPath($Repository).TrimEnd('\', '/').Length + 1).Replace('\', '/')
|
||||
$workspaceInputs[$relative] = Hash-File $file.FullName
|
||||
}
|
||||
if (-not $workspaceInputs.Contains('build/windows_manifest.rs')) { throw 'Shared Windows build manifest input is missing.' }
|
||||
$locked = @{}
|
||||
foreach ($block in ([IO.File]::ReadAllText($lock) -split '(?m)^\[\[package\]\]\s*$')) {
|
||||
$fields = @{}
|
||||
@@ -53,7 +67,7 @@ function Get-WindowsNotices([string]$Repository, [string]$Target, [string]$Notic
|
||||
foreach ($package in $metadata.packages) { $packages[$package.id] = $package }
|
||||
foreach ($node in $metadata.resolve.nodes) { $nodes[$node.id] = $node }
|
||||
$queue = New-Object 'Collections.Generic.Queue[string]'
|
||||
foreach ($name in @('oa-desktop', 'oa-server')) {
|
||||
foreach ($name in @($RootPackages | Sort-Object -Unique)) {
|
||||
$roots = @($metadata.packages | Where-Object { $_.name -eq $name -and $metadata.workspace_members -contains $_.id })
|
||||
if ($roots.Count -ne 1) { throw "Expected one workspace package: $name" }
|
||||
$queue.Enqueue($roots[0].id)
|
||||
@@ -100,8 +114,15 @@ function Get-WindowsNotices([string]$Repository, [string]$Target, [string]$Notic
|
||||
# conservatively. Tests/examples/benches are excluded, never all font files by glob.
|
||||
if ($file.Extension -eq '.rs' -and $relative -notmatch '^(tests|examples|benches)/') {
|
||||
$text = [IO.File]::ReadAllText($file.FullName)
|
||||
# Full-line comments, including rustdoc examples, are not compiled
|
||||
# font embeds. Keep real code and feature-gated macros conservative.
|
||||
$text = [regex]::Replace($text, '(?m)^[\t ]*//[^\r\n]*', '')
|
||||
foreach ($match in [regex]::Matches($text, 'include_bytes!\s*\(\s*"([^"]+\.(?:ttf|otf|woff2?))"')) {
|
||||
$font = Under-Root $root ([IO.Path]::GetFullPath((Join-Path $file.DirectoryName $match.Groups[1].Value)).Substring($root.Length + 1))
|
||||
$fontPath = [IO.Path]::GetFullPath((Join-Path $file.DirectoryName $match.Groups[1].Value))
|
||||
$fontRoot = [IO.Path]::GetFullPath($root).TrimEnd('\', '/') + [IO.Path]::DirectorySeparatorChar
|
||||
$fontComparison = if ([IO.Path]::DirectorySeparatorChar -eq '/') { [StringComparison]::Ordinal } else { [StringComparison]::OrdinalIgnoreCase }
|
||||
if (-not $fontPath.StartsWith($fontRoot, $fontComparison)) { throw "Embedded font path escapes crate source root: $key/$relative" }
|
||||
$font = Under-Root $root $fontPath.Substring($fontRoot.Length)
|
||||
[void]$fontReferences.Add($font.Substring($root.Length + 1).Replace('\', '/'))
|
||||
}
|
||||
}
|
||||
@@ -156,5 +177,10 @@ function Get-WindowsNotices([string]$Repository, [string]$Target, [string]$Notic
|
||||
}
|
||||
}
|
||||
if ($failures.Count -gt 0) { throw ("Notice preflight unresolved:`n - " + ($failures -join "`n - ")) }
|
||||
return [pscustomobject]@{ Inputs = $inputs; Hashes = $hashes; Inventory = [ordered]@{ format_version = 1; target = $Target; cargo_lock_sha256 = $lockHash; scope = 'Target-filtered locked offline metadata; transitive normal/build edges from oa-desktop and oa-server. Workspace feature unification may include a conservative superset. No binary/source equivalence or universal license audit claimed.'; packages = @($records.ToArray()); rust = [ordered]@{ version = $rustVersion; notices = $rustNotices; target_libraries_sha256 = $rustLibraries }; runtime = $runtime } }
|
||||
return [pscustomobject]@{ Inputs = $inputs; Hashes = $hashes; Inventory = [ordered]@{ format_version = 1; target = $Target; root_packages = @($RootPackages | Sort-Object -Unique); cargo_lock_sha256 = $lockHash; workspace_build_inputs_sha256 = $workspaceInputs; scope = 'Target-filtered locked offline metadata; transitive normal/build edges from the stated root packages. Workspace feature unification may include a conservative superset. No binary/source equivalence or universal license audit claimed.'; packages = @($records.ToArray()); rust = [ordered]@{ version = $rustVersion; notices = $rustNotices; target_libraries_sha256 = $rustLibraries }; runtime = $runtime } }
|
||||
}
|
||||
|
||||
# Compatibility entry point for the reviewed Windows pipeline and its callers.
|
||||
function Get-WindowsNotices([string]$Repository, [string]$Target, [string]$NoticeManifest, [string]$LlvmMinGWRoot) {
|
||||
Get-ArcadiaNotices $Repository $Target $NoticeManifest $LlvmMinGWRoot
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user