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

250 lines
10 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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}
}