Update core components including CLI, Nushell libraries, plugins system, and utility scripts for the provisioning system. CLI Updates: - Command implementations - CLI utilities and dispatching - Help system improvements - Command validation Library Updates: - Configuration management system - Infrastructure validation - Extension system improvements - Secrets management - Workspace operations - Cache management system Plugin System: - Interactive form plugin (inquire) - KCL integration plugin - Performance optimization plugins - Plugin registration system Utilities: - Build and distribution scripts - Installation procedures - Testing utilities - Development tools Documentation: - Library module documentation - Extension API guides - Plugin usage guides - Service management documentation All changes are backward compatible. No breaking changes.
193 lines
5.6 KiB
Plaintext
193 lines
5.6 KiB
Plaintext
#!/usr/bin/env nu
|
|
# [command]
|
|
# name = "metadata handler"
|
|
# group = "infrastructure"
|
|
# tags = ["metadata", "forms", "validation", "interactive"]
|
|
# version = "1.0.0"
|
|
# requires = ["traits.nu", "forminquire.nu"]
|
|
# note = "Command metadata validation and interactive form handling in dispatcher"
|
|
|
|
# ============================================================================
|
|
# Metadata Handler for Dispatcher Integration
|
|
# Version: 1.0.0
|
|
# Purpose: Validate commands and execute interactive forms in dispatcher
|
|
# ============================================================================
|
|
|
|
use ../lib_provisioning/commands/traits.nu *
|
|
use ../../forminquire/nulib/forminquire.nu *
|
|
|
|
# Validate command exists and meets requirements
|
|
def validate-command-execution [
|
|
canonical_name: string
|
|
flags: record = {}
|
|
] : nothing -> record {
|
|
let metadata_result = (get-command-metadata $canonical_name)
|
|
|
|
# If metadata not found, allow command through with default settings
|
|
# Metadata is optional - commands can still work without it
|
|
if not $metadata_result.found {
|
|
return {
|
|
valid: true
|
|
error: ""
|
|
interactive: false
|
|
form_template: ""
|
|
}
|
|
}
|
|
|
|
let req = $metadata_result.metadata.requirements
|
|
|
|
# Check workspace requirement
|
|
if ($req.requires_workspace and (($env.PROVISIONING_WORKSPACE? | is-empty))) {
|
|
if not ($flags.workspace? | is-empty) {
|
|
# Workspace flag provided, will be set by dispatcher
|
|
} else {
|
|
return {
|
|
valid: false
|
|
error: "Active workspace required. Use --workspace <name> or set PROVISIONING_WORKSPACE"
|
|
interactive: false
|
|
form_template: ""
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check confirmation requirement
|
|
if ($req.requires_confirmation and not ($flags.auto_confirm? | default false)) {
|
|
# Forms will handle this
|
|
}
|
|
|
|
# Check auth requirement
|
|
if ($req.requires_auth) {
|
|
# Auth will be validated by auth handler, not here
|
|
}
|
|
|
|
{
|
|
valid: true
|
|
error: ""
|
|
interactive: $req.interactive
|
|
form_template: ($metadata_result.metadata.form_path? // "")
|
|
metadata: $metadata_result.metadata
|
|
}
|
|
}
|
|
|
|
# Handle interactive command execution
|
|
def handle-interactive-command [
|
|
canonical_name: string
|
|
form_template: string
|
|
form_context: record = {}
|
|
] : nothing -> record {
|
|
# Determine which form to run based on command
|
|
# Use specialized functions from their modules for setup and workspace
|
|
let form_result = (
|
|
match $canonical_name {
|
|
"setup" => {
|
|
use ../lib_provisioning/setup/wizard.nu *
|
|
# For setup, we return a special handling marker
|
|
# The dispatcher will handle calling the right function
|
|
{
|
|
success: true
|
|
error: ""
|
|
values: {}
|
|
_setup_command: true
|
|
}
|
|
}
|
|
"workspace init" => {
|
|
# For workspace init, same approach
|
|
{
|
|
success: true
|
|
error: ""
|
|
values: {}
|
|
_workspace_init_command: true
|
|
}
|
|
}
|
|
"auth login" => { run-form $form_template }
|
|
"server delete" => { run-form $form_template }
|
|
_ => {
|
|
if not (($form_template | is-empty)) {
|
|
run-form $form_template
|
|
} else {
|
|
{
|
|
success: false
|
|
error: "No form template defined for interactive command"
|
|
values: {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
|
|
if not $form_result.success {
|
|
return {
|
|
proceed: false
|
|
error: $form_result.error
|
|
form_values: {}
|
|
}
|
|
}
|
|
|
|
# Inject form results into environment for command to use
|
|
$env.FORM_RESULTS = ($form_result.values | to json)
|
|
|
|
{
|
|
proceed: true
|
|
error: ""
|
|
form_values: $form_result.values
|
|
}
|
|
}
|
|
|
|
# Print validation errors
|
|
def show-validation-error [error_msg: string] : nothing -> nothing {
|
|
print $"(ansi red_bold)✗ Command validation failed(ansi reset)"
|
|
print $" (ansi yellow)Error:(ansi reset) ($error_msg)"
|
|
print ""
|
|
}
|
|
|
|
# Validate and prepare command for execution
|
|
def prepare-command-execution [
|
|
canonical_name: string
|
|
flags: record = {}
|
|
] : nothing -> record {
|
|
# Validate command
|
|
let validation = (validate-command-execution $canonical_name $flags)
|
|
|
|
if not $validation.valid {
|
|
show-validation-error $validation.error
|
|
return {
|
|
proceed: false
|
|
error: $validation.error
|
|
form_values: {}
|
|
}
|
|
}
|
|
|
|
# Handle interactive commands
|
|
if $validation.interactive {
|
|
handle-interactive-command $canonical_name $validation.form_template {}
|
|
} else {
|
|
{
|
|
proceed: true
|
|
error: ""
|
|
form_values: {}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Check if command should skip if --yes flag provided
|
|
def should-skip-interactive [flags: record] : nothing -> bool {
|
|
$flags.auto_confirm? | default false
|
|
}
|
|
|
|
# Main exported function for dispatcher integration
|
|
export def validate-and-prepare [
|
|
command_str: string
|
|
flags: record = {}
|
|
] : nothing -> record {
|
|
# If --yes flag provided, skip interactive forms
|
|
if (should-skip-interactive $flags) {
|
|
return {
|
|
proceed: true
|
|
error: ""
|
|
form_values: {}
|
|
}
|
|
}
|
|
|
|
prepare-command-execution $command_str $flags
|
|
}
|