#!/usr/bin/env nu # Build Nushell with all workspace plugins # # This script builds the complete nushell binary with all built-in plugins # from the nushell workspace, optimized for distribution. use lib/common_lib.nu [log_info, log_error, log_success, log_warn, validate_nushell_version] def main [ --release (-r) # Build in release mode (default: debug) --features (-f): string = "" # Additional cargo features to enable --target (-t): string = "" # Build target (cross-compilation) --verbose (-v) # Enable verbose output --profile (-p): string = "" # Build profile (release, dev, etc.) ] { log_info "🔨 Building Nushell with workspace plugins..." # Validate nushell version consistency first validate_nushell_version # Get nushell directory let nushell_dir = $"($env.PWD)/nushell" # Validate nushell directory exists if not ($nushell_dir | path exists) { log_error $"Nushell directory not found: ($nushell_dir)" exit 1 } # Build cargo command mut cargo_cmd = ["cargo", "build"] # Add build mode if $release != null { $cargo_cmd = ($cargo_cmd | append "--release") log_info "🚀 Building in release mode" } else { log_info "🛠️ Building in debug mode" } # Add profile if specified if ($profile | is-not-empty) { $cargo_cmd = ($cargo_cmd | append ["--profile", $profile]) log_info $"📋 Using profile: ($profile)" } # Add target if specified if ($target | is-not-empty) { $cargo_cmd = ($cargo_cmd | append ["--target", $target]) log_info $"🎯 Building for target: ($target)" } # Determine features to enable mut all_features = [ "plugin" # Enable plugin system "network" # Network commands "sqlite" # SQLite support "trash-support" # Trash commands "rustls-tls" # TLS support "system-clipboard" # System clipboard support ] # Add additional features if provided if ($features | is-not-empty) { let custom_features = ($features | split row ",") $all_features = ($all_features | append $custom_features) } # Add features to cargo command let features_str = ($all_features | str join ",") $cargo_cmd = ($cargo_cmd | append ["--features", $features_str]) log_info $"✨ Enabled features: ($features_str)" # Add verbose flag if requested if $verbose != null { $cargo_cmd = ($cargo_cmd | append "--verbose") log_info "📢 Verbose output enabled" } # Change to nushell directory log_info $"📁 Working in: ($nushell_dir)" try { # Execute cargo build let cargo_cmd_str = ($cargo_cmd | str join " ") log_info $"🔨 Running: ($cargo_cmd_str)" cd $nushell_dir let result = bash -c $cargo_cmd_str # Determine output directory based on build mode and target mut target_dir = $"($nushell_dir)/target" if ($target | is-not-empty) { $target_dir = $"($target_dir)/($target)" } mut profile_dir = if $release != null { "release" } else if ($profile | is-not-empty) { $profile } else { "debug" } let binary_path = $"($target_dir)/($profile_dir)/nu" let binary_path = if $nu.os-info.name == "windows" { $"($binary_path).exe" } else { $binary_path } # Check if binary was created if ($binary_path | path exists) { let binary_size = (ls $binary_path | get size.0) log_success $"✅ Nushell binary built successfully!" log_info $"📄 Binary location: ($binary_path)" log_info $"📊 Binary size: ($binary_size)" # Show binary info try { let version_info = run-external $binary_path "--version" | complete if $version_info.exit_code == 0 { log_info $"🔢 Version: ($version_info.stdout | str trim)" } } catch { log_warn "⚠️ Could not get version information" } # List workspace plugins that are built-in log_info "🧩 Built-in workspace plugins:" let workspace_plugins = [ "nu_plugin_custom_values" "nu_plugin_example" "nu_plugin_formats" "nu_plugin_gstat" "nu_plugin_inc" "nu_plugin_polars" "nu_plugin_query" "nu_plugin_stress_internals" ] for plugin in $workspace_plugins { let plugin_binary = $"($target_dir)/($profile_dir)/($plugin)" let plugin_binary = if $nu.os-info.name == "windows" { $"($plugin_binary).exe" } else { $plugin_binary } if ($plugin_binary | path exists) { let plugin_size = (ls $plugin_binary | get size.0) log_info $" ✅ ($plugin): ($plugin_size)" } else { log_warn $" ❌ ($plugin): not built" } } return { success: true binary_path: $binary_path target_dir: $target_dir profile_dir: $profile_dir features: $features_str } } else { log_error $"❌ Binary not found at expected location: ($binary_path)" exit 1 } } catch { |err| log_error $"❌ Build failed: ($err.msg)" exit 1 } } # Show build information def "build info" [] { log_info "🔨 Nushell Build Information" log_info "===========================" log_info "" log_info "Available features:" log_info " plugin - Enable plugin system" log_info " network - Network commands (http, etc.)" log_info " sqlite - SQLite database support" log_info " trash-support - Trash/recycle bin commands" log_info " rustls-tls - TLS support with rustls" log_info " system-clipboard - System clipboard integration" log_info " native-tls - TLS support with native libs" log_info " static-link-openssl - Statically link OpenSSL" log_info "" log_info "Build profiles:" log_info " dev - Debug build (default)" log_info " release - Optimized release build" log_info " profiling - Release with debug info" log_info " ci - CI optimized build" log_info "" log_info "Workspace plugins (built-in):" log_info " nu_plugin_custom_values - Custom value handling" log_info " nu_plugin_example - Example plugin" log_info " nu_plugin_formats - Additional file formats" log_info " nu_plugin_gstat - Git status plugin" log_info " nu_plugin_inc - Increment plugin" log_info " nu_plugin_polars - DataFrame support" log_info " nu_plugin_query - Query plugin" log_info " nu_plugin_stress_internals - Stress testing" } # Check build dependencies def "build deps" [] { log_info "🔍 Checking build dependencies..." # Check Rust toolchain try { let rust_version = run-external "rustc" "--version" | complete if $rust_version.exit_code == 0 { log_success $"✅ Rust: ($rust_version.stdout | str trim)" } else { log_error "❌ Rust compiler not found" return false } } catch { log_error "❌ Rust compiler not found" return false } # Check Cargo try { let cargo_version = run-external "cargo" "--version" | complete if $cargo_version.exit_code == 0 { log_success $"✅ Cargo: ($cargo_version.stdout | str trim)" } else { log_error "❌ Cargo not found" return false } } catch { log_error "❌ Cargo not found" return false } # Check nushell directory let nushell_dir = $"($env.PWD)/nushell" if ($nushell_dir | path exists) { log_success $"✅ Nushell source: ($nushell_dir)" } else { log_error $"❌ Nushell source not found: ($nushell_dir)" return false } # Check Cargo.toml let cargo_toml = $"($nushell_dir)/Cargo.toml" if ($cargo_toml | path exists) { log_success $"✅ Nushell Cargo.toml found" # Show workspace members try { let cargo_content = open $cargo_toml if "workspace" in $cargo_content { let members = $cargo_content.workspace.members | length log_info $"📦 Workspace members: ($members)" } } catch { log_warn "⚠️ Could not parse Cargo.toml" } } else { log_error $"❌ Nushell Cargo.toml not found: ($cargo_toml)" return false } log_success "✅ All build dependencies satisfied" return true }