provisioning-core/nulib/tools/nickel/process.nu
Jesús Pérez c22722a418
core: push cluster foundation out of cli/components.nu to proper layers (ADR-026 slice 2a)
Untangle the shared foundation that the cluster subsystem depends on, moving each
helper to the layer its dependency topology dictates, de-cli-ifying on the way
(cli-err → error make). One-directional imports only; verified no cycles.

  comp-ncl-export                        → tools/nickel/process.nu
  ws-resolution (8 fns + root finders)   → domain/workspace/resolve.nu  (new)
  comp-ssh-run, comp-server-ssh-info     → platform/clients/ssh.nu       (new)
  comp-kubectl-access, comp-kubectl-ssh  → domain/cluster/access.nu      (new)

Consumers (components.nu, components_cluster.nu, component.nu) repointed to the
new locations. components.nu 2664 → 2408.

Verified: NU_LIB_DIRS module-load of all 8 touched modules (no cycle, no missing
command, no export error); ADR-026 hygiene (no upward imports in the new
platform/domain/tools modules); `provisioning component list` runs; component/cluster
--help exit 0. Prereq for slice 2b (cluster helpers → domain/cluster/introspect.nu).
2026-07-10 07:16:14 +01:00

115 lines
4.5 KiB
Text

# Nickel file processor — plugin-backed evaluation with cache, with direct fallback.
# Raw export via ^nickel binary (no cache). Used internally as fallback.
export def process_nickel_export_raw [
src_file: string
out_format: string
]: nothing -> string {
let prov_root = ($env.PROVISIONING? | default "/usr/local/provisioning")
^nickel export $src_file --format $out_format --import-path $prov_root
}
# Build the canonical import path list — used by callers that want explicit control.
#
# NOTE: After dropping import_paths from the cache key (plugin + daemon),
# the list passed here only affects cold-path nickel export invocations, NOT
# cache lookups. So mismatches between daemon and caller no longer cause misses.
export def default-ncl-paths [workspace: string = ""]: nothing -> list {
let ws = if ($workspace | is-not-empty) { $workspace } else { $env.PWD }
# Workspace-scoped paths (ontoref convention)
mut paths = [
($ws | path join ".ontology")
($ws | path join "adrs")
($ws | path join ".ontoref" | path join "ontology" | path join "schemas")
($ws | path join ".ontoref" | path join "adrs")
($ws | path join ".onref")
$ws
]
# $PROVISIONING
if ($env.PROVISIONING? | is-not-empty) { $paths = ($paths | append $env.PROVISIONING) }
# $NICKEL_IMPORT_PATH — colon-separated
if ($env.NICKEL_IMPORT_PATH? | is-not-empty) {
for entry in ($env.NICKEL_IMPORT_PATH | split row ":" | where { $in | is-not-empty }) {
$paths = ($paths | append $entry)
}
}
# $ONTOREF_ROOT — auto-discover or default macOS path
let ontoref_root = if ($env.ONTOREF_ROOT? | is-not-empty) {
$env.ONTOREF_ROOT
} else {
let home = ($env.HOME? | default "~" | path expand)
let mac_path = ($home | path join "Library" | path join "Application Support" | path join "ontoref")
let linux_path = ($home | path join ".local" | path join "share" | path join "ontoref")
if ($mac_path | path exists) {
$mac_path
} else {
if ($linux_path | path exists) { $linux_path } else { "" }
}
}
if ($ontoref_root | is-not-empty) {
$paths = ($paths | append [
($ontoref_root | path join "ontology")
($ontoref_root | path join "ontology" | path join "schemas")
($ontoref_root | path join "reflection")
($ontoref_root | path join "reflection" | path join "schemas")
($ontoref_root | path join "adrs")
$ontoref_root
] | flatten)
}
# De-duplicate preserving order (same as daemon)
$paths | reduce --fold [] {|it, acc|
if ($it in $acc) { $acc } else { $acc | append $it }
}
}
# Evaluate a Nickel file via the plugin (cached). Error propagates on failure.
#
# Equivalent to: ^nickel export --format json --import-path ... $path | from json
# but uses the nu_plugin_nickel cache, returning a Nu record/list directly.
export def ncl-eval [
path: string
import_paths: list = []
]: nothing -> any {
nickel-eval $path --import-path $import_paths
}
# Evaluate a Nickel file via the plugin (cached). Returns `fallback` on any error.
#
# Use for best-effort reads where failure is acceptable (e.g. optional NCL files).
# try/catch is valid for Nu plugin commands in Nu 0.111.0+.
export def ncl-eval-soft [
path: string
import_paths: list = []
fallback: any = null
]: nothing -> any {
try {
nickel-eval $path --import-path $import_paths
} catch {
$fallback
}
}
# Export a workspace-relative NCL file to a record, resolving import paths from the
# workspace root. Always calls nickel directly (no plugin cache) — deploy/ops paths
# require fresh config. Set PROVISIONING_USE_CACHE=true to opt into the plugin cache
# (read-only queries only).
export def comp-ncl-export [ws_root: string, rel_path: string]: nothing -> record {
let full_path = ($ws_root | path join $rel_path)
let use_cache = ($env.PROVISIONING_USE_CACHE? | default "false") == "true"
if $use_cache {
ncl-eval $full_path (default-ncl-paths $ws_root)
} else {
let import_paths = (default-ncl-paths $ws_root)
let import_args = ($import_paths | each {|p| ["--import-path" $p] } | flatten)
let r = (do { ^nickel export --format json $full_path ...$import_args } | complete)
if $r.exit_code != 0 {
error make {msg: $"NCL evaluation failed for ($full_path): ($r.stderr | str trim)"}
}
$r.stdout | from json
}
}