301 lines
9.1 KiB
Plaintext
Raw Normal View History

2025-10-07 10:32:04 +01:00
#!/usr/bin/env nu
# Layered Module Resolver
# Provides unified resolution across 3 layers: System → Workspace → Infrastructure
use ../../taskservs/discover.nu *
use ../../providers/discover.nu *
use ../../clusters/discover.nu *
# 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
]: nothing -> record {
# 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]: nothing -> record {
match $type {
"taskserv" => {
try {
let info = (get-taskserv-info $name)
{
path: $info.kcl_path
layer: "system"
layer_number: 1
name: $name
type: "taskserv"
found: true
metadata: $info
}
} catch {
{found: false}
}
}
"provider" => {
try {
let info = (get-provider-info $name)
{
path: $info.kcl_path
layer: "system"
layer_number: 1
name: $name
type: "provider"
found: true
metadata: $info
}
} catch {
{found: false}
}
}
"cluster" => {
try {
let info = (get-cluster-info $name)
{
path: $info.kcl_path
layer: "system"
layer_number: 1
name: $name
type: "cluster"
found: true
metadata: $info
}
} catch {
{found: false}
}
}
_ => {
{found: false}
}
}
}
# List all available modules across layers
export def list-modules-by-layer [
module_type: string
--workspace: string = ""
--infra: string = ""
]: nothing -> table {
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 = ""
]: nothing -> table {
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
]: nothing -> record {
# 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]: nothing -> nothing {
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"
}
}