2025-09-24 18:52:07 +01:00
|
|
|
#!/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
|
|
|
|
}
|
|
|
|
|
2025-09-24 21:28:50 +01:00
|
|
|
# Build cargo command with --workspace for system plugins
|
|
|
|
mut cargo_cmd = ["cargo", "build", "--workspace"]
|
|
|
|
log_info "📦 Building entire workspace (nushell + system plugins)"
|
2025-09-24 18:52:07 +01:00
|
|
|
|
|
|
|
# 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
|
|
|
|
}
|