#!/usr/bin/env nu # Create Distribution Manifest - Scan & List Available Plugins # # Scans the distribution directory for available plugin binaries # and creates a manifest file for the installer to use. # # Usage: # create_distribution_manifest.nu # Scan current directory # create_distribution_manifest.nu ./dist # Scan specific directory # create_distribution_manifest.nu --output manifest.json def main [ source_dir: string = "." # Directory to scan for plugins --output: string = "DISTRIBUTION_MANIFEST.json" # Output manifest file ] { log_info "šŸ“‹ Distribution Manifest Generator" log_info "==================================================================" log_info $"\nšŸ” Step 1: Scanning directory: ($source_dir)" # Find all plugin binaries let plugins = scan_for_plugins $source_dir if ($plugins | length) == 0 { log_error "No plugin binaries found!" log_error $"Expected: ($source_dir)/nu_plugin_*" return } log_success $"Found ($plugins | length) plugin\(s\)" print "" # Display found plugins for plugin in $plugins { log_info $" āœ“ ($plugin.name)" } # Create manifest log_info $"\nšŸ“ Step 2: Creating manifest..." let manifest = { version: "1.0.0" created: (date now | format date "%Y-%m-%dT%H:%M:%SZ") source_directory: $source_dir total_plugins: ($plugins | length) plugins: $plugins } # Save manifest log_info $"\nšŸ’¾ Step 3: Saving to ($output)..." try { $manifest | to json | save -f $output log_success $"Manifest saved: ($output)" } catch {|err| log_error $"Failed to save manifest: ($err.msg)" return } # Summary log_info "\n==================================================================" log_success "āœ… Manifest created!" log_info "" log_info "Next steps:" log_info $" 1. Include ($output) in distribution" log_info " 2. Run installer with: install_from_manifest.nu --manifest $output" } # Scan directory for plugins def scan_for_plugins [source_dir: string]: nothing -> list { mut found = [] try { let all_files = ls $source_dir let plugin_files = $all_files | where type == "file" | where {|row| let basename = $row.name | path basename $basename =~ "^nu_plugin_" } let plugins = $plugin_files | each {|row| let basename = $row.name | path basename let purpose = get_plugin_purpose $basename let file_size = $row.size { name: $basename purpose: $purpose path: $row.name size_bytes: $file_size } } $found = $plugins } catch {|err| log_error $"Error scanning directory: ($err.msg)" } $found } # Get plugin purpose/description def get_plugin_purpose [name: string]: nothing -> string { let purposes = { "nu_plugin_auth": "Authentication (JWT, MFA)" "nu_plugin_kms": "Encryption & KMS" "nu_plugin_orchestrator": "Orchestration operations" "nu_plugin_kcl": "KCL configuration" "nu_plugin_tera": "Template rendering" "nu_plugin_highlight": "Syntax highlighting" "nu_plugin_clipboard": "Clipboard operations" "nu_plugin_image": "Image processing" "nu_plugin_hashes": "Hash functions" "nu_plugin_qr_maker": "QR code generation" "nu_plugin_fluent": "Localization" "nu_plugin_desktop_notifications": "Desktop notifications" "nu_plugin_port_extension": "Port extensions" "nu_plugin_polars": "Data analysis" "nu_plugin_formats": "Format conversion" "nu_plugin_inc": "Increment operations" "nu_plugin_gstat": "Git status" "nu_plugin_query": "Advanced querying" "nu_plugin_custom_values": "Custom values" "nu_plugin_example": "Example template" "nu_plugin_stress_internals": "Stress testing" } $purposes | get --optional $name | default "Nushell plugin" } # Logging def log_info [msg: string] { print $"ā„¹ļø ($msg)" } def log_success [msg: string] { print $"āœ… ($msg)" } def log_error [msg: string] { print $"āŒ ($msg)" } main