#!/usr/bin/env nu # Common Library for Nushell Plugins Distribution Scripts # Provides shared utilities, logging, and validation functions # Logging functions with consistent formatting export def log_info [message: string] { print $"(ansi blue)ℹ️ ($message)(ansi reset)" } export def log_success [message: string] { print $"(ansi green)✅ ($message)(ansi reset)" } export def log_warn [message: string] { print $"(ansi yellow)⚠️ ($message)(ansi reset)" } export def log_error [message: string] { print $"(ansi red)❌ ($message)(ansi reset)" } export def log_debug [message: string] { if ($env.DEBUG? | default false) { print $"(ansi dim)🐛 DEBUG: ($message)(ansi reset)" } } # Validate nushell version consistency between system and workspace export def validate_nushell_version [] { log_debug "Validating nushell version consistency..." # Check if nushell submodule exists let nushell_dir = "./nushell" if not ($nushell_dir | path exists) { log_error $"Nushell submodule not found at ($nushell_dir)" exit 1 } # Get system nu version let system_version = try { (nu --version | str replace "nushell " "" | str replace " .*" "") } catch { log_error "Could not determine system nushell version" exit 1 } # Get workspace nu version from Cargo.toml let cargo_toml_path = $"($nushell_dir)/Cargo.toml" let workspace_version = try { (open $cargo_toml_path | get package.version) } catch { log_error $"Could not read package version from ($cargo_toml_path)" exit 1 } if $system_version != $workspace_version { log_error $"Version mismatch: system nu ($system_version) != workspace nu ($workspace_version)" log_info "Run 'just fix-nushell' to resolve version inconsistencies" exit 1 } log_success $"Nushell version validation passed: ($system_version)" } # Get current platform identifier export def get_current_platform [] { let os = (sys host | get name) let arch = (run-external "uname" "-m" | str trim) let platform_name = match $os { "Linux" => "linux", "Darwin" => "darwin", "Windows" => "windows", _ => ($os | str downcase) } let arch_name = match $arch { "x86_64" => "x86_64", "aarch64" => "arm64", "arm64" => "arm64", _ => $arch } $"($platform_name)-($arch_name)" } # Get all supported platforms export def get_supported_platforms [] { [ "linux-x86_64", "linux-arm64", "darwin-x86_64", "darwin-arm64", "windows-x86_64" ] } # Get binary extension for platform export def get_binary_extension [platform: string] { if ($platform | str starts-with "windows") { ".exe" } else { "" } } # Get archive extension for platform export def get_archive_extension [platform: string] { if ($platform | str starts-with "windows") { ".zip" } else { ".tar.gz" } } # Ensure directory exists export def ensure_dir [path: string] { if not ($path | path exists) { mkdir $path log_info $"Created directory: ($path)" } } # Remove directory if it exists export def remove_dir [path: string] { if ($path | path exists) { rm -rf $path log_info $"Removed directory: ($path)" } } # Copy file with logging export def copy_file [src: string, dest: string] { if not ($src | path exists) { log_error $"Source file does not exist: ($src)" return false } let dest_dir = ($dest | path dirname) ensure_dir $dest_dir cp $src $dest log_debug $"Copied ($src) -> ($dest)" true } # Create checksums for files export def create_checksums [files: list, output_dir: string] { let checksum_file = $"($output_dir)/checksums.txt" let checksums = $files | each {|file| if ($file | path exists) { let hash = (open $file --raw | hash sha256) let filename = ($file | path basename) $"($hash) ($filename)" } } | compact $checksums | save -f $checksum_file log_success $"Created checksums file: ($checksum_file)" } # Detect available plugin directories export def get_plugin_directories [] { glob "nu_plugin_*" | where {|it| ($it | path exists) and (($it | path type) == "dir")} } # Get plugin name from directory export def get_plugin_name [dir: string] { $dir | path basename } # Check if path is a plugin directory export def is_plugin_directory [path: string] { ($path | path basename | str starts-with "nu_plugin_") and ($path | path type) == "dir" } # Get version from current workspace export def get_workspace_version [] { let version_from_git = try { (git describe --tags --abbrev=0 2>/dev/null | str replace "^v" "") } catch { "" } if ($version_from_git | str length) > 0 { $version_from_git } else { # Fallback to version from nushell Cargo.toml try { (open "./nushell/Cargo.toml" | get package.version) } catch { "0.1.0" } } } # Create manifest for distribution export def create_manifest [ version: string, platform: string, components: record, output_file: string ] { let manifest = { version: $version, platform: $platform, created_at: (date now | format date "%Y-%m-%d %H:%M:%S UTC"), components: $components, nushell_version: (try { (nu --version) } catch { "unknown" }) } $manifest | to json | save -f $output_file log_success $"Created manifest: ($output_file)" } # Parse command line flags into structured data export def parse_flags [args: list] { mut flags = {} mut i = 0 while $i < ($args | length) { let arg = ($args | get $i) if ($arg | str starts-with "--") { let flag_name = ($arg | str replace "--" "") # Check if next arg is a value or another flag let next_i = ($i + 1) if $next_i < ($args | length) { let next_arg = ($args | get $next_i) if not ($next_arg | str starts-with "--") { $flags = ($flags | insert $flag_name $next_arg) $i = ($i + 2) } else { $flags = ($flags | insert $flag_name true) $i = ($i + 1) } } else { $flags = ($flags | insert $flag_name true) $i = ($i + 1) } } else { $i = ($i + 1) } } $flags } # Execute command with error handling export def exec_with_error [command: string] { log_debug $"Executing: ($command)" let result = try { (bash -c $command) } catch {|err| log_error $"Command failed: ($command)" log_error $"Error: ($err.msg)" exit 1 } $result } # Check if binary exists and is executable export def check_binary [path: string] { if not ($path | path exists) { false } else if ($path | path type) != "file" { false } else { # On Unix-like systems, check if executable if (sys host | get name) != "Windows" { try { (ls -l $path | get 0.mode | str contains "x") } catch { false } } else { true } } }