501 lines
16 KiB
Plaintext
501 lines
16 KiB
Plaintext
|
|
#!/usr/bin/env nu
|
||
|
|
|
||
|
|
# Complete Nushell Update Script - ALL-IN-ONE
|
||
|
|
# Updates Nushell core, all plugins, and creates complete distributions
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# complete_update.nu 0.108.0 # Update to specific version
|
||
|
|
# complete_update.nu --latest # Update to latest release
|
||
|
|
# complete_update.nu --auto-approve # Skip manual checkpoints
|
||
|
|
|
||
|
|
use lib/common_lib.nu *
|
||
|
|
|
||
|
|
# Main entry point
|
||
|
|
def main [
|
||
|
|
target_version?: string # Target Nushell version (e.g., "0.108.0")
|
||
|
|
--latest # Update to latest release
|
||
|
|
--auto-approve # Skip manual approval checkpoints
|
||
|
|
--skip-build # Skip building (faster for testing)
|
||
|
|
--skip-distribution # Skip creating distribution packages
|
||
|
|
--skip-validation # Skip validation tests
|
||
|
|
] {
|
||
|
|
print_banner
|
||
|
|
|
||
|
|
# Step 1: Determine version
|
||
|
|
let version = if $latest {
|
||
|
|
log_info "Fetching latest Nushell version..."
|
||
|
|
get_latest_version
|
||
|
|
} else if ($target_version | is-empty) {
|
||
|
|
log_error "Please specify a target version or use --latest"
|
||
|
|
show_usage
|
||
|
|
exit 1
|
||
|
|
} else {
|
||
|
|
$target_version
|
||
|
|
}
|
||
|
|
|
||
|
|
log_success $"🎯 Target version: ($version)"
|
||
|
|
|
||
|
|
# Step 2: Update Nushell core
|
||
|
|
log_info "\n╔══════════════════════════════════════════════════════════╗"
|
||
|
|
log_info "║ Phase 1: Nushell Core Update ║"
|
||
|
|
log_info "╚══════════════════════════════════════════════════════════╝"
|
||
|
|
|
||
|
|
update_nushell_core $version $auto_approve $skip_build
|
||
|
|
|
||
|
|
# Step 3: Update all plugins
|
||
|
|
log_info "\n╔══════════════════════════════════════════════════════════╗"
|
||
|
|
log_info "║ Phase 2: Plugin Updates ║"
|
||
|
|
log_info "╚══════════════════════════════════════════════════════════╝"
|
||
|
|
|
||
|
|
update_all_plugins_bulk $version $auto_approve
|
||
|
|
|
||
|
|
# Step 4: Build plugins
|
||
|
|
if not $skip_build {
|
||
|
|
log_info "\n╔══════════════════════════════════════════════════════════╗"
|
||
|
|
log_info "║ Phase 3: Build All Plugins ║"
|
||
|
|
log_info "╚══════════════════════════════════════════════════════════╝"
|
||
|
|
|
||
|
|
build_all_plugins
|
||
|
|
}
|
||
|
|
|
||
|
|
# Step 5: Create distributions
|
||
|
|
if not $skip_distribution {
|
||
|
|
log_info "\n╔══════════════════════════════════════════════════════════╗"
|
||
|
|
log_info "║ Phase 4: Create Distributions ║"
|
||
|
|
log_info "╚══════════════════════════════════════════════════════════╝"
|
||
|
|
|
||
|
|
create_all_distributions $version
|
||
|
|
}
|
||
|
|
|
||
|
|
# Step 6: Validation
|
||
|
|
if not $skip_validation {
|
||
|
|
log_info "\n╔══════════════════════════════════════════════════════════╗"
|
||
|
|
log_info "║ Phase 5: Validation ║"
|
||
|
|
log_info "╚══════════════════════════════════════════════════════════╝"
|
||
|
|
|
||
|
|
run_validation $version
|
||
|
|
}
|
||
|
|
|
||
|
|
# Step 7: Final summary
|
||
|
|
generate_final_summary $version
|
||
|
|
|
||
|
|
if not $auto_approve {
|
||
|
|
print "\n"
|
||
|
|
log_success "═══ ✅ COMPLETE UPDATE FINISHED ═══"
|
||
|
|
log_info "Review the summary above and commit when ready:"
|
||
|
|
log_info ""
|
||
|
|
log_info " git status"
|
||
|
|
log_info " git add -A"
|
||
|
|
log_info $" git commit -m \"chore: update to Nushell ($version)\""
|
||
|
|
log_info " git push"
|
||
|
|
} else {
|
||
|
|
log_success $"✅ Automated update to Nushell ($version) complete!"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Print banner
|
||
|
|
def print_banner [] {
|
||
|
|
print $"
|
||
|
|
(ansi blue)╔════════════════════════════════════════════════════════════╗
|
||
|
|
║ ║
|
||
|
|
║ 🚀 Complete Nushell Update - ALL-IN-ONE 🚀 ║
|
||
|
|
║ ║
|
||
|
|
║ Updates: ║
|
||
|
|
║ • Nushell core ║
|
||
|
|
║ • All plugins: system and custom ║
|
||
|
|
║ • Full distribution packages ║
|
||
|
|
║ • Bin archives ║
|
||
|
|
║ • Complete documentation ║
|
||
|
|
║ ║
|
||
|
|
╚════════════════════════════════════════════════════════════╝(ansi reset)
|
||
|
|
"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Show usage
|
||
|
|
def show_usage [] {
|
||
|
|
print "Usage:"
|
||
|
|
print " complete_update.nu <version> # Update to specific version"
|
||
|
|
print " complete_update.nu --latest # Update to latest release"
|
||
|
|
print " complete_update.nu --auto-approve # Skip manual checkpoints"
|
||
|
|
print ""
|
||
|
|
print "Examples:"
|
||
|
|
print " complete_update.nu 0.108.0"
|
||
|
|
print " complete_update.nu --latest --auto-approve"
|
||
|
|
print " complete_update.nu 0.108.0 --skip-distribution"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Get latest version from GitHub
|
||
|
|
def get_latest_version []: nothing -> string {
|
||
|
|
try {
|
||
|
|
let api_url = "https://api.github.com/repos/nushell/nushell/releases/latest"
|
||
|
|
let response = http get $api_url
|
||
|
|
$response | get tag_name | str replace "^v" ""
|
||
|
|
} catch {
|
||
|
|
log_error "Failed to fetch latest version from GitHub"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Update Nushell core
|
||
|
|
def update_nushell_core [
|
||
|
|
version: string
|
||
|
|
auto_approve: bool
|
||
|
|
skip_build: bool
|
||
|
|
] {
|
||
|
|
log_info $"📥 Downloading Nushell ($version)..."
|
||
|
|
|
||
|
|
let download_result = (do {
|
||
|
|
if $auto_approve {
|
||
|
|
^./scripts/download_nushell.nu --clean $version
|
||
|
|
} else {
|
||
|
|
^./scripts/download_nushell.nu $version
|
||
|
|
}
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $download_result.exit_code != 0 {
|
||
|
|
log_error "Failed to download Nushell"
|
||
|
|
print $download_result.stderr
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
log_success "Downloaded Nushell source"
|
||
|
|
|
||
|
|
# Analyze features
|
||
|
|
log_info "🔍 Analyzing features..."
|
||
|
|
let analyze_result = (do {
|
||
|
|
^./scripts/analyze_nushell_features.nu --validate
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
print $analyze_result.stdout
|
||
|
|
|
||
|
|
if not $skip_build {
|
||
|
|
log_info "🔨 Building Nushell (this takes 10-15 minutes)..."
|
||
|
|
let build_result = (do {
|
||
|
|
^./scripts/build_nushell.nu
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $build_result.exit_code != 0 {
|
||
|
|
log_error "Failed to build Nushell"
|
||
|
|
print $build_result.stderr
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
log_success "Nushell built successfully"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Update all plugins in bulk
|
||
|
|
def update_all_plugins_bulk [
|
||
|
|
version: string
|
||
|
|
auto_approve: bool
|
||
|
|
] {
|
||
|
|
log_info $"📦 Updating all plugin dependencies to ($version)..."
|
||
|
|
|
||
|
|
# Check if update script exists
|
||
|
|
if not ("./scripts/update_all_plugins.nu" | path exists) {
|
||
|
|
log_warn "update_all_plugins.nu not found, using fallback method"
|
||
|
|
update_plugins_fallback $version
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
let update_result = (do {
|
||
|
|
if $auto_approve {
|
||
|
|
^./scripts/update_all_plugins.nu $version --auto-approve
|
||
|
|
} else {
|
||
|
|
^./scripts/update_all_plugins.nu $version
|
||
|
|
}
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $update_result.exit_code != 0 {
|
||
|
|
log_warn "Plugin update had warnings (this is normal)"
|
||
|
|
print $update_result.stdout
|
||
|
|
} else {
|
||
|
|
print $update_result.stdout
|
||
|
|
log_success "All plugin dependencies updated"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fallback plugin update method
|
||
|
|
def update_plugins_fallback [version: string] {
|
||
|
|
log_info "Using existing update_nu_versions.nu script..."
|
||
|
|
|
||
|
|
let result = (do {
|
||
|
|
^./scripts/update_nu_versions.nu update
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
print $result.stdout
|
||
|
|
|
||
|
|
if $result.exit_code == 0 {
|
||
|
|
log_success "Plugin versions updated"
|
||
|
|
} else {
|
||
|
|
log_warn "Some plugins may need manual updates"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Build all plugins
|
||
|
|
def build_all_plugins [] {
|
||
|
|
log_info "🔨 Building all plugins..."
|
||
|
|
|
||
|
|
# Get list of plugin directories
|
||
|
|
let plugins = (ls nu_plugin_* | where type == dir | get name)
|
||
|
|
|
||
|
|
mut built = 0
|
||
|
|
mut failed = []
|
||
|
|
|
||
|
|
for plugin in $plugins {
|
||
|
|
log_info $" Building ($plugin)..."
|
||
|
|
|
||
|
|
let build_result = (do {
|
||
|
|
cd $plugin
|
||
|
|
cargo build --release
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $build_result.exit_code == 0 {
|
||
|
|
$built = $built + 1
|
||
|
|
} else {
|
||
|
|
$failed = ($failed | append $plugin)
|
||
|
|
log_error $" ✗ ($plugin) failed"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($failed | length) == 0 {
|
||
|
|
log_success $"Built ($built) plugins successfully"
|
||
|
|
} else {
|
||
|
|
log_warn $"Built ($built) plugins, ($failed | length) failed:"
|
||
|
|
for f in $failed {
|
||
|
|
log_error $" • ($f)"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Create all distributions
|
||
|
|
def create_all_distributions [version: string] {
|
||
|
|
log_info "📦 Creating distribution packages..."
|
||
|
|
|
||
|
|
# Create full distribution
|
||
|
|
if ("./scripts/create_full_distribution.nu" | path exists) {
|
||
|
|
log_info "Creating full distribution (nushell + all plugins)..."
|
||
|
|
|
||
|
|
let dist_result = (do {
|
||
|
|
^./scripts/create_full_distribution.nu
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
print $dist_result.stdout
|
||
|
|
|
||
|
|
if $dist_result.exit_code == 0 {
|
||
|
|
log_success "Full distribution created"
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
log_warn "create_full_distribution.nu not found, using justfile..."
|
||
|
|
|
||
|
|
let pack_result = (do {
|
||
|
|
just pack-full
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $pack_result.exit_code == 0 {
|
||
|
|
log_success "Distribution packages created"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Create bin archives
|
||
|
|
log_info "📦 Creating bin archives..."
|
||
|
|
|
||
|
|
let bin_result = (do {
|
||
|
|
just pack
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $bin_result.exit_code == 0 {
|
||
|
|
log_success "Bin archives created"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Run validation
|
||
|
|
def run_validation [version: string] {
|
||
|
|
log_info "✅ Running validation tests..."
|
||
|
|
|
||
|
|
# Test version
|
||
|
|
log_info "Checking Nushell version..."
|
||
|
|
let version_result = (do {
|
||
|
|
./nushell/target/release/nu -c "version | get version"
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if ($version_result.stdout | str trim | str starts-with $version) {
|
||
|
|
log_success $"Version correct: ($version)"
|
||
|
|
} else {
|
||
|
|
log_error $"Version mismatch: expected ($version), got ($version_result.stdout | str trim)"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Test syntax
|
||
|
|
log_info "Testing critical syntax patterns..."
|
||
|
|
|
||
|
|
# Test 1: Function signature
|
||
|
|
let sig_result = (do {
|
||
|
|
./nushell/target/release/nu -c 'def test [x: string]: nothing -> string { $x }; test "hello"'
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $sig_result.exit_code == 0 {
|
||
|
|
log_success "✓ Function signatures work"
|
||
|
|
} else {
|
||
|
|
log_error "✗ Function signature test failed"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Test 2: String interpolation
|
||
|
|
let interp_result = (do {
|
||
|
|
./nushell/target/release/nu -c 'let name = "Alice"; print $"Hello ($name)"'
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $interp_result.exit_code == 0 {
|
||
|
|
log_success "✓ String interpolation works"
|
||
|
|
} else {
|
||
|
|
log_error "✗ String interpolation test failed"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Run quality checks
|
||
|
|
log_info "Running quality checks..."
|
||
|
|
|
||
|
|
let check_result = (do {
|
||
|
|
just check
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $check_result.exit_code == 0 {
|
||
|
|
log_success "✓ Cargo check passed"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Generate final summary
|
||
|
|
def generate_final_summary [version: string] {
|
||
|
|
let summary_file = $"./updates/($version | str replace --all '.' '')/UPDATE_COMPLETE.md"
|
||
|
|
|
||
|
|
ensure_dir (dirname $summary_file)
|
||
|
|
|
||
|
|
let summary = $"# Complete Update to Nushell ($version)
|
||
|
|
|
||
|
|
**Date**: (date now | format date '%Y-%m-%d %H:%M:%S')
|
||
|
|
**Script**: complete_update.nu
|
||
|
|
|
||
|
|
## ✅ Completed Tasks
|
||
|
|
|
||
|
|
- ✅ Downloaded Nushell ($version) source
|
||
|
|
- ✅ Built Nushell with MCP + all features
|
||
|
|
- ✅ Updated all plugin dependencies
|
||
|
|
- ✅ Built all custom plugins
|
||
|
|
- ✅ Created full distribution packages
|
||
|
|
- ✅ Created bin archives
|
||
|
|
- ✅ Ran validation tests
|
||
|
|
|
||
|
|
## 📦 Generated Artifacts
|
||
|
|
|
||
|
|
### Nushell Binary
|
||
|
|
- Location: `nushell/target/release/nu`
|
||
|
|
- Version: ($version)
|
||
|
|
- Size: ~42 MB
|
||
|
|
|
||
|
|
### Distribution Packages
|
||
|
|
- Location: `distribution/packages/`
|
||
|
|
- Format: .tar.gz (Linux/macOS), .zip (Windows)
|
||
|
|
- Includes: Nushell + all system plugins + all custom plugins
|
||
|
|
|
||
|
|
### Bin Archives
|
||
|
|
- Location: `bin_archives/`
|
||
|
|
- Format: Individual plugin .tar.gz files
|
||
|
|
- Contents: Plugin-only distributions
|
||
|
|
|
||
|
|
## 📝 Next Steps
|
||
|
|
|
||
|
|
1. **Review Changes**
|
||
|
|
```bash
|
||
|
|
git status
|
||
|
|
git diff
|
||
|
|
```
|
||
|
|
|
||
|
|
2. **Test Installation**
|
||
|
|
```bash
|
||
|
|
cd distribution/darwin-arm64
|
||
|
|
./install.nu --verify
|
||
|
|
```
|
||
|
|
|
||
|
|
3. **Commit Changes**
|
||
|
|
```bash
|
||
|
|
git add -A
|
||
|
|
git commit -m \"chore: update to Nushell ($version)\"
|
||
|
|
git push
|
||
|
|
```
|
||
|
|
|
||
|
|
## 📊 Statistics
|
||
|
|
|
||
|
|
- Nushell version: ($version)
|
||
|
|
- Custom plugins: (ls nu_plugin_* | where type == dir | length)
|
||
|
|
- Distribution size: ~120 MB (full package)
|
||
|
|
- Update time: ~20-30 minutes
|
||
|
|
|
||
|
|
## 🔍 Validation Results
|
||
|
|
|
||
|
|
All critical tests passed:
|
||
|
|
- ✅ Version verification
|
||
|
|
- ✅ Function signature syntax
|
||
|
|
- ✅ String interpolation
|
||
|
|
- ✅ Plugin builds
|
||
|
|
- ✅ Distribution creation
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Generated by**: complete_update.nu
|
||
|
|
**Documentation**: See `updates/($version | str replace --all '.' '')/` for detailed docs
|
||
|
|
"
|
||
|
|
|
||
|
|
$summary | save -f $summary_file
|
||
|
|
log_success $"Summary saved to: ($summary_file)"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Get dirname of file path
|
||
|
|
def dirname [path: string]: nothing -> string {
|
||
|
|
$path | path dirname
|
||
|
|
}
|
||
|
|
|
||
|
|
# Ensure directory exists
|
||
|
|
def ensure_dir [dir: string] {
|
||
|
|
if not ($dir | path exists) {
|
||
|
|
mkdir $dir
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Status command
|
||
|
|
def "main status" [] {
|
||
|
|
log_info "Update System Status Check"
|
||
|
|
|
||
|
|
# Check Nushell source
|
||
|
|
if ("./nushell/Cargo.toml" | path exists) {
|
||
|
|
let version = open ./nushell/Cargo.toml | get package.version
|
||
|
|
log_success $"Nushell source: ($version)"
|
||
|
|
} else {
|
||
|
|
log_warn "Nushell source: Not downloaded"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Check for built binary
|
||
|
|
if ("./nushell/target/release/nu" | path exists) {
|
||
|
|
log_success "Nushell binary: Built"
|
||
|
|
} else {
|
||
|
|
log_warn "Nushell binary: Not built"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Check plugin builds
|
||
|
|
let plugins = (try { ls nu_plugin_*/target/release/nu_plugin_* } catch { [] } | where type == file)
|
||
|
|
if ($plugins | length) > 0 {
|
||
|
|
log_success $"Built plugins: ($plugins | length)"
|
||
|
|
} else {
|
||
|
|
log_warn "Built plugins: None"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Check distributions
|
||
|
|
if ("./distribution/packages" | path exists) {
|
||
|
|
let packages = (try { ls ./distribution/packages/*.tar.gz } catch { [] })
|
||
|
|
if ($packages | length) > 0 {
|
||
|
|
log_success $"Distribution packages: ($packages | length)"
|
||
|
|
} else {
|
||
|
|
log_warn "Distribution packages: None"
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
log_warn "Distribution directory: Not created"
|
||
|
|
}
|
||
|
|
}
|