#!/usr/bin/env nu # Pack Distribution Script # Creates distribution archives for built plugins # Load environment variables from env file def load_env_vars [] { let env_file = "env" if ($env_file | path exists) { let content = open $env_file | lines | where ($it | str trim | str length) > 0 | where not ($it | str starts-with "#") | each {|line| if ($line | str contains "=") { let parts = $line | split column "=" key value let key = $parts | get 0 | str replace "export " "" | str trim let value = $parts | get 1 | str trim {$key: $value} } else { {} } } | reduce -f {} {|item, acc| $acc | merge $item} $content } else { { APP_NAME: "nushell-plugins", TARGET_PATH: "distribution", INSTALL_FILE: "install_nu_plugins.nu", INSTALL_BIN_PATH: "/usr/local/bin", ARCHIVE_DIR_PATH: "/tmp", BIN_ARCHIVES_DIR_PATH: "bin_archives" } } } # Get system architecture info def get_system_info [] { let arch = match (uname -m) { "x86_64" => "amd64", "aarch64" => "arm64", $arch if ($arch | str starts-with "arm") => "arm64", $other => $other } let platform = match (uname -s | str downcase) { $os if ($os | str contains "linux") => "linux", $os if ($os | str contains "darwin") => "darwin", $os if ($os | str contains "windows") => "windows", $other => $other } {platform: $platform, arch: $arch} } # Check if target directory has required files def validate_target [target_path: string] { let required_files = ["LICENSE", "README"] let optional_files = ["env"] let plugin_files = (ls $target_path | where name =~ "nu_plugin_" and type == "file" | get name) mut issues = [] if ($plugin_files | length) == 0 { $issues = ($issues | append "No plugin binaries found") } for file in $required_files { if not ($"($target_path)/($file)" | path exists) { $issues = ($issues | append $"Required file missing: ($file)") } } {valid: (($issues | length) == 0), issues: $issues, plugin_count: ($plugin_files | length)} } # Create archive def create_archive [target_path: string, archive_path: string, env_vars: record] { # Copy env file to target temporarily if ("env" | path exists) { cp env $"($target_path)/env" } let files_to_archive = [ $"($target_path)/nu_plugin_*", $"($target_path)/($env_vars.INSTALL_FILE)", $"($target_path)/LICENSE", $"($target_path)/README", $"($target_path)/env" ] # Filter files that actually exist let existing_files = $files_to_archive | where ($it | path exists) if ($existing_files | length) == 0 { error make {msg: "No files found to archive"} } print $"šŸ“¦ Creating archive with ($existing_files | length) files..." try { # Use tar to create the archive tar czf $archive_path ...$existing_files # Clean up temporary env file if ($"($target_path)/env" | path exists) { rm $"($target_path)/env" } let archive_size = ls $archive_path | get 0.size print $"āœ… Archive created: ($archive_path) (($archive_size))" true } catch {|err| # Clean up on failure if ($"($target_path)/env" | path exists) { rm $"($target_path)/env" } error make {msg: $"Failed to create archive: ($err.msg)"} } } # Main function def main [ --target (-t): string = "" # Override target path --output (-o): string = "" # Override output archive path --archive-dir (-a): string = "" # Override archive directory --force (-f) # Force overwrite existing archive --list (-l) # List what would be archived ] { # Ensure we're in the repository root directory if not ("nu_plugin_clipboard" | path exists) { error make {msg: "Please run this script from the nushell-plugins repository root directory"} } print "šŸ“¦ Nushell Plugin Distribution Packager" # Load environment variables let env_vars = load_env_vars print $"šŸ“‹ Loaded configuration:" for var in ($env_vars | transpose key value) { print $" ($var.key): ($var.value)" } # Determine paths let target_path = if ($target | str length) > 0 { $target } else { $env_vars.TARGET_PATH } let archive_dir = if ($archive_dir | str length) > 0 { $archive_dir } else { $env_vars.BIN_ARCHIVES_DIR_PATH? | default "." } # Validate target directory if not ($target_path | path exists) { print $"āŒ Target directory not found: ($target_path)" print "šŸ’” Run './scripts/sh/collect-install.sh' first" exit 1 } let validation = validate_target $target_path if not $validation.valid { print "āŒ Target directory validation failed:" for issue in $validation.issues { print $" - ($issue)" } exit 1 } print $"āœ… Target directory validated: ($validation.plugin_count) plugins found" # Get system info and create archive name let sys_info = get_system_info let archive_name = $"($sys_info.platform)-($sys_info.arch)-($env_vars.APP_NAME).tar.gz" # Determine final archive path let archive_path = if ($output | str length) > 0 { $output } else if ($archive_dir | path exists) { $"($archive_dir)/($archive_name)" } else { $archive_name } # List mode if $list { print $"šŸ“‹ Files that would be archived from ($target_path):" let files = ls $target_path | where type == "file" for file in $files { print $" šŸ“„ ($file.name) (($file.size))" } print $"\nšŸ“¦ Would create archive: ($archive_path)" return } # Check if archive already exists if ($archive_path | path exists) and not $force { print $"āš ļø Archive already exists: ($archive_path)" let confirm = input "Overwrite? [y/N]: " if ($confirm | str downcase) != "y" { print "āŒ Aborted" exit 1 } } # Create archive directory if needed let archive_parent = $archive_path | path dirname if not ($archive_parent | path exists) { mkdir $archive_parent print $"šŸ“ Created archive directory: ($archive_parent)" } # Create the archive print $"šŸ“¦ Creating archive for ($sys_info.platform)-($sys_info.arch)..." create_archive $target_path $archive_path $env_vars # Summary print $"\nāœ… Distribution package created!" print $"šŸ“¦ Archive: ($archive_path)" print $"šŸ—ļø Platform: ($sys_info.platform)-($sys_info.arch)" let archive_size = ls $archive_path | get 0.size print $"šŸ“ Size: ($archive_size)" print "\nšŸ’” Next steps:" print $" 1. Test archive: tar -tzf ($archive_path)" print $" 2. Distribute: Upload or copy ($archive_path) to target systems" print $" 3. Install: Extract and run the installation script" } if ($env.NUSHELL_EXECUTION_CONTEXT? | default "" | str contains "run") { main }