602 lines
21 KiB
Plaintext
Executable File
602 lines
21 KiB
Plaintext
Executable File
#!/usr/bin/env nu
|
|
# Info: Script to run Provisioning Workspace Management
|
|
# Author: JesusPerezLorenzo
|
|
# Release: 1.0.0
|
|
# Date: 29-09-2025
|
|
|
|
use std log
|
|
|
|
use lib_provisioning *
|
|
use env.nu *
|
|
|
|
# - > Help on Workspace
|
|
export def "main help" [
|
|
--src: string = ""
|
|
--notitles # not titles
|
|
--out: string # Print Output format: json, yaml, text (default)
|
|
]: nothing -> nothing {
|
|
if $notitles == null or not $notitles { show_titles }
|
|
^$"($env.PROVISIONING_NAME)" -mod workspace --help
|
|
if ($out | is-not-empty) { $env.PROVISIONING_NO_TERMINAL = false }
|
|
print (provisioning_options $src)
|
|
if not $env.PROVISIONING_DEBUG { end_run "" }
|
|
}
|
|
|
|
# > Workspace Management
|
|
def main [
|
|
...args: string # Other options, use help to get info
|
|
-v # Show version
|
|
-i # Show Info
|
|
--version (-V) # Show version with title
|
|
--info (-I) # Show Info with title
|
|
--about (-a) # Show About
|
|
--infra: string # Infrastructure name
|
|
--template: string = "minimal" # Template type: minimal, full, example
|
|
--workspace-type: string = "development" # Workspace type
|
|
--user-name: string = "" # User name for workspace
|
|
--taskservs: list<string> = [] # Taskservs to load during init
|
|
--providers: list<string> = [] # Providers to load during init
|
|
--clusters: list<string> = [] # Clusters to load during init
|
|
--dep-option: string = "" # Dependency option: home-package, git-package, publish-repo, workspace-home
|
|
--dep-url: string = "" # Dependency URL for git-package or publish-repo
|
|
--overwrite # Overwrite existing workspace
|
|
--check (-c) # Only check mode, no actual changes
|
|
--yes (-y) # Confirm task
|
|
--debug (-x) # Use Debug mode
|
|
--xm # Debug with PROVISIONING_METADATA
|
|
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
|
--metadata # Error with metadata (-xm)
|
|
--notitles # Do not show banner titles
|
|
--helpinfo (-h) # For more details use options "help" (no dashes)
|
|
--out: string # Print Output format: json, yaml, text (default)
|
|
]: nothing -> nothing {
|
|
if ($out | is-not-empty) {
|
|
$env.PROVISIONING_OUT = $out
|
|
$env.PROVISIONING_NO_TERMINAL = true
|
|
}
|
|
provisioning_init $helpinfo "workspace" $args
|
|
if $version or $v { ^$env.PROVISIONING_NAME -v ; exit }
|
|
if $info or $i { ^$env.PROVISIONING_NAME -i ; exit }
|
|
if $about {
|
|
_print (get_about_info)
|
|
exit
|
|
}
|
|
if $debug { $env.PROVISIONING_DEBUG = true }
|
|
if $metadata { $env.PROVISIONING_METADATA = true }
|
|
|
|
let task = if ($args | length) > 0 { ($args | get 0) } else { "" }
|
|
let ops = $"($env.PROVISIONING_ARGS? | default "") " | str replace $" ($task) " "" | str trim
|
|
|
|
# Extract workspace path (first non-flag argument)
|
|
let workspace_path = if ($ops | is-not-empty) and not ($ops | str starts-with "-") {
|
|
let parts = ($ops | split row " ")
|
|
let first_part = ($parts | get 0)
|
|
# Stop at first flag
|
|
if ($first_part | str starts-with "-") {
|
|
"."
|
|
} else {
|
|
$first_part
|
|
}
|
|
} else {
|
|
"."
|
|
}
|
|
|
|
$env.PROVISIONING_MODULE = "workspace"
|
|
|
|
match $task {
|
|
"h" | "help" => {
|
|
# Redirect to main categorized help system
|
|
exec $"($env.PROVISIONING_NAME)" help workspace --notitles
|
|
},
|
|
"init" => {
|
|
if $overwrite and $check {
|
|
workspace_init $workspace_path --infra $infra --template $template --workspace-type $workspace_type --user-name $user_name --taskservs $taskservs --providers $providers --clusters $clusters --dep-option $dep_option --dep-url $dep_url --overwrite --check
|
|
} else if $overwrite {
|
|
workspace_init $workspace_path --infra $infra --template $template --workspace-type $workspace_type --user-name $user_name --taskservs $taskservs --providers $providers --clusters $clusters --dep-option $dep_option --dep-url $dep_url --overwrite
|
|
} else if $check {
|
|
workspace_init $workspace_path --infra $infra --template $template --workspace-type $workspace_type --user-name $user_name --taskservs $taskservs --providers $providers --clusters $clusters --dep-option $dep_option --dep-url $dep_url --check
|
|
} else {
|
|
workspace_init $workspace_path --infra $infra --template $template --workspace-type $workspace_type --user-name $user_name --taskservs $taskservs --providers $providers --clusters $clusters --dep-option $dep_option --dep-url $dep_url
|
|
}
|
|
},
|
|
"create" => {
|
|
print $"📁 Creating workspace: ($workspace_path)"
|
|
if $check {
|
|
workspace_create $workspace_path --infra $infra --template $template --check
|
|
} else {
|
|
workspace_create $workspace_path --infra $infra --template $template
|
|
}
|
|
},
|
|
"migrate" => {
|
|
print $"🔄 Migrating workspace: ($workspace_path)"
|
|
if $check {
|
|
workspace_migrate $workspace_path --check
|
|
} else {
|
|
workspace_migrate $workspace_path
|
|
}
|
|
},
|
|
"validate" => {
|
|
let result = workspace_validate $workspace_path
|
|
if $result.valid {
|
|
print $"✅ Workspace is valid: ($workspace_path)"
|
|
} else {
|
|
print $"❌ Workspace validation failed: ($workspace_path)"
|
|
print $"Missing directories: ($result.missing_directories)"
|
|
print $"Missing files: ($result.missing_files)"
|
|
print $"Recommendations: ($result.recommendations)"
|
|
}
|
|
if ($out | is-not-empty) {
|
|
if $out == "json" {
|
|
print ($result | to json)
|
|
} else if $out == "yaml" {
|
|
print ($result | to yaml)
|
|
} else {
|
|
print ($result | table)
|
|
}
|
|
}
|
|
},
|
|
"info" => {
|
|
let info = workspace_info $workspace_path
|
|
print $"📊 Workspace Information:"
|
|
print $" Path: ($info.workspace)"
|
|
print $" Taskservs: ($info.taskservs_count) - ($info.taskservs | str join ', ')"
|
|
print $" Providers: ($info.providers_count) - ($info.providers | str join ', ')"
|
|
print $" Clusters: ($info.clusters_count) - ($info.clusters | str join ', ')"
|
|
if ($out | is-not-empty) {
|
|
if $out == "json" {
|
|
print ($info | to json)
|
|
} else if $out == "yaml" {
|
|
print ($info | to yaml)
|
|
} else {
|
|
print ($info | table)
|
|
}
|
|
}
|
|
},
|
|
"status" => {
|
|
let status = workspace_status $workspace_path
|
|
print $"📈 Workspace Status:"
|
|
print $" Path: ($status.workspace)"
|
|
print $" Has new structure: ($status.has_new_structure)"
|
|
print $" Is migrated: ($status.is_migrated)"
|
|
print $" Backup files: ($status.backup_files)"
|
|
if ($out | is-not-empty) {
|
|
if $out == "json" {
|
|
print ($status | to json)
|
|
} else if $out == "yaml" {
|
|
print ($status | to yaml)
|
|
} else {
|
|
print ($status | table)
|
|
}
|
|
}
|
|
},
|
|
"list" => {
|
|
workspace_list --out $out
|
|
},
|
|
"rollback" => {
|
|
if not $yes {
|
|
print "⚠️ This will rollback the migration. Use --yes to confirm."
|
|
exit 1
|
|
}
|
|
workspace_rollback $workspace_path
|
|
},
|
|
"dry-run" => {
|
|
workspace_dry_run $workspace_path
|
|
},
|
|
"config" => {
|
|
# Config subcommands
|
|
let config_cmd = if ($ops | is-not-empty) {
|
|
($ops | split row " " | get 0)
|
|
} else {
|
|
"help"
|
|
}
|
|
let config_ops = $ops | str replace $config_cmd "" | str trim
|
|
|
|
match $config_cmd {
|
|
"show" => {
|
|
let format_flag = if ($out | is-not-empty) { $out } else { "yaml" }
|
|
let ws_name = if ($infra | is-not-empty) { $infra } else { "" }
|
|
workspace-config-show $ws_name --format $format_flag
|
|
},
|
|
"validate" => {
|
|
let ws_name = if ($infra | is-not-empty) { $infra } else { "" }
|
|
workspace-config-validate $ws_name
|
|
},
|
|
"generate" => {
|
|
let parts = ($config_ops | split row " ")
|
|
if ($parts | length) < 2 {
|
|
print "Usage: provisioning workspace config generate provider <name>"
|
|
exit 1
|
|
}
|
|
let gen_type = ($parts | get 0)
|
|
let gen_name = ($parts | get 1)
|
|
if $gen_type == "provider" {
|
|
let ws_name = if ($infra | is-not-empty) { $infra } else { "" }
|
|
workspace-config-generate-provider $gen_name $ws_name
|
|
} else {
|
|
print $"Unknown generate type: ($gen_type)"
|
|
exit 1
|
|
}
|
|
},
|
|
"edit" => {
|
|
let parts = ($config_ops | split row " ")
|
|
if ($parts | length) < 1 {
|
|
print "Usage: provisioning workspace config edit <type> [name]"
|
|
print "Types: main, provider, platform, kms"
|
|
exit 1
|
|
}
|
|
let edit_type = ($parts | get 0)
|
|
let edit_name = if ($parts | length) > 1 { ($parts | get 1) } else { "" }
|
|
let ws_name = if ($infra | is-not-empty) { $infra } else { "" }
|
|
workspace-config-edit $edit_type $edit_name $ws_name
|
|
},
|
|
"hierarchy" => {
|
|
let ws_name = if ($infra | is-not-empty) { $infra } else { "" }
|
|
workspace-config-hierarchy $ws_name
|
|
},
|
|
"list" => {
|
|
let ws_name = if ($infra | is-not-empty) { $infra } else { "" }
|
|
let type_flag = if ($config_ops | is-not-empty) { $config_ops } else { "all" }
|
|
workspace-config-list $ws_name --type $type_flag
|
|
},
|
|
"help" => {
|
|
print "Workspace Configuration Commands:"
|
|
print ""
|
|
print " config show [name] [--format yaml|json|toml]"
|
|
print " Show workspace configuration"
|
|
print ""
|
|
print " config validate [name]"
|
|
print " Validate all workspace configs"
|
|
print ""
|
|
print " config generate provider <name>"
|
|
print " Generate provider config from template"
|
|
print ""
|
|
print " config edit <type> [name]"
|
|
print " Edit configuration file"
|
|
print " Types: main, provider, platform, kms"
|
|
print ""
|
|
print " config hierarchy [name]"
|
|
print " Show configuration loading hierarchy"
|
|
print ""
|
|
print " config list [name] [--type all|provider|platform|kms]"
|
|
print " List configuration files"
|
|
print ""
|
|
print "Use --infra <name> to specify workspace, or uses active workspace"
|
|
},
|
|
_ => {
|
|
print $"Unknown config command: ($config_cmd)"
|
|
print "Use 'provisioning workspace config help' for available commands"
|
|
exit 1
|
|
}
|
|
}
|
|
},
|
|
_ => {
|
|
print $"❌ Unknown task: ($task)"
|
|
print "Use 'provisioning workspace help' for available commands"
|
|
exit 1
|
|
}
|
|
}
|
|
}
|
|
|
|
# Initialize workspace
|
|
def workspace_init [
|
|
path: string
|
|
--infra: string
|
|
--template: string
|
|
--workspace-type: string
|
|
--user-name: string
|
|
--taskservs: list<string>
|
|
--providers: list<string>
|
|
--clusters: list<string>
|
|
--dep-option: string
|
|
--dep-url: string
|
|
--overwrite
|
|
--check
|
|
]: nothing -> nothing {
|
|
# Validate workspace name - no hyphens allowed (causes KCL module resolution issues)
|
|
let workspace_name = ($path | path basename)
|
|
if ($workspace_name | str contains "-") {
|
|
print $"❌ Error: Workspace name cannot contain hyphens: '($workspace_name)'"
|
|
print ""
|
|
print " Hyphens in workspace names cause KCL module resolution issues."
|
|
print $" Use underscores instead: '($workspace_name | str replace -a '-' '_')'"
|
|
print ""
|
|
exit 1
|
|
}
|
|
|
|
# Validate infra name if provided - no hyphens allowed
|
|
if ($infra | is-not-empty) and ($infra | str contains "-") {
|
|
print $"❌ Error: Infrastructure name cannot contain hyphens: '($infra)'"
|
|
print ""
|
|
print " Hyphens in infrastructure names cause KCL module resolution issues."
|
|
print $" Use underscores instead: '($infra | str replace -a '-' '_')'"
|
|
print ""
|
|
exit 1
|
|
}
|
|
|
|
let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning"
|
|
let init_script = ($provisioning_root | path join "tools" "workspace-init.nu")
|
|
|
|
if not ($init_script | path exists) {
|
|
print $"❌ Workspace init script not found: ($init_script)"
|
|
exit 1
|
|
}
|
|
|
|
let infra_flag = if ($infra | is-not-empty) { ["--infra-name" $infra] } else { [] }
|
|
let template_flag = if ($template | is-not-empty) { ["--template" $template] } else { [] }
|
|
let workspace_type_flag = if ($workspace_type | is-not-empty) { ["--workspace-type" $workspace_type] } else { [] }
|
|
let user_flag = if ($user_name | is-not-empty) { ["--user-name" $user_name] } else { [] }
|
|
let dep_option_flag = if ($dep_option | is-not-empty) { ["--dep-option" $dep_option] } else { [] }
|
|
let dep_url_flag = if ($dep_url | is-not-empty) { ["--dep-url" $dep_url] } else { [] }
|
|
let overwrite_flag = if $overwrite { ["--overwrite"] } else { [] }
|
|
let check_flag = if $check { ["--check"] } else { [] }
|
|
|
|
let all_flags = ($infra_flag | append $template_flag | append $workspace_type_flag | append $user_flag | append $dep_option_flag | append $dep_url_flag | append $overwrite_flag | append $check_flag)
|
|
|
|
if ($taskservs | is-empty) and ($providers | is-empty) and ($clusters | is-empty) {
|
|
^nu $init_script $path ...$all_flags
|
|
} else {
|
|
let taskservs_flag = if not ($taskservs | is-empty) { ["--taskservs" $taskservs] } else { [] }
|
|
let providers_flag = if not ($providers | is-empty) { ["--providers" $providers] } else { [] }
|
|
let clusters_flag = if not ($clusters | is-empty) { ["--clusters" $clusters] } else { [] }
|
|
^nu $init_script init $path ...$all_flags ...$taskservs_flag ...$providers_flag ...$clusters_flag
|
|
}
|
|
}
|
|
|
|
# Create workspace structure
|
|
def workspace_create [
|
|
path: string
|
|
--infra: string
|
|
--template: string
|
|
--check
|
|
]: nothing -> nothing {
|
|
if $check {
|
|
workspace_init $path --infra $infra --template $template --check
|
|
} else {
|
|
workspace_init $path --infra $infra --template $template
|
|
}
|
|
}
|
|
|
|
# Migrate workspace
|
|
def workspace_migrate [
|
|
path: string
|
|
--check
|
|
]: nothing -> nothing {
|
|
let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning"
|
|
let migrate_script = ($provisioning_root | path join "tools" "workspace-migrate.nu")
|
|
|
|
if not ($migrate_script | path exists) {
|
|
print $"❌ Workspace migrate script not found: ($migrate_script)"
|
|
exit 1
|
|
}
|
|
|
|
if $check {
|
|
^nu $migrate_script dry-run $path
|
|
} else {
|
|
^nu $migrate_script $path
|
|
}
|
|
}
|
|
|
|
# Validate workspace
|
|
def workspace_validate [path: string]: nothing -> record {
|
|
let workspace_abs = ($path | path expand)
|
|
|
|
let required_dirs = [".taskservs", ".providers", ".clusters", ".manifest"]
|
|
let required_files = ["kcl.mod"]
|
|
|
|
let missing_dirs = $required_dirs | where {|dir|
|
|
not (($workspace_abs | path join $dir) | path exists)
|
|
}
|
|
|
|
let missing_files = $required_files | where {|file|
|
|
not (($workspace_abs | path join $file) | path exists)
|
|
}
|
|
|
|
let is_valid = ($missing_dirs | is-empty) and ($missing_files | is-empty)
|
|
|
|
{
|
|
valid: $is_valid
|
|
workspace: $workspace_abs
|
|
missing_directories: $missing_dirs
|
|
missing_files: $missing_files
|
|
recommendations: (if not $is_valid {
|
|
["Run 'provisioning workspace init <path>' to create or fix workspace structure"]
|
|
} else {
|
|
[]
|
|
})
|
|
}
|
|
}
|
|
|
|
# Show workspace info
|
|
def workspace_info [path: string]: nothing -> record {
|
|
let workspace_abs = ($path | path expand)
|
|
|
|
if not ($workspace_abs | path exists) {
|
|
print $"❌ Workspace does not exist: ($workspace_abs)"
|
|
exit 1
|
|
}
|
|
|
|
let taskservs_manifest_path = ($workspace_abs | path join ".manifest" | path join "taskservs.yaml")
|
|
let taskservs_manifest = if ($taskservs_manifest_path | path exists) {
|
|
open $taskservs_manifest_path
|
|
} else {
|
|
{ loaded_taskservs: [] }
|
|
}
|
|
|
|
let providers_manifest_path = ($workspace_abs | path join ".manifest" | path join "providers.yaml")
|
|
let providers_manifest = if ($providers_manifest_path | path exists) {
|
|
open $providers_manifest_path
|
|
} else {
|
|
{ loaded_providers: [] }
|
|
}
|
|
|
|
let clusters_manifest_path = ($workspace_abs | path join ".manifest" | path join "clusters.yaml")
|
|
let clusters_manifest = if ($clusters_manifest_path | path exists) {
|
|
open $clusters_manifest_path
|
|
} else {
|
|
{ loaded_clusters: [] }
|
|
}
|
|
|
|
{
|
|
workspace: $workspace_abs
|
|
taskservs_count: ($taskservs_manifest.loaded_taskservs? | default [] | length)
|
|
providers_count: ($providers_manifest.loaded_providers? | default [] | length)
|
|
clusters_count: ($clusters_manifest.loaded_clusters? | default [] | length)
|
|
taskservs: ($taskservs_manifest.loaded_taskservs? | default [] | get -o name | default [])
|
|
providers: ($providers_manifest.loaded_providers? | default [] | get -o name | default [])
|
|
clusters: ($clusters_manifest.loaded_clusters? | default [] | get -o name | default [])
|
|
}
|
|
}
|
|
|
|
# Show workspace migration status
|
|
def workspace_status [path: string]: nothing -> record {
|
|
let workspace_abs = ($path | path expand)
|
|
|
|
let has_new_structure = [".taskservs", ".providers", ".clusters", ".manifest"] | all {|dir|
|
|
($workspace_abs | path join $dir) | path exists
|
|
}
|
|
|
|
let migration_info_path = ($workspace_abs | path join ".migration-info.yaml")
|
|
let migration_info = if ($migration_info_path | path exists) {
|
|
open $migration_info_path
|
|
} else {
|
|
null
|
|
}
|
|
|
|
let backup_pattern = ($workspace_abs | path join "**/*.bak")
|
|
let backup_result = (do { glob $backup_pattern | length } | complete)
|
|
let backup_files = if $backup_result.exit_code == 0 {
|
|
$backup_result.stdout
|
|
} else {
|
|
0
|
|
}
|
|
|
|
{
|
|
workspace: $workspace_abs
|
|
has_new_structure: $has_new_structure
|
|
migration_info: $migration_info
|
|
backup_files: $backup_files
|
|
is_migrated: ($has_new_structure and ($migration_info != null))
|
|
}
|
|
}
|
|
|
|
# List available workspaces
|
|
def workspace_list [--out: string]: nothing -> nothing {
|
|
let workspace_root = $env.PWD
|
|
let infra_path = ($workspace_root | path join "infra")
|
|
|
|
# Check if we're in a workspace directory
|
|
if not ($infra_path | path exists) {
|
|
print $"📁 Current directory: ($workspace_root)"
|
|
print "❌ Not in a workspace directory (no 'infra/' subdirectory found)"
|
|
print ""
|
|
print "To use this command:"
|
|
print " 1. Navigate to a workspace directory: cd <workspace-path>"
|
|
print " 2. Or create a new workspace: provisioning ws init <name>"
|
|
print ""
|
|
print "Example:"
|
|
print " provisioning ws init my-workspace"
|
|
print " cd my-workspace"
|
|
print " provisioning ws list"
|
|
return
|
|
}
|
|
|
|
# Get list of infrastructure directories
|
|
let infra_dirs = (ls $infra_path | where type == dir)
|
|
|
|
if ($infra_dirs | is-empty) {
|
|
print $"📁 Workspace: ($workspace_root)"
|
|
print "⚠️ No infrastructure configurations found in infra/"
|
|
print ""
|
|
print "Create an infrastructure:"
|
|
print " provisioning ws init . --infra <name>"
|
|
return
|
|
}
|
|
|
|
# Build infrastructure info
|
|
let infra_info = ($infra_dirs | each {|dir|
|
|
let infra_name = ($dir.name | path basename)
|
|
let infra_full_path = $dir.name
|
|
let has_servers = ($infra_full_path | path join "servers.k") | path exists
|
|
let has_kcl_mod = ($infra_full_path | path join "kcl.mod") | path exists
|
|
|
|
# Count loaded modules
|
|
let taskservs_manifest = ($infra_full_path | path join ".manifest" "taskservs.yaml")
|
|
let providers_manifest = ($infra_full_path | path join ".manifest" "providers.yaml")
|
|
|
|
let taskservs_count = if ($taskservs_manifest | path exists) {
|
|
let manifest = (open $taskservs_manifest)
|
|
($manifest | get -o loaded_taskservs | default [] | length)
|
|
} else { 0 }
|
|
|
|
let providers_count = if ($providers_manifest | path exists) {
|
|
let manifest = (open $providers_manifest)
|
|
($manifest | get -o loaded_providers | default [] | length)
|
|
} else { 0 }
|
|
|
|
{
|
|
name: $infra_name
|
|
path: $infra_full_path
|
|
servers_config: $has_servers
|
|
kcl_mod: $has_kcl_mod
|
|
taskservs: $taskservs_count
|
|
providers: $providers_count
|
|
}
|
|
})
|
|
|
|
# Output based on format
|
|
if ($out | is-not-empty) {
|
|
if $out == "json" {
|
|
print ($infra_info | to json)
|
|
} else if $out == "yaml" {
|
|
print ($infra_info | to yaml)
|
|
} else {
|
|
print ($infra_info | table)
|
|
}
|
|
} else {
|
|
# Pretty output
|
|
print $"📁 Workspace: ($workspace_root)"
|
|
print $"📂 Infrastructure configurations: ($infra_info | length)"
|
|
print ""
|
|
|
|
$infra_info | each {|infra|
|
|
print $" (_ansi green_bold)($infra.name)(_ansi reset)"
|
|
print $" Path: infra/($infra.name)"
|
|
print $" Servers config: ($infra.servers_config)"
|
|
print $" KCL module: ($infra.kcl_mod)"
|
|
print $" Taskservs loaded: ($infra.taskservs)"
|
|
print $" Providers loaded: ($infra.providers)"
|
|
print ""
|
|
}
|
|
|
|
print "Usage:"
|
|
print $" cd infra/<name> # Navigate to infrastructure"
|
|
print $" provisioning ws init . --infra <name> # Add new infrastructure"
|
|
}
|
|
}
|
|
|
|
# Rollback workspace migration
|
|
def workspace_rollback [path: string]: nothing -> nothing {
|
|
let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning"
|
|
let migrate_script = ($provisioning_root | path join "tools" "workspace-migrate.nu")
|
|
|
|
if not ($migrate_script | path exists) {
|
|
print $"❌ Workspace migrate script not found: ($migrate_script)"
|
|
exit 1
|
|
}
|
|
|
|
^nu $migrate_script rollback $path
|
|
}
|
|
|
|
# Dry run migration
|
|
def workspace_dry_run [path: string]: nothing -> nothing {
|
|
let provisioning_root = $env.PROVISIONING? | default "/usr/local/provisioning"
|
|
let migrate_script = ($provisioning_root | path join "tools" "workspace-migrate.nu")
|
|
|
|
if not ($migrate_script | path exists) {
|
|
print $"❌ Workspace migrate script not found: ($migrate_script)"
|
|
exit 1
|
|
}
|
|
|
|
^nu $migrate_script dry-run $path
|
|
}
|