export def require [ok: bool, message: string] {
if not $ok { error make {msg: $message} }
}
export def digest [path: string] { open --raw $path | hash sha256 }
export def pair-input [identity: record, side: string, cache: string] {
require ($side in [baseline current]) 'invalid package side'
let relative_archive = (if $side == baseline { 'published.crate' } else { 'package-target/package/cyber-nox-0.2.0.crate' })
$identity | get $side | merge {
root: ($cache | path join $side cyber-nox-0.2.0),
archive: ($cache | path join $relative_archive)
}
}
export def package-inputs [root: string] {
^rg --files --hidden $root | lines | sort | each {|p|
{path: ($p | path relative-to $root), sha256: (digest $p)}
}
}
def compiler-path [p: string] {
(not ($p | str starts-with audit/) and not ($p | str starts-with .claude/)
and (($p | str ends-with '.rs') or ($p | str starts-with '.cargo/')
or ($p | path basename) in [Cargo.toml Cargo.lock rust-toolchain.toml rust-toolchain]))
}
export def owner-inputs [root: string] {
let config = ($root | path join .cargo)
let config_paths = (if ($config | path exists) {
^rg --files --hidden --no-ignore $config | lines | each {|p| $p | path relative-to $root}
} else { [] })
^git -C $root ls-files --cached --others --exclude-standard | lines | append $config_paths | sort | uniq
| where {|p| compiler-path $p}
| each {|p| {path: $p, sha256: (digest ($root | path join $p))}}
}
export def committed-owner [root: string] {
let files = (owner-inputs $root)
let paths = (^git -C $root ls-tree -r --name-only HEAD | lines | where {|p| compiler-path $p} | sort)
require (($files | get path) == $paths) 'owning compiler inventory is not committed'
for file in $files {
let body = (do { ^git -C $root show $'HEAD:($file.path)' } | complete)
require ($body.exit_code == 0 and ($body.stdout | hash sha256) == $file.sha256) $'owning compiler input differs from HEAD: ($file.path)'
}
$files
}
export def capture [out: string, name: string, argv: list<string>, cwd: string, environment: record, expected: int = 0] {
for suffix in [json stdout stderr] {
require (not ($out | path join $'($name).($suffix)' | path exists)) $'receipt already exists: ($name).($suffix)'
}
let started = (date now | format date '%+')
let result = (with-env $environment { cd $cwd; do { ^($argv | first) ...($argv | skip 1) } | complete })
$result.stdout | save ($out | path join $'($name).stdout')
$result.stderr | save ($out | path join $'($name).stderr')
let record = {command: $argv, cwd: $cwd, env: $environment, started: $started,
finished: (date now | format date '%+'), exit_code: $result.exit_code, expected_exit_code: $expected,
stdout_sha256: ($result.stdout | hash sha256), stderr_sha256: ($result.stderr | hash sha256)}
$record | to json | save ($out | path join $'($name).json')
require ($result.exit_code == $expected) $'unexpected command outcome: ($name), exit ($result.exit_code)'
$record
}
export def extract-crate [archive: string, destination: string] {
require (not ($destination | path exists)) 'package destination already exists'
let listing = (do { ^tar -tzf $archive } | complete)
require ($listing.exit_code == 0) 'cannot list crate archive'
for entry in ($listing.stdout | lines) {
require (($entry | str starts-with 'cyber-nox-0.2.0/') and not ('..' in ($entry | split row '/'))) 'unexpected archive member'
}
mkdir $destination
let extracted = (do { ^tar -xzf $archive -C $destination } | complete)
require ($extracted.exit_code == 0) 'cannot extract crate archive'
$destination | path join cyber-nox-0.2.0
}
export def check-rust-against-git [repo: string, revision: string, package: string] {
let files = (package-inputs $package | where {|f| $f.path | str ends-with '.rs'})
let git_paths = (^git -C $repo ls-tree -r --name-only $revision -- rs | lines
| where {|p| $p | str ends-with '.rs'} | each {|p| $p | str substring 3..} | sort)
require (($files | get path | sort) == $git_paths) 'package Rust inventory differs from owning revision'
for file in $files {
let git_bytes = (do { ^git -C $repo show $'($revision):rs/($file.path)' } | complete)
require ($git_bytes.exit_code == 0 and ($git_bytes.stdout | hash sha256) == $file.sha256) $'package Rust differs: ($file.path)'
}
$files
}