prvng_core/nulib/lib_provisioning/layers/resolver.nu
Jesús Pérez d50fa22d92
refactor(module_loader + layers + diagnostics): selective imports (ADR-025 L2/L3)
Four files, 3 stars each -> selective.

module_loader.nu:
  config/accessor/core.nu [config-get get-config]
  config/cache/simple-cache.nu  DROPPED (dead)
  utils/                        DROPPED (dead)

layers/resolver.nu:
  taskservs/discover.nu [discover-taskservs get-taskserv-info]
  providers/discover.nu [discover-providers get-provider-info]
  clusters/discover.nu  [discover-clusters get-cluster-info]

  Note: these 3 discover.nu files live outside lib_provisioning/ (at
  core/nulib/{taskservs,providers,clusters}/). Absolute paths from
  nulib/ root preserved. Former relative paths (../../) replaced.

diagnostics/system_status.nu:
  config/accessor/core.nu [config-get]
  user/config.nu          [load-user-config]
  plugins/mod.nu          DROPPED (dead)

diagnostics/mod.nu (Layer 3 facade):
  system_status.nu ["provisioning status" "provisioning status-json"]
  health_check.nu  ["provisioning health" "provisioning health-json"]
  next_steps.nu    ["provisioning next" "provisioning phase"]
  All multi-word Nu subcommands, quoted per syntax.

Validation: all 4 nu --ide-check 50 -> 0 errors.

Refs: ADR-025
2026-04-17 09:02:05 +01:00

316 lines
9.6 KiB
Text

