# Environment Management Commands # CLI commands for managing provisioning environments use ../config/accessor.nu * use ../config/loader.nu * use ../utils/ui.nu * use std log # List all available environments export def "env list" [ --config: record # Optional pre-loaded config ] { print "Available environments:" let environments = (list-available-environments --config $config) let current_env = (get-current-environment --config $config) for env in $environments { if $env == $current_env { print $" ✓ ($env) (current)" } else { print $" ($env)" } } print "" print $"Current environment: ($current_env)" } # Show current environment information export def "env current" [ --config: record # Optional pre-loaded config ] { let current_env = (get-current-environment --config $config) let config_data = if ($config | is-empty) { get-config --environment $current_env } else { $config } print $"Current environment: ($current_env)" print "" # Show environment-specific configuration let env_config = (config-get $"environments.($current_env)" {} --config $config_data) if ($env_config | is-not-empty) { print "Environment-specific configuration:" $env_config | to yaml | print } else { print "No environment-specific configuration found" } } # Switch to a different environment export def "env switch" [ environment: string # Environment to switch to --validate = true # Validate environment before switching ] { switch-environment $environment --validate=$validate } # Validate environment configuration export def "env validate" [ environment?: string # Environment to validate (default: current) --strict = false # Use strict validation ] { let target_env = if ($environment | is-not-empty) { $environment } else { get-current-environment } print $"Validating environment: ($target_env)" validate-current-config --environment=$target_env --strict=$strict } # Compare configurations between environments export def "env compare" [ env1: string # First environment env2: string # Second environment --section: string # Specific section to compare ] { compare-environments $env1 $env2 --section=$section } # Show environment configuration export def "env show" [ environment?: string # Environment to show (default: current) --section: string # Show only specific section --format: string = "yaml" # Output format (yaml, json, table) ] { let target_env = if ($environment | is-not-empty) { $environment } else { get-current-environment } print $"Environment: ($target_env)" print "" show-config --environment=$target_env --section=$section --format=$format } # Initialize environment-specific configuration export def "env init" [ environment: string # Environment to initialize --template: string # Template to use (dev, test, prod) --force = false # Overwrite existing config ] { init-environment-config $environment --template=$template --force=$force } # Detect current environment automatically export def "env detect" [] { let detected_env = (detect-current-environment) print $"Detected environment: ($detected_env)" # Show detection details print "" print "Detection criteria:" # Check environment variables if ($env.PROVISIONING_ENV? | is-not-empty) { print $" - PROVISIONING_ENV: ($env.PROVISIONING_ENV)" } if ($env.CI? | is-not-empty) { print " - CI environment detected" } if ($env.NODE_ENV? | is-not-empty) { print $" - NODE_ENV: ($env.NODE_ENV)" } if ($env.ENVIRONMENT? | is-not-empty) { print $" - ENVIRONMENT: ($env.ENVIRONMENT)" } # Check directory indicators if ($env.PWD | path join ".git" | path exists) { print " - Git repository detected (dev indicator)" } $detected_env } # Set environment variable and update configuration export def "env set" [ environment: string # Environment to set --persist = false # Persist to shell profile ] { # Validate environment first let config_data = (get-config) let validation = (validate-environment $environment $config_data) if not $validation.valid { error make { msg: $validation.message } } # Set environment variable $env.PROVISIONING_ENV = $environment print $"Set PROVISIONING_ENV=($environment)" if $persist { # Add to shell profile (simplified approach) let shell_config = match ($env.SHELL? | default "") { "/bin/bash" | "/usr/bin/bash" => "~/.bashrc" "/bin/zsh" | "/usr/bin/zsh" => "~/.zshrc" _ => "~/.profile" } print $"To persist this setting, add to your ($shell_config):" print $"export PROVISIONING_ENV=($environment)" } } # Get environment-specific paths export def "env paths" [ environment?: string # Environment to get paths for ] { let target_env = if ($environment | is-not-empty) { $environment } else { get-current-environment } print $"Paths for environment: ($target_env)" let paths = (get-environment-paths --environment=$target_env) $paths | to yaml | print } # Create a new environment configuration template export def "env create" [ environment: string # Environment name --template: string = "dev" # Base template to copy from --description: string # Description for the environment ] { # Create environment-specific config file let config_path = ($env.PWD | path join $"config.($environment).toml") if ($config_path | path exists) { let response = (input $"Environment config ($config_path) already exists. Overwrite? [y/N]: ") if ($response | str downcase) != "y" { print "Cancelled." return } } # Load base template let template_path = match $template { "dev" => "config.dev.toml.example" "test" => "config.test.toml.example" "prod" => "config.prod.toml.example" _ => "config.user.toml.example" } let base_path = (get-base-path) let source_template = ($base_path | path join $template_path) if not ($source_template | path exists) { error make { msg: $"Template file not found: ($source_template)" } } # Copy and customize template cp $source_template $config_path # Update the config with environment-specific details let config_content = (open $config_path) let updated_content = ($config_content | str replace --all "TEMPLATE_NAME" $environment) $updated_content | save $config_path print $"Created environment configuration: ($config_path)" if ($description | is-not-empty) { print $"Description: ($description)" } print "" print "Next steps:" print $"1. Edit the configuration: ($config_path)" print $"2. Validate: ./core/nulib/provisioning env validate ($environment)" print $"3. Switch to environment: ./core/nulib/provisioning env switch ($environment)" } # Delete environment configuration export def "env delete" [ environment: string # Environment to delete --force = false # Skip confirmation ] { # Prevent deletion of system environments let protected_envs = ["dev" "test" "prod"] if ($environment in $protected_envs) { error make { msg: $"Cannot delete protected environment: ($environment)" } } if not $force { let response = (input $"Delete environment '($environment)'? This cannot be undone. [y/N]: ") if ($response | str downcase) != "y" { print "Cancelled." return } } # Remove environment-specific config files let config_files = [ ($env.PWD | path join $"config.($environment).toml") ($env.HOME | path join ".config" | path join "provisioning" | path join $"config.($environment).toml") ] mut deleted_files = [] for file in $config_files { if ($file | path exists) { rm $file $deleted_files = ($deleted_files | append $file) } } if ($deleted_files | length) > 0 { print $"Deleted environment configuration files:" for file in $deleted_files { print $" - ($file)" } } else { print $"No configuration files found for environment: ($environment)" } } # Export environment configuration export def "env export" [ environment?: string # Environment to export (default: current) --output: string # Output file path --format: string = "toml" # Export format (toml, yaml, json) ] { let target_env = if ($environment | is-not-empty) { $environment } else { get-current-environment } let config_data = (get-config --environment=$target_env) let output_path = if ($output | is-not-empty) { $output } else { $"exported-config-($target_env).($format)" } match $format { "yaml" => { $config_data | to yaml | save $output_path } "json" => { $config_data | to json --indent 2 | save $output_path } "toml" => { $config_data | to toml | save $output_path } _ => { error make { msg: $"Unsupported format: ($format). Use toml, yaml, or json." } } } print $"Exported ($target_env) environment configuration to: ($output_path)" } # Environment status and health check export def "env status" [ environment?: string # Environment to check (default: current) --detailed = false # Show detailed status ] { let target_env = if ($environment | is-not-empty) { $environment } else { get-current-environment } print $"Environment Status: ($target_env)" print "" # Validate configuration let validation = (validate-current-config --environment=$target_env) if $validation.valid { print "✅ Configuration: Valid" } else { print "❌ Configuration: Invalid" if $detailed { for error in $validation.errors { print $" Error: ($error.message)" } } } # Check environment-specific settings let config_data = (get-config --environment=$target_env) # Check paths let base_path = (config-get "paths.base" "" --config $config_data) if ($base_path | path exists) { print "✅ Base path: Accessible" } else { print "❌ Base path: Not found" } # Check SOPS configuration let use_sops = (config-get "sops.use_sops" false --config $config_data) if $use_sops { let sops_key = (find-sops-key --config $config_data) if ($sops_key | is-not-empty) { print "✅ SOPS: Key found" } else { print "⚠️ SOPS: No key found" } } else { print "ℹ️ SOPS: Disabled" } # Check provider configuration let default_provider = (config-get "providers.default" "" --config $config_data) if ($default_provider | is-not-empty) { print $"✅ Provider: ($default_provider)" } else { print "❌ Provider: Not configured" } if $detailed { print "" print "Environment Configuration:" let env_config = (config-get $"environments.($target_env)" {} --config $config_data) if ($env_config | is-not-empty) { $env_config | to yaml | print } else { print "No environment-specific configuration" } } }