169 lines
5.4 KiB
Plaintext
169 lines
5.4 KiB
Plaintext
|
|
#!/usr/bin/env nu
|
||
|
|
# Check environment prerequisites for ontoref operations.
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# nu reflection/bin/check-prereqs.nu
|
||
|
|
# nu reflection/bin/check-prereqs.nu --context ci
|
||
|
|
# nu reflection/bin/check-prereqs.nu --context agent
|
||
|
|
# nu reflection/bin/check-prereqs.nu --form new_adr
|
||
|
|
# nu reflection/bin/check-prereqs.nu --context local_dev --severity Hard
|
||
|
|
|
||
|
|
def main [
|
||
|
|
--context: string = "local_dev",
|
||
|
|
--form: string = "",
|
||
|
|
--severity: string = "",
|
||
|
|
--json,
|
||
|
|
] {
|
||
|
|
let base_file = "reflection/requirements/base.ncl"
|
||
|
|
let contexts_file = "reflection/requirements/contexts.ncl"
|
||
|
|
|
||
|
|
# Inline daemon-export with subprocess fallback (standalone script, no module imports).
|
||
|
|
let export_base = do { ^nickel export $base_file } | complete
|
||
|
|
if $export_base.exit_code != 0 {
|
||
|
|
error make { msg: "Failed to load base.ncl — is nickel installed?" }
|
||
|
|
}
|
||
|
|
let all_tools = ($export_base.stdout | from json | get tools)
|
||
|
|
|
||
|
|
let export_ctx = do { ^nickel export $contexts_file } | complete
|
||
|
|
if $export_ctx.exit_code != 0 {
|
||
|
|
error make { msg: "Failed to load contexts.ncl" }
|
||
|
|
}
|
||
|
|
let ctx_candidates = ($export_ctx.stdout | from json | get contexts | where id == $context)
|
||
|
|
if ($ctx_candidates | is-empty) {
|
||
|
|
error make { msg: $"Unknown context '($context)'. Valid: local_dev | ci | agent | benchmark" }
|
||
|
|
}
|
||
|
|
let ctx_def = ($ctx_candidates | first)
|
||
|
|
|
||
|
|
let tools = if ($form | is-empty) {
|
||
|
|
$all_tools | where { |it| $it.contexts | any { |c| $c == $context } }
|
||
|
|
} else {
|
||
|
|
$all_tools | where { |it| $it.used_by_forms | any { |f| $f == $form } }
|
||
|
|
}
|
||
|
|
|
||
|
|
let tools = if ($severity | is-empty) {
|
||
|
|
$tools
|
||
|
|
} else {
|
||
|
|
$tools | where { |it| $it.severity == $severity }
|
||
|
|
}
|
||
|
|
|
||
|
|
let results = $tools | each { |tool|
|
||
|
|
let is_plugin = ($tool.plugin_name? | is-not-empty)
|
||
|
|
|
||
|
|
# Presence check: plugin registry or PATH binary
|
||
|
|
let present = if $is_plugin {
|
||
|
|
plugin list | where name == $tool.plugin_name | is-not-empty
|
||
|
|
} else {
|
||
|
|
(do { run-external "which" $tool.binary } | complete | get exit_code) == 0
|
||
|
|
}
|
||
|
|
|
||
|
|
# Version: run check_cmd via nu -c for both binary and plugin tools
|
||
|
|
let version = if $present and ($tool.check_cmd | is-not-empty) {
|
||
|
|
do { nu -c $"($tool.check_cmd) | str trim" } | complete
|
||
|
|
| if $in.exit_code == 0 { $in.stdout | str trim } else { "unknown" }
|
||
|
|
} else if $present {
|
||
|
|
"present"
|
||
|
|
} else {
|
||
|
|
"not installed"
|
||
|
|
}
|
||
|
|
|
||
|
|
let version_ok = if $present and $version != "unknown" and $version != "present" {
|
||
|
|
let min_parts = ($tool.version_min | split row "." | each { |p| $p | into int })
|
||
|
|
let act_result = (
|
||
|
|
$version
|
||
|
|
| parse --regex $tool.version_extract
|
||
|
|
| if ($in | is-empty) { null } else { $in | first | get capture0 }
|
||
|
|
)
|
||
|
|
if ($act_result | is-empty) {
|
||
|
|
true # Cannot parse version — assume ok (plugin compat versions)
|
||
|
|
} else {
|
||
|
|
let act_parts = ($act_result | split row "." | each { |p| $p | into int })
|
||
|
|
let major_ok = ($act_parts | get 0) >= ($min_parts | get 0)
|
||
|
|
let minor_ok = if ($act_parts | get 0) == ($min_parts | get 0) {
|
||
|
|
($act_parts | get 1) >= ($min_parts | get 1)
|
||
|
|
} else { true }
|
||
|
|
$major_ok and $minor_ok
|
||
|
|
}
|
||
|
|
} else if $present {
|
||
|
|
true
|
||
|
|
} else {
|
||
|
|
false
|
||
|
|
}
|
||
|
|
|
||
|
|
let config_ok = if $present and ($tool.config_check? | is-not-empty) {
|
||
|
|
do { nu -c $tool.config_check } | complete | get exit_code | $in == 0
|
||
|
|
} else {
|
||
|
|
true
|
||
|
|
}
|
||
|
|
|
||
|
|
let display_name = if $is_plugin { $"plugin:($tool.plugin_name)" } else { $tool.binary }
|
||
|
|
|
||
|
|
{
|
||
|
|
id: $tool.id,
|
||
|
|
binary: $display_name,
|
||
|
|
severity: $tool.severity,
|
||
|
|
present: $present,
|
||
|
|
version: $version,
|
||
|
|
version_min: $tool.version_min,
|
||
|
|
version_ok: $version_ok,
|
||
|
|
config_ok: $config_ok,
|
||
|
|
status: (if not $present {
|
||
|
|
"MISSING"
|
||
|
|
} else if not $version_ok {
|
||
|
|
"VERSION_LOW"
|
||
|
|
} else if not $config_ok {
|
||
|
|
"CONFIG_FAIL"
|
||
|
|
} else {
|
||
|
|
"OK"
|
||
|
|
}),
|
||
|
|
install_hint: $tool.install_hint,
|
||
|
|
config_hint: ($tool.config_hint? | default ""),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if $json {
|
||
|
|
$results | to json
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
print $"Environment check — context: ($context)"
|
||
|
|
print $"─────────────────────────────────────────────────────"
|
||
|
|
|
||
|
|
let fails = $results | where status != "OK"
|
||
|
|
|
||
|
|
for r in $results {
|
||
|
|
let icon = match $r.status {
|
||
|
|
"OK" => "✓",
|
||
|
|
"MISSING" => "✗",
|
||
|
|
"VERSION_LOW" => "↑",
|
||
|
|
"CONFIG_FAIL" => "⚠",
|
||
|
|
_ => "?",
|
||
|
|
}
|
||
|
|
let sev = if $r.severity == "Hard" { "[Hard]" } else { "[Soft]" }
|
||
|
|
print $"($icon) ($sev) ($r.binary) ($r.version) [min: ($r.version_min)]"
|
||
|
|
}
|
||
|
|
|
||
|
|
print ""
|
||
|
|
|
||
|
|
if ($fails | is-empty) {
|
||
|
|
print "All checks passed."
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
let hard_fails = $fails | where severity == "Hard"
|
||
|
|
|
||
|
|
for f in $fails {
|
||
|
|
print $"── ($f.binary) — ($f.status) ──"
|
||
|
|
match $f.status {
|
||
|
|
"MISSING" => { print $" Install: ($f.install_hint)" },
|
||
|
|
"VERSION_LOW" => { print $" Installed: ($f.version) Required: >= ($f.version_min)" ; print $" Update: ($f.install_hint)" },
|
||
|
|
"CONFIG_FAIL" => { print $" Config issue: ($f.config_hint)" },
|
||
|
|
}
|
||
|
|
print ""
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($hard_fails | is-not-empty) {
|
||
|
|
let hard_ids = $hard_fails | get binary | str join ", "
|
||
|
|
error make { msg: $"Hard prerequisites not met: ($hard_ids)" }
|
||
|
|
}
|
||
|
|
}
|