#!/usr/bin/env nu
# Layered Module Resolver
# Provides unified resolution across 3 layers: System → Workspace → Infrastructure
# Selective imports (ADR-025 Phase 3 Layer 2).
# discover.nu files live at core/nulib/{taskservs,providers,clusters}/ — outside
# lib_provisioning/. Absolute paths from nulib/ root used.
use taskservs/discover.nu [discover-taskservs get-taskserv-info]
use providers/discover.nu [discover-providers get-provider-info]
use clusters/discover.nu [discover-clusters get-cluster-info]
# Resolve module path with layer information
# Returns: {path: string, layer: string, name: string, type: string, found: bool}
export def resolve-module [
module_name: string
module_type: string # "taskserv", "provider", "cluster"
--workspace: string = "" # Workspace path for Layer 2
--infra: string = "" # Infrastructure path for Layer 3
] {
# Layer 3: Infrastructure-specific (highest priority)
if ($infra | is-not-empty) and ($infra | path exists) {
let infra_path = match $module_type {
"taskserv" => ($infra | path join ".taskservs" $module_name)
"provider" => ($infra | path join ".providers" $module_name)
"cluster" => ($infra | path join ".clusters" $module_name)
_ => ""
}
if ($infra_path | path exists) {
return {
path: $infra_path
layer: "infra"
layer_number: 3
name: $module_name
type: $module_type
found: true
}
}
}
# Layer 2: Workspace-shared (medium priority)
if ($workspace | is-not-empty) and ($workspace | path exists) {
let workspace_path = match $module_type {
"taskserv" => ($workspace | path join ".taskservs" $module_name)
"provider" => ($workspace | path join ".providers" $module_name)
"cluster" => ($workspace | path join ".clusters" $module_name)
_ => ""
}
if ($workspace_path | path exists) {
return {
path: $workspace_path
layer: "workspace"
layer_number: 2
name: $module_name
type: $module_type
found: true
}
}
}
# Layer 1: System extensions (lowest priority)
let system_result = resolve-system-module $module_name $module_type
if $system_result.found {
return $system_result
}
# Not found in any layer
{
path: ""
layer: "none"
layer_number: 0
name: $module_name
type: $module_type
found: false
}
}
# Resolve module from system extensions (Layer 1)
def resolve-system-module [name: string, type: string] {
match $type {
"taskserv" => {
let result = (do {
let info = (get-taskserv-info $name)
{
path: $info.schema_path
layer: "system"
layer_number: 1
name: $name
type: "taskserv"
found: true
metadata: $info
}
} | complete)
if $result.exit_code == 0 {
$result.stdout
} else {
{found: false}
}
}
"provider" => {
let result = (do {
let info = (get-provider-info $name)
{
path: $info.schema_path
layer: "system"
layer_number: 1
name: $name
type: "provider"
found: true
metadata: $info
}
} | complete)
if $result.exit_code == 0 {
$result.stdout
} else {
{found: false}
}
}
"cluster" => {
let result = (do {
let info = (get-cluster-info $name)
{
path: $info.schema_path
layer: "system"
layer_number: 1
name: $name
type: "cluster"
found: true
metadata: $info
}
} | complete)
if $result.exit_code == 0 {
$result.stdout
} else {
{found: false}
}
}
_ => {
{found: false}
}
}
}
# List all available modules across layers
export def list-modules-by-layer [
module_type: string
--workspace: string = ""
--infra: string = ""
] {
mut modules = []
# Layer 1: System
let system_modules = match $module_type {
"taskserv" => (discover-taskservs | each {|m| $m | insert layer "system" | insert layer_number 1})
"provider" => (discover-providers | each {|m| $m | insert layer "system" | insert layer_number 1})
"cluster" => (discover-clusters | each {|m| $m | insert layer "system" | insert layer_number 1})
_ => []
}
$modules = ($modules | append $system_modules)
# Layer 2: Workspace
if ($workspace | is-not-empty) and ($workspace | path exists) {
let ws_dir = match $module_type {
"taskserv" => ($workspace | path join ".taskservs")
"provider" => ($workspace | path join ".providers")
"cluster" => ($workspace | path join ".clusters")
_ => ""
}
if ($ws_dir | path exists) {
let ws_modules = (ls $ws_dir | where type == "dir" | each {|dir|
{
name: ($dir.name | path basename)
type: $module_type
layer: "workspace"
layer_number: 2
path: $dir.name
}
})
$modules = ($modules | append $ws_modules)
}
}
# Layer 3: Infrastructure
if ($infra | is-not-empty) and ($infra | path exists) {
let infra_dir = match $module_type {
"taskserv" => ($infra | path join ".taskservs")
"provider" => ($infra | path join ".providers")
"cluster" => ($infra | path join ".clusters")
_ => ""
}
if ($infra_dir | path exists) {
let infra_modules = (ls $infra_dir | where type == "dir" | each {|dir|
{
name: ($dir.name | path basename)
type: $module_type
layer: "infra"
layer_number: 3
path: $dir.name
}
})
$modules = ($modules | append $infra_modules)
}
}
$modules
}
# Show effective modules (deduplicated by resolution order)
export def show-effective-modules [
module_type: string
--workspace: string = ""
--infra: string = ""
] {
let all_modules = (list-modules-by-layer $module_type --workspace $workspace --infra $infra)
# Group by name and pick highest layer number
$all_modules
| group-by name
| items {|name, versions|
let effective = ($versions | sort-by layer_number | reverse | first)
$effective | insert overrides (($versions | length) - 1)
}
}
# Determine target layer from context
export def determine-layer [
--workspace: string = ""
--infra: string = ""
--level: string = "" # Explicit level: "workspace", "infra", or auto-detect
] {
# Explicit level takes precedence
if ($level | is-not-empty) {
if $level == "workspace" {
return {
layer: "workspace"
layer_number: 2
path: $workspace
}
} else if $level == "infra" {
return {
layer: "infra"
layer_number: 3
path: $infra
}
}
}
# Auto-detect based on current directory
let pwd = $env.PWD
# Check if we're in an infrastructure directory
if ($pwd | str contains "/infra/") {
let infra_path = if ($infra | is-not-empty) {
$infra
} else {
# Try to find infra path from current directory
let parts = ($pwd | path split)
let infra_idx = ($parts | enumerate | where item == "infra" | get index | first)
if ($infra_idx | is-not-empty) {
let infra_parts = ($parts | take ($infra_idx + 2))
$infra_parts | path join
} else {
$pwd
}
}
return {
layer: "infra"
layer_number: 3
path: $infra_path
}
}
# Check if we're in a workspace directory
if ($workspace | is-not-empty) and ($workspace | path exists) {
return {
layer: "workspace"
layer_number: 2
path: $workspace
}
}
# Check if current directory has .taskservs (workspace marker)
if (($pwd | path join ".taskservs") | path exists) and (($pwd | path join "infra") | path exists) {
return {
layer: "workspace"
layer_number: 2
path: $pwd
}
}
# Default to infrastructure level
{
layer: "infra"
layer_number: 3
path: ($infra | default $pwd)
}
}
# Print resolution information for debugging
export def print-resolution [resolution: record] {
if $resolution.found {
print $"✅ Found ($resolution.name) at Layer ($resolution.layer_number) \(($resolution.layer)\)"
print $" Path: ($resolution.path)"
} else {
print $"❌ Module ($resolution.name) not found in any layer"
}
}