132 lines
5.6 KiB
Text
132 lines
5.6 KiB
Text
|
|
# Workspace path/root/state resolution — extracted from cli/components.nu (ADR-026 slice 2a-ii).
|
||
|
|
use platform/user/config.nu [get-active-workspace-details list-workspaces]
|
||
|
|
|
||
|
|
# Resolve the first server hostname present in the state file for a workspace.
|
||
|
|
# Used by --live to find which host to SSH into when the DAG server is unknown.
|
||
|
|
export def comp-state-server [workspace_path: string]: nothing -> string {
|
||
|
|
let st = (state-read $workspace_path)
|
||
|
|
$st.servers
|
||
|
|
| transpose hostname srv
|
||
|
|
| where {|row| ($row.srv.taskservs? | default {} | is-not-empty) }
|
||
|
|
| get 0?
|
||
|
|
| get -o hostname
|
||
|
|
| default ""
|
||
|
|
}
|
||
|
|
|
||
|
|
# ─── SSH + k0s kubectl live check infrastructure ─────────────────────────────
|
||
|
|
|
||
|
|
# Resolve workspace root path (exported for use by component.nu dispatcher).
|
||
|
|
export def comp-ws-path [workspace: string]: nothing -> string {
|
||
|
|
comp-resolve-ws-path $workspace
|
||
|
|
}
|
||
|
|
|
||
|
|
# Auto-detect infra name from workspace root (exported for use by component.nu dispatcher).
|
||
|
|
export def comp-ws-infra [ws_root: string]: nothing -> string {
|
||
|
|
ls ($ws_root | path join "infra")
|
||
|
|
| where type == dir
|
||
|
|
| get name
|
||
|
|
| each {|p| $p | path basename }
|
||
|
|
| where {|n| ($ws_root | path join "infra" $n "settings.ncl" | path exists) }
|
||
|
|
| get 0?
|
||
|
|
| default ""
|
||
|
|
}
|
||
|
|
|
||
|
|
# Resolve workspace name: explicit --workspace flag or active workspace.
|
||
|
|
# A path counts as a workspace ONLY if it has real workspace content — not just
|
||
|
|
# any directory that happens to be called "infra/". Otherwise $HOME/infra/
|
||
|
|
# (or similar incidental dirs) hijack the walk-up and shadow the active workspace.
|
||
|
|
def is-workspace-root [path: string]: nothing -> bool {
|
||
|
|
if (($path | path join ".ontology") | path exists) { return true }
|
||
|
|
if (($path | path join "config" "provisioning.ncl") | path exists) { return true }
|
||
|
|
let infra_dir = ($path | path join "infra")
|
||
|
|
if not ($infra_dir | path exists) { return false }
|
||
|
|
# Require at least one infra/*/settings.ncl to treat this as a workspace root.
|
||
|
|
(ls $infra_dir | where type == dir | get name
|
||
|
|
| any { |p| ($p | path join "settings.ncl" | path exists) })
|
||
|
|
}
|
||
|
|
|
||
|
|
def find-workspace-root-up [path: string]: nothing -> string {
|
||
|
|
if ($path | is-empty) or $path == "/" { return "" }
|
||
|
|
if (is-workspace-root $path) { return $path }
|
||
|
|
let parent = ($path | path dirname)
|
||
|
|
if $parent == $path { return "" }
|
||
|
|
find-workspace-root-up $parent
|
||
|
|
}
|
||
|
|
|
||
|
|
# Walk up from $path looking for a sibling `workspaces/<name>/` that qualifies as
|
||
|
|
# a workspace root. Returns the full path to the workspace, or "" if not found.
|
||
|
|
def find-named-workspace-up [path: string, name: string]: nothing -> string {
|
||
|
|
if ($path | is-empty) or $path == "/" { return "" }
|
||
|
|
let candidate = ($path | path join "workspaces" $name)
|
||
|
|
if ($candidate | path exists) and (is-workspace-root $candidate) {
|
||
|
|
return $candidate
|
||
|
|
}
|
||
|
|
let parent = ($path | path dirname)
|
||
|
|
if $parent == $path { return "" }
|
||
|
|
find-named-workspace-up $parent $name
|
||
|
|
}
|
||
|
|
|
||
|
|
# Derive the project root from $env.PROVISIONING (typically
|
||
|
|
# `<project-root>/provisioning`). Returns "" if PROVISIONING is unset.
|
||
|
|
def project-root-from-prov []: nothing -> string {
|
||
|
|
let prov = ($env.PROVISIONING? | default "")
|
||
|
|
if ($prov | is-empty) { return "" }
|
||
|
|
$prov | path dirname
|
||
|
|
}
|
||
|
|
|
||
|
|
# Returns the workspace ROOT PATH (not name) — works for both registered and unregistered workspaces.
|
||
|
|
export def comp-resolve-ws-path [workspace: string]: nothing -> string {
|
||
|
|
# 1. Explicit --workspace → resolve to a path.
|
||
|
|
if ($workspace | is-not-empty) {
|
||
|
|
# 1a. Absolute or CWD-relative path that is itself a workspace root.
|
||
|
|
let as_path = ($workspace | path expand)
|
||
|
|
if ($as_path | path exists) and (is-workspace-root $as_path) {
|
||
|
|
return $as_path
|
||
|
|
}
|
||
|
|
# 1b. Registered in the user config.
|
||
|
|
let registered = (
|
||
|
|
list-workspaces
|
||
|
|
| where { |ws| $ws.name == $workspace }
|
||
|
|
| get -o 0
|
||
|
|
)
|
||
|
|
if ($registered | is-not-empty) {
|
||
|
|
return $registered.path
|
||
|
|
}
|
||
|
|
# 1c. Walk up from CWD looking for a sibling `workspaces/<name>/`.
|
||
|
|
let from_cwd = (find-named-workspace-up $env.PWD $workspace)
|
||
|
|
if ($from_cwd | is-not-empty) { return $from_cwd }
|
||
|
|
# 1d. Derive from $env.PROVISIONING — the canonical project-root anchor.
|
||
|
|
let project_root = (project-root-from-prov)
|
||
|
|
if ($project_root | is-not-empty) {
|
||
|
|
let from_prov = ($project_root | path join "workspaces" $workspace)
|
||
|
|
if ($from_prov | path exists) and (is-workspace-root $from_prov) {
|
||
|
|
return $from_prov
|
||
|
|
}
|
||
|
|
}
|
||
|
|
error make {msg: $"Workspace '($workspace)' not found in registry, CWD ancestors, or under ($project_root)/workspaces/"}
|
||
|
|
}
|
||
|
|
# 2. Detect from CWD: registered workspace whose path is prefix of CWD
|
||
|
|
let pwd = $env.PWD
|
||
|
|
let from_registry = (
|
||
|
|
list-workspaces
|
||
|
|
| where { |ws| ($ws.path | is-not-empty) and ($pwd | str starts-with $ws.path) }
|
||
|
|
| sort-by { |ws| ($ws.path | str length) }
|
||
|
|
| last # longest match wins
|
||
|
|
)
|
||
|
|
if not ($from_registry | is-empty) {
|
||
|
|
return $from_registry.path
|
||
|
|
}
|
||
|
|
# 3. Unregistered: walk up CWD until workspace markers found
|
||
|
|
let ws_root = (find-workspace-root-up $pwd)
|
||
|
|
if ($ws_root | is-not-empty) {
|
||
|
|
return $ws_root
|
||
|
|
}
|
||
|
|
# 4. Fall back to active workspace
|
||
|
|
let details = (get-active-workspace-details)
|
||
|
|
if ($details == null) or ($details.path? | default "" | is-empty) {
|
||
|
|
error make {msg: "No active workspace — pass --workspace or activate one first"}
|
||
|
|
}
|
||
|
|
$details.path
|
||
|
|
}
|
||
|
|
|