use platform/user/config.nu [get-active-workspace get-workspace-path] export def "workspace update" [ workspace_name?: string --check (-c) --force (-f) --yes (-y) --verbose (-v) ] { let force_final = ($force or $yes) let ws_name = if ($workspace_name | is-not-empty) { $workspace_name } else { let active = (get-active-workspace) if ($active == null or ($active | is-empty)) { print $"(ansi red)✗(ansi reset) No active workspace" print $"(ansi yellow)Specify workspace name or activate a workspace first(ansi reset)" exit 1 } $active } let workspace_path = (get-workspace-path $ws_name) if ($workspace_path == null or not ($workspace_path | path exists)) { print $"(ansi red)✗(ansi reset) Workspace not found: ($ws_name)" exit 1 } let parent1 = ($workspace_path | path dirname) let parent2 = ($parent1 | path dirname) let prov_root = if (($parent1 | path join "provisioning" | path exists)) { $parent1 } else if (($parent2 | path join "provisioning" | path exists)) { $parent2 } else { "" } if ($prov_root | is-empty) { print $"(ansi red)✗(ansi reset) Cannot find provisioning root" print " Expected: /provisioning" print $" Workspace: ($workspace_path)" exit 1 } print $"(ansi cyan)🔄 Updating workspace...(ansi reset)" print $" Workspace: (ansi green)($ws_name)(ansi reset)" print $" Path: ($workspace_path)" print "" let updates = [ {name: ".providers", source: ($prov_root | path join "provisioning/catalog/providers"), target: ($workspace_path | path join ".providers")} {name: ".clusters", source: ($prov_root | path join "provisioning/catalog/clusters"), target: ($workspace_path | path join ".clusters")} {name: ".taskservs", source: ($prov_root | path join "provisioning/catalog/taskservs"), target: ($workspace_path | path join ".taskservs")} {name: ".nickel", source: ($prov_root | path join "provisioning/nickel"), target: ($workspace_path | path join ".nickel")} ] print $"(ansi green_bold)Directories to update:(ansi reset)" print "" for update in $updates { let src_exists = ($update.source | path exists) let status = if $src_exists { $"(ansi green)✓(ansi reset)" } else { $"(ansi yellow)⊘(ansi reset)" } print $" ($status) ($update.name)" if $verbose { print $" Source: ($update.source)" print $" Target: ($update.target)" } } print "" if $check { print $"(ansi cyan)[CHECK MODE](ansi reset) No changes will be made" return } if not $force_final { print $"(ansi yellow)⚠ This will overwrite existing directories(ansi reset)" print "" print "To proceed, use: provisioning ws update --yes" return } print "" print $"(ansi cyan)Updating...(ansi reset)" print "" for update in $updates { let src_exists = ($update.source | path exists) if not $src_exists { print $" (ansi yellow)⊘(ansi reset) Skipped: ($update.name) \(source-not-found\)" continue } if ($update.target | path exists) { rm -rf $update.target } cp -r $update.source $update.target print $" (ansi green)✓(ansi reset) Updated: ($update.name)" if ($update.name == ".providers") { _fix-provider-nickel-paths $update.target $verbose } } print "" print $"(ansi green)✓(ansi reset) Workspace update complete" } def _fix-provider-nickel-paths [providers_path: string, verbose: bool] { let nickel_mods = (glob $"($providers_path)/**/nickel.mod") if ($nickel_mods | is-empty) { return } for mod_file in $nickel_mods { if not ($mod_file | path exists) { continue } let content = (open $mod_file) let updated = ( $content | str replace --all '{ path = "../../../../nickel' '{ path = "../../../.nickel/packages/provisioning' | str replace --all '{ path = "../../../../.nickel' '{ path = "../../../.nickel/packages/provisioning' ) if ($content != $updated) { $updated | save -f $mod_file if $verbose { print $" Fixed Nickel path in: ($mod_file)" } } } } export def "workspace check-updates" [ workspace_name?: string --verbose (-v) ] { let ws_name = if ($workspace_name | is-not-empty) { $workspace_name } else { let active = (get-active-workspace) if ($active == null or ($active | is-empty)) { print $"(ansi red)✗(ansi reset) No active workspace" exit 1 } $active } let workspace_path = (get-workspace-path $ws_name) if ($workspace_path == null or not ($workspace_path | path exists)) { print $"(ansi red)✗(ansi reset) Workspace not found: ($ws_name)" exit 1 } print $"(ansi cyan)📋 Checking workspace updates...(ansi reset)" print $" Workspace: (ansi green)($ws_name)(ansi reset)" print $" Path: ($workspace_path)" print "" let checks = [ {name: ".providers", path: ($workspace_path | path join ".providers")} {name: ".clusters", path: ($workspace_path | path join ".clusters")} {name: ".taskservs", path: ($workspace_path | path join ".taskservs")} {name: ".nickel", path: ($workspace_path | path join ".nickel")} {name: "config", path: ($workspace_path | path join "config")} ] let status_list = ($checks | each {|check| let exists = ($check.path | path exists) if $exists { print $" (ansi green)✓(ansi reset) ($check.name) - present" } else { print $" (ansi yellow)⊘(ansi reset) ($check.name) - missing" } if $verbose { print $" Path: ($check.path)" } {name: $check.name, exists: $exists} }) let missing_count = ($status_list | where {|s| $s.exists == false} | length) print "" if $missing_count == 0 { print $"(ansi green)✓(ansi reset) All directories are present and up-to-date" } else { let label = if $missing_count == 1 { "directory needs" } else { "directories need" } print $"(ansi yellow)⚠(ansi reset) ($missing_count) ($label) updating" print "" print $"(ansi cyan)Update with:(ansi reset) provisioning workspace update" } } export def "workspace sync-modules" [ workspace_name?: string --check (-c) --force (-f) --verbose (-v) ] { let ws_name = if ($workspace_name | is-not-empty) { $workspace_name } else { let active = (get-active-workspace) if ($active == null or ($active | is-empty)) { print $"(ansi red)✗(ansi reset) No active workspace" exit 1 } $active } let workspace_path = (get-workspace-path $ws_name) if ($workspace_path == null or not ($workspace_path | path exists)) { print $"(ansi red)✗(ansi reset) Workspace not found: ($ws_name)" exit 1 } let config_path = ($workspace_path | path join "config") if not ($config_path | path exists) { print $"(ansi red)✗(ansi reset) Workspace config not found" exit 1 } print $"(ansi cyan)🔄 Syncing workspace modules...(ansi reset)" print $" Workspace: (ansi green)($ws_name)(ansi reset)" print $" Path: ($workspace_path)" print "" if (($config_path | path join "providers") | path exists) { print "Configured Providers:" ls ($config_path | path join "providers") | where {|f| ($f.type == "file") and ($f.name | str ends-with ".toml")} | each {|f| print $" - ($f.name)"} | ignore } if (($config_path | path join "clusters") | path exists) { print "" print "Configured Clusters:" ls ($config_path | path join "clusters") | where {|f| ($f.type == "file") and ($f.name | str ends-with ".toml")} | each {|f| print $" - ($f.name)"} | ignore } print "" print $"(ansi green)✓(ansi reset) Module sync complete" }