108 lines
4.8 KiB
Text
108 lines
4.8 KiB
Text
# Shell Command Handlers
|
|
# Domain: Nushell environment, shell info, and resource listing
|
|
|
|
# REMOVED: use ../../../lib_provisioning * - causes circular import
|
|
use cli/flags.nu *
|
|
|
|
# Validate infrastructure name is safe from path injection
|
|
def validate_infra_name [infra: string] {
|
|
# Returns true if INVALID (contains dangerous patterns)
|
|
if ($infra | str contains "/") or ($infra | str contains "..") or ($infra | str starts-with "/") or ($infra | str contains " ") {
|
|
return true
|
|
}
|
|
false
|
|
}
|
|
|
|
# Nu shell command handler - Start Nushell with provisioning library loaded
|
|
export def handle_nu [ops: string, flags: record] {
|
|
let run_ops = if ($ops | str trim | str starts-with "-") {
|
|
""
|
|
} else {
|
|
let parts = ($ops | split row " ")
|
|
if ($parts | is-empty) { "" } else { $parts | first }
|
|
}
|
|
|
|
if ($flags.infra | is-not-empty) {
|
|
# Validate infra name to prevent path injection
|
|
if (validate_infra_name $flags.infra) {
|
|
error make { msg: "Invalid infrastructure name - contains path traversal characters" }
|
|
}
|
|
if ($env.PROVISIONING_INFRA_PATH | path join $flags.infra | path exists) {
|
|
cd ($env.PROVISIONING_INFRA_PATH | path join $flags.infra)
|
|
}
|
|
}
|
|
|
|
if ($flags.output_format | is-empty) {
|
|
if ($run_ops | is-empty) {
|
|
print (
|
|
$"\nTo exit (_ansi purple_bold)NuShell(_ansi reset) session, with (_ansi default_dimmed)lib_provisioning(_ansi reset) loaded, " +
|
|
$"use (_ansi green_bold)exit(_ansi reset) or (_ansi green_bold)[CTRL-D](_ansi reset)"
|
|
)
|
|
# Pass the provisioning configuration files to the Nu subprocess
|
|
# This ensures the interactive session has the same config loaded as the calling environment
|
|
let config_path = ($env.PROVISIONING_CONFIG? | default "")
|
|
# Build library paths argument - needed for module resolution during parsing
|
|
# Convert colon-separated string to -I flag arguments
|
|
let lib_dirs = ($env.NU_LIB_DIRS? | default "")
|
|
let lib_paths = if ($lib_dirs | is-not-empty) {
|
|
($lib_dirs | split row ":" | where { |x| ($x | is-not-empty) })
|
|
} else {
|
|
[]
|
|
}
|
|
|
|
if ($config_path | is-not-empty) {
|
|
# Pass config files AND library paths via -I flags for module resolution
|
|
# Library paths are set via -I flags which enables module resolution during parsing phase
|
|
if ($lib_paths | length) > 0 {
|
|
# Construct command with -I flags for each library path
|
|
let cmd = (mut cmd_parts = []; for path in $lib_paths { $cmd_parts = ($cmd_parts | append "-I" | append $path) }; $cmd_parts)
|
|
# Start interactive Nushell with provisioning configuration loaded
|
|
# The -i flag enables interactive mode (REPL) with full terminal features
|
|
^nu --config $"($config_path)/config.nu" --env-config $"($config_path)/env.nu" ...$cmd -i
|
|
} else {
|
|
^nu --config $"($config_path)/config.nu" --env-config $"($config_path)/env.nu" -i
|
|
}
|
|
} else {
|
|
# Fallback if PROVISIONING_CONFIG not set
|
|
if ($lib_paths | length) > 0 {
|
|
let cmd = (mut cmd_parts = []; for path in $lib_paths { $cmd_parts = ($cmd_parts | append "-I" | append $path) }; $cmd_parts)
|
|
^nu ...$cmd -i
|
|
} else {
|
|
^nu -i
|
|
}
|
|
}
|
|
} else {
|
|
# Also pass library paths for single command execution
|
|
let lib_dirs = ($env.NU_LIB_DIRS? | default "")
|
|
let lib_paths = if ($lib_dirs | is-not-empty) {
|
|
($lib_dirs | split row ":" | where { |x| ($x | is-not-empty) })
|
|
} else {
|
|
[]
|
|
}
|
|
|
|
if ($lib_paths | length) > 0 {
|
|
let cmd = (mut cmd_parts = []; for path in $lib_paths { $cmd_parts = ($cmd_parts | append "-I" | append $path) }; $cmd_parts)
|
|
^nu ...$cmd -c $"($run_ops)"
|
|
} else {
|
|
^nu -c $"($run_ops)"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Nu info command handler - Show Nushell version info
|
|
export def handle_nuinfo [] {
|
|
print $"\n (_ansi yellow)Nu shell info(_ansi reset)"
|
|
print (version)
|
|
}
|
|
|
|
# List command handler - List resources (servers, taskservs, clusters)
|
|
export def handle_list [ops: string, flags: record] {
|
|
let target_list = if ($ops | is-not-empty) {
|
|
let parts = ($ops | split row " ")
|
|
if ($parts | is-empty) { "" } else { $parts | first }
|
|
} else { "" }
|
|
|
|
let list_ops = ($ops | str replace $"($target_list) " "" | str trim)
|
|
on_list $target_list ($flags.onsel | default "") $list_ops
|
|
}
|