provisioning-core/nulib/domain/workspace/enforcement.nu

251 lines
10 KiB
Text
Raw Permalink Normal View History

use std log
use platform/user/config.nu [get-active-workspace get-active-workspace-details]
use domain/workspace/version.nu [check-workspace-compatibility validate-workspace-structure]
export def get-workspace-exempt-commands [] {
[
"help" "version" "workspace" "ws" "guide" "guides" "sc" "shortcuts" "howto"
"nu" "nuinfo" "cache" "status" "health" "diagnostics" "next" "phase"
"setup" "st" "config" "platform" "plat" "providers" "plugin" "plugins"
"taskserv" "task" "server" "cluster" "infra"
"-v" "--version" "-V" "--info" "-I" "--about" "-a" "--helpinfo" "-h"
]
}
export def command-requires-workspace [command: string] {
let exempt_commands = (get-workspace-exempt-commands)
not ($exempt_commands | any {|cmd| $command == $cmd or $command starts-with $cmd})
}
export def enforce-workspace-requirement [command: string, args: list<string>] {
if not (command-requires-workspace $command) {
return {required: false, allowed: true, reason: "command_exempt"}
}
let active_workspace = (get-active-workspace)
if ($active_workspace == null or ($active_workspace | is-empty)) {
return {
required: true, allowed: false, reason: "no_active_workspace"
message: "No active workspace. Please activate or create a workspace first."
}
}
let workspace_details = (get-active-workspace-details)
if ($workspace_details == null or ($workspace_details | is-empty)) {
return {
required: true, allowed: false, reason: "workspace_not_found"
message: $"Active workspace '($active_workspace)' not found in registry"
}
}
let workspace_path = $workspace_details.path
if not ($workspace_path | path exists) {
return {
required: true, allowed: false, reason: "workspace_path_missing"
message: $"Workspace directory not found: ($workspace_path)"
workspace_name: $active_workspace
}
}
let structure_validation = (validate-workspace-structure $workspace_path)
if not $structure_validation.valid {
let error_issues = ($structure_validation.issues | where severity == "error")
return {
required: true, allowed: false, reason: "invalid_workspace_structure"
message: "Workspace structure is invalid"
workspace_name: $active_workspace, workspace_path: $workspace_path, issues: $error_issues
}
}
let compatibility = (check-workspace-compatibility $workspace_path)
if not $compatibility.compatible {
return {
required: true, allowed: false, reason: "version_incompatible"
message: $compatibility.message
workspace_name: $active_workspace, workspace_path: $workspace_path, compatibility: $compatibility
}
}
{
required: true, allowed: true, reason: "workspace_valid"
workspace_name: $active_workspace, workspace_path: $workspace_path, compatibility: $compatibility
}
}
export def display-enforcement-error [enforcement_result: record] {
print ""
print $"(ansi red_bold)✗ Workspace Required(ansi reset)"
print ""
match $enforcement_result.reason {
"no_active_workspace" => {
print $"(ansi yellow)No active workspace is configured.(ansi reset)"
print ""
print $"(ansi cyan)To get started:(ansi reset)"
print ""
print " 1. Create a new workspace:"
print $" (ansi green)provisioning workspace init <name>(ansi reset)"
print ""
print " 2. Or activate an existing workspace:"
print $" (ansi green)provisioning workspace activate <name>(ansi reset)"
print ""
print " 3. List available workspaces:"
print $" (ansi green)provisioning workspace list(ansi reset)"
print ""
}
"workspace_not_found" => {
print $"(ansi yellow)Active workspace not found in registry.(ansi reset)"
print ""
print $"(ansi cyan)To fix this:(ansi reset)"
print ""
print " 1. List available workspaces:"
print $" (ansi green)provisioning workspace list(ansi reset)"
print ""
print " 2. Activate a different workspace:"
print $" (ansi green)provisioning workspace activate <name>(ansi reset)"
print ""
}
"workspace_path_missing" => {
print $"(ansi yellow)Workspace directory not found:(ansi reset)"
print $" ($enforcement_result.workspace_name)"
print ""
print $"(ansi cyan)The workspace may have been moved or deleted.(ansi reset)"
print ""
print " 1. Remove the workspace from registry:"
print $" (ansi green)provisioning workspace remove ($enforcement_result.workspace_name)(ansi reset)"
print ""
print " 2. Create a new workspace:"
print $" (ansi green)provisioning workspace init <name>(ansi reset)"
print ""
}
"invalid_workspace_structure" => {
print $"(ansi yellow)Workspace has invalid structure:(ansi reset)"
print $" Workspace: ($enforcement_result.workspace_name)"
print $" Path: ($enforcement_result.workspace_path)"
print ""
print $"(ansi red)Issues found:(ansi reset)"
for issue in $enforcement_result.issues { print $" • ($issue.message)" }
print ""
print $"(ansi cyan)To fix this:(ansi reset)"
print ""
print " 1. Run workspace migration:"
print $" (ansi green)provisioning workspace migrate ($enforcement_result.workspace_name)(ansi reset)"
print ""
print " 2. Or create a new workspace:"
print $" (ansi green)provisioning workspace init <name>(ansi reset)"
print ""
}
"version_incompatible" => {
print $"(ansi yellow)Workspace version is incompatible:(ansi reset)"
print $" Workspace: ($enforcement_result.workspace_name)"
print $" Path: ($enforcement_result.workspace_path)"
print ""
print $"(ansi red)($enforcement_result.message)(ansi reset)"
print ""
let compat = $enforcement_result.compatibility
if ($compat.reason == "no_metadata") {
print $"(ansi cyan)This workspace needs migration:(ansi reset)"
print ""
print " Run workspace migration:"
print $" (ansi green)provisioning workspace migrate ($enforcement_result.workspace_name)(ansi reset)"
print ""
} else if ($compat.reason == "workspace_too_new") {
print $"(ansi cyan)Workspace is newer than the system:(ansi reset)"
print $" Workspace version: ($compat.workspace_version)"
print $" System version: ($compat.current_system)"
print ""
print " Upgrade the provisioning system to use this workspace."
print ""
} else if ($compat.reason == "migration_available") {
print $"(ansi cyan)Workspace can be migrated:(ansi reset)"
print $" From: ($compat.workspace_version)"
print $" To: ($compat.current_system)"
print ""
print " Run workspace migration:"
print $" (ansi green)provisioning workspace migrate ($enforcement_result.workspace_name)(ansi reset)"
print ""
} else if ($compat.reason == "version_too_old") {
print $"(ansi cyan)System version is too old:(ansi reset)"
print $" Required: ($compat.min_required)"
print $" Current: ($compat.current_system)"
print ""
print " Upgrade the provisioning system to continue."
print ""
}
}
_ => {
print $"(ansi yellow)($enforcement_result.message)(ansi reset)"
print ""
}
}
}
export def check-and-enforce [command: string, args: list<string>] {
let enforcement = (enforce-workspace-requirement $command $args)
if not $enforcement.allowed {
display-enforcement-error $enforcement
return false
}
if $enforcement.required and $enforcement.compatibility.requires_migration? {
if ($enforcement.compatibility.migration_optional? | default false) {
print $"(ansi yellow) Migration available: Workspace can be updated from ($enforcement.compatibility.workspace_version) to ($enforcement.compatibility.current_system)(ansi reset)"
print $" Run: (ansi green)provisioning workspace migrate ($enforcement.workspace_name)(ansi reset)"
print ""
}
}
return true
}
export def get-current-workspace-info [] {
let active_workspace = (get-active-workspace)
if ($active_workspace == null or ($active_workspace | is-empty)) {
return {active: false, name: null, path: null}
}
let workspace_details = (get-active-workspace-details)
if ($workspace_details == null or ($workspace_details | is-empty)) {
return {active: false, name: $active_workspace, path: null}
}
{
active: true
name: $workspace_details.name
path: $workspace_details.path
last_used: $workspace_details.last_used
}
}
export def preflight-check [operation: string] {
let workspace_info = (get-current-workspace-info)
if not $workspace_info.active {
return {passed: false, reason: "no_workspace", message: "No active workspace"}
}
let structure = (validate-workspace-structure $workspace_info.path)
if not $structure.valid {
return {passed: false, reason: "invalid_structure", message: "Workspace structure is invalid", issues: $structure.issues}
}
let compatibility = (check-workspace-compatibility $workspace_info.path)
if not $compatibility.compatible {
return {passed: false, reason: "incompatible_version", message: $compatibility.message, compatibility: $compatibility}
}
{passed: true, workspace: $workspace_info, compatibility: $compatibility}
}