switch to homegrown pinning
All checks were successful
Nix Build / nix build (push) Successful in 8s
All checks were successful
Nix Build / nix build (push) Successful in 8s
This commit is contained in:
parent
33313e0634
commit
ebeee537a4
1 changed files with 123 additions and 49 deletions
172
meat.nu
172
meat.nu
|
|
@ -34,10 +34,6 @@ def hn []: nothing -> string {
|
|||
^hostname | str trim
|
||||
}
|
||||
|
||||
def flake-target []: nothing -> string {
|
||||
$"($env.MEATS)#nixosConfigurations.(hn).config.system.build.toplevel"
|
||||
}
|
||||
|
||||
def system-attr []: nothing -> string {
|
||||
$"nixosConfigurations.(hn).config.system.build.toplevel"
|
||||
}
|
||||
|
|
@ -89,14 +85,14 @@ def cmd-yum [...args: string] {
|
|||
def cmd-cook [...args: string] {
|
||||
with-frame {
|
||||
meat-print "PREPARING DELICIOUS MEATS.."
|
||||
try { ^nix build --no-link (flake-target) ...$args }
|
||||
try { ^nix-build --no-out-link $"($env.MEATS)/entry.nix" -A (system-attr) ...$args }
|
||||
}
|
||||
}
|
||||
|
||||
def cmd-poke [...args: string] {
|
||||
with-frame {
|
||||
meat-print "PREPARING SUSPICIOUS MEATS.."
|
||||
try { ^nix build --no-link (flake-target) --show-trace ...$args }
|
||||
try { ^nix-build --no-out-link --show-trace $"($env.MEATS)/entry.nix" -A (system-attr) ...$args }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -114,64 +110,142 @@ def cmd-trade [] {
|
|||
}
|
||||
}
|
||||
|
||||
def cmd-fresh [...flakes: string] {
|
||||
def pins-path [] { $"($env.MEATS)/pins/pins.toml" }
|
||||
def lock-path [] { $"($env.MEATS)/pins/pins.lock.json" }
|
||||
|
||||
def load-pins [] {
|
||||
let p = pins-path
|
||||
if not ($p | path exists) { error make { msg: $"no pins file at ($p)" } }
|
||||
open --raw $p | from toml
|
||||
}
|
||||
|
||||
def load-lock [] {
|
||||
let p = lock-path
|
||||
if ($p | path exists) { open --raw $p | from json } else { {} }
|
||||
}
|
||||
|
||||
# Sort keys alphabetically and write atomically.
|
||||
def write-lock [lock: record] {
|
||||
let p = lock-path
|
||||
let sorted = $lock | columns | sort | reduce -f {} { |k, acc| $acc | insert $k ($lock | get $k) }
|
||||
let tmp = $"($p).tmp"
|
||||
$sorted | to json --indent 2 | save -f $tmp
|
||||
^mv $tmp $p
|
||||
}
|
||||
|
||||
# scheme:rest → expansion via {path} template, or pass-through.
|
||||
def expand-shorturl [url: string, shorturls: record] {
|
||||
let parts = $url | split row ":" -n 2
|
||||
if (($parts | length) < 2) { return $url }
|
||||
let scheme = $parts | get 0
|
||||
if not ($scheme in ($shorturls | columns)) { return $url }
|
||||
($shorturls | get $scheme) | str replace --regex '\{path\}' ($parts | get 1)
|
||||
}
|
||||
|
||||
# Decompose to {git_url, ref?} for cheap ls-remote queries (used by `look`).
|
||||
def parse-git-target [url: string] {
|
||||
if ($url | str starts-with "github:") {
|
||||
let body = $url | str substring 7..
|
||||
let path_query = $body | split row "?" -n 2
|
||||
let segs = ($path_query | get 0) | split row "/"
|
||||
let owner = $segs | get 0
|
||||
let repo = $segs | get 1
|
||||
let ref = if (($segs | length) > 2) { $segs | skip 2 | str join "/" } else { null }
|
||||
return { git_url: $"https://github.com/($owner)/($repo).git", ref: $ref }
|
||||
}
|
||||
if ($url | str starts-with "git+") {
|
||||
let stripped = $url | str substring 4..
|
||||
let parts = $stripped | split row "?" -n 2
|
||||
let base = $parts | get 0
|
||||
let ref = if (($parts | length) > 1) {
|
||||
($parts | get 1) | split row "&" | each { |kv|
|
||||
let kvp = $kv | split row "=" -n 2
|
||||
{ k: ($kvp | get 0), v: ($kvp | get 1?) }
|
||||
} | where k == "ref" | get -o 0 | get -o v
|
||||
} else { null }
|
||||
return { git_url: $base, ref: $ref }
|
||||
}
|
||||
error make { msg: $"unsupported url scheme for ls-remote: ($url)" }
|
||||
}
|
||||
|
||||
# Cheap "is upstream ahead?" check via git ls-remote. Returns the rev string.
|
||||
def ls-remote-head [url: string] {
|
||||
let tgt = parse-git-target $url
|
||||
let target_ref = if ($tgt.ref? | is-not-empty) { $"refs/heads/($tgt.ref)" } else { "HEAD" }
|
||||
let r = ^git ls-remote $tgt.git_url $target_ref | complete
|
||||
if $r.exit_code != 0 { error make { msg: $"ls-remote failed: ($r.stderr)" } }
|
||||
let first = $r.stdout | str trim | lines | get -o 0
|
||||
if ($first | is-empty) { error make { msg: "no refs returned" } }
|
||||
$first | split row "\t" | get 0
|
||||
}
|
||||
|
||||
# Real prefetch — caches in /nix/store and returns the full locked attrset.
|
||||
# Output JSON: { hash: SRI, locked: {...}, original: {...}, storePath: PATH }
|
||||
def prefetch-pin [url: string] {
|
||||
let r = ^nix flake prefetch --json $url | complete
|
||||
if $r.exit_code != 0 { error make { msg: $"prefetch failed for ($url): ($r.stderr)" } }
|
||||
let j = $r.stdout | from json
|
||||
$j.locked | insert narHash $j.hash
|
||||
}
|
||||
|
||||
def cmd-fresh [...names: string] {
|
||||
with-frame {
|
||||
meat-print "HUNTING FRESH MEATS.."
|
||||
let root = $env.MEATS
|
||||
if ($flakes | is-empty) {
|
||||
try { ^nix flake update --flake $root }
|
||||
} else {
|
||||
for f in $flakes {
|
||||
if ($f | str downcase) == "meat" {
|
||||
meat-print "PROCESSING REAL MEAT.."
|
||||
} else {
|
||||
meat-print $"PROCESSING FRESH MEAT ($f | str upcase).."
|
||||
let pins = load-pins
|
||||
let shorturls = $pins.shorturls? | default {}
|
||||
let inputs = $pins.inputs
|
||||
mut lock = load-lock
|
||||
|
||||
let targets = if ($names | is-empty) { $inputs | columns } else { $names }
|
||||
|
||||
for name in $targets {
|
||||
if not ($name in ($inputs | columns)) {
|
||||
meat-print $"NO MEAT CALLED ($name | str upcase).."
|
||||
continue
|
||||
}
|
||||
meat-print $"PROCESSING ($name | str upcase).."
|
||||
try {
|
||||
let pin = $inputs | get $name
|
||||
let expanded = expand-shorturl $pin.url $shorturls
|
||||
let entry = prefetch-pin $expanded
|
||||
let old_rev = ($lock | get -o $name) | default {} | get -o rev
|
||||
let new_rev = $entry.rev
|
||||
if $old_rev == $new_rev {
|
||||
meat-print $" ($name | str upcase) STILL FRESH"
|
||||
continue
|
||||
}
|
||||
try { ^nix flake update $f --flake $root }
|
||||
$lock = $lock | upsert $name $entry
|
||||
write-lock $lock
|
||||
let from = if ($old_rev | is-empty) { "NEW" } else { $old_rev | str substring 0..8 }
|
||||
meat-print $" ($name | str upcase): ($from) -> ($new_rev | str substring 0..8)"
|
||||
} catch { |e|
|
||||
meat-print $" NO FIND ($name | str upcase): ($e.msg)"
|
||||
}
|
||||
}
|
||||
}
|
||||
print ""
|
||||
}
|
||||
|
||||
def lookup-input [nodes: record, name: string, node_ref: any] {
|
||||
let node_name = if (($node_ref | describe) == "string") { $node_ref } else { $name }
|
||||
let node = $nodes | get $node_name
|
||||
let locked = $node.locked
|
||||
let original = $node.original
|
||||
let url = match $locked.type {
|
||||
"github" => $"https://github.com/($locked.owner)/($locked.repo).git"
|
||||
"git" => $original.url
|
||||
_ => { error make { msg: $"unsupported type: ($locked.type)" } }
|
||||
}
|
||||
let target_ref = if ('ref' in $original) { $"refs/heads/($original.ref)" } else { "HEAD" }
|
||||
let out = ^git ls-remote $url $target_ref | complete
|
||||
if $out.exit_code != 0 {
|
||||
error make { msg: "git ls-remote failed" }
|
||||
}
|
||||
let first_line = $out.stdout | str trim | lines | get 0?
|
||||
if ($first_line | is-empty) {
|
||||
error make { msg: "no refs returned" }
|
||||
}
|
||||
let latest = $first_line | split row "\t" | first
|
||||
{ name: $name, locked: $locked.rev, latest: $latest }
|
||||
}
|
||||
|
||||
def cmd-look [] {
|
||||
with-frame {
|
||||
meat-print "LOOK FOR NEW MEATS.."
|
||||
let lock = open --raw $"($env.MEATS)/flake.lock" | from json
|
||||
let nodes = $lock.nodes
|
||||
let root_inputs = $nodes.root.inputs
|
||||
let stale = $root_inputs | transpose name node_ref | each { |row|
|
||||
let pins = load-pins
|
||||
let shorturls = $pins.shorturls? | default {}
|
||||
let inputs = $pins.inputs
|
||||
let lock = load-lock
|
||||
|
||||
let stale = $inputs | transpose name pin | each { |row|
|
||||
try {
|
||||
let r = lookup-input $nodes $row.name $row.node_ref
|
||||
if $r.latest != $r.locked {
|
||||
meat-print $"($r.name | str upcase) MEAT RIPE!"
|
||||
$r.name
|
||||
let expanded = expand-shorturl $row.pin.url $shorturls
|
||||
let new_rev = ls-remote-head $expanded
|
||||
let old_rev = ($lock | get -o $row.name) | default {} | get -o rev
|
||||
if $old_rev != $new_rev {
|
||||
let from = if ($old_rev | is-empty) { "NEW" } else { $old_rev | str substring 0..8 }
|
||||
meat-print $" ($row.name | str upcase): ($from) -> ($new_rev | str substring 0..8)"
|
||||
$row.name
|
||||
} else { null }
|
||||
} catch {
|
||||
meat-print $"NO FIND ($row.name | str upcase).."
|
||||
meat-print $" NO FIND ($row.name | str upcase).."
|
||||
null
|
||||
}
|
||||
} | compact
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue