- Add `show-arguments` recipe documenting all version update commands - Add `complete-update-interactive` recipe for manual confirmations - Maintain `complete-update` as automatic mode (no prompts) - Update `update-help` to reference new recipes and modes - Document 7-step workflow and step-by-step differences Changes: - complete-update: Automatic mode (recommended for CI/CD) - complete-update-interactive: Interactive mode (with confirmations) - show-arguments: Complete documentation of all commands and modes - Both modes share same 7-step workflow with different behavior in Step 4
294 lines
8.3 KiB
Plaintext
Executable File
294 lines
8.3 KiB
Plaintext
Executable File
#!/usr/bin/env nu
|
|
|
|
# Download Nushell Source Script
|
|
# Downloads and extracts Nushell source from GitHub tags
|
|
#
|
|
# Usage:
|
|
# download_nushell.nu <version> # Download specific version
|
|
# download_nushell.nu --latest # Download latest release
|
|
# download_nushell.nu --clean # Remove existing nushell directory
|
|
|
|
use lib/common_lib.nu *
|
|
|
|
# Main entry point
|
|
def main [
|
|
version?: string # Nushell version (e.g., "0.108.0")
|
|
--latest # Download latest release
|
|
--clean # Remove existing nushell directory first
|
|
--verify # Verify download integrity
|
|
] {
|
|
log_info "Nushell Source Download Script"
|
|
|
|
# Determine target version
|
|
let target_version = if $latest {
|
|
get_latest_nushell_version
|
|
} else if ($version | is-empty) {
|
|
log_error "Please specify a version or use --latest flag"
|
|
log_info "Usage: download_nushell.nu <version> or download_nushell.nu --latest"
|
|
exit 1
|
|
} else {
|
|
$version
|
|
}
|
|
|
|
log_info $"Target version: [$target_version]"
|
|
|
|
# Clean existing directory if requested
|
|
if $clean {
|
|
clean_nushell_directory
|
|
}
|
|
|
|
# Download and extract
|
|
download_nushell_tarball $target_version $verify
|
|
|
|
# Verify extraction
|
|
verify_nushell_source $target_version
|
|
|
|
log_success $"Nushell [$target_version] downloaded and ready!"
|
|
log_info $"Location: ./nushell/"
|
|
log_info $"Next steps: Run 'just analyze-nushell-features' to check available features"
|
|
}
|
|
|
|
# Get latest nushell version from GitHub API
|
|
def get_latest_nushell_version []: nothing -> string {
|
|
log_info "Fetching latest Nushell version from GitHub..."
|
|
|
|
let api_url = "https://api.github.com/repos/nushell/nushell/releases/latest"
|
|
|
|
let response = try {
|
|
http get $api_url
|
|
} catch {
|
|
log_error "Failed to fetch latest release from GitHub API"
|
|
log_info "Falling back to manual check at: https://github.com/nushell/nushell/releases"
|
|
exit 1
|
|
}
|
|
|
|
let tag_name = try {
|
|
$response | get tag_name | str trim
|
|
} catch {
|
|
log_error "Could not parse tag_name from GitHub response"
|
|
exit 1
|
|
}
|
|
|
|
# Remove 'v' prefix if present
|
|
let version = $tag_name | str replace "^v" ""
|
|
|
|
log_success $"Latest version: [$version]"
|
|
$version
|
|
}
|
|
|
|
# Clean existing nushell directory
|
|
def clean_nushell_directory [] {
|
|
let nushell_dir = "./nushell"
|
|
|
|
if ($nushell_dir | path exists) {
|
|
log_warn "Removing existing nushell directory..."
|
|
rm -rf $nushell_dir
|
|
log_success "Cleaned nushell directory"
|
|
} else {
|
|
log_info "No existing nushell directory to clean"
|
|
}
|
|
}
|
|
|
|
# Download nushell tarball from GitHub
|
|
def download_nushell_tarball [
|
|
version: string
|
|
verify_checksum: bool
|
|
] {
|
|
let tarball_url = $"https://github.com/nushell/nushell/archive/refs/tags/($version).tar.gz"
|
|
let download_dir = "./tmp"
|
|
let tarball_path = $"($download_dir)/nushell-($version).tar.gz"
|
|
|
|
# Ensure tmp directory exists
|
|
ensure_dir $download_dir
|
|
|
|
# Download tarball
|
|
log_info $"Downloading from: ($tarball_url)"
|
|
|
|
let download_result = try {
|
|
http get $tarball_url | save -f $tarball_path
|
|
{success: true}
|
|
} catch { |err|
|
|
{success: false, error: $err}
|
|
}
|
|
|
|
if not $download_result.success {
|
|
log_error $"Failed to download tarball from GitHub"
|
|
log_info $"URL: ($tarball_url)"
|
|
exit 1
|
|
}
|
|
|
|
# Check file was downloaded
|
|
if not ($tarball_path | path exists) {
|
|
log_error $"Tarball not found at [$tarball_path]"
|
|
exit 1
|
|
}
|
|
|
|
let file_size = (ls $tarball_path | get size.0)
|
|
log_success $"Downloaded tarball: ($file_size) bytes"
|
|
|
|
# Verify checksum if requested
|
|
if $verify_checksum {
|
|
verify_download_checksum $tarball_path $version
|
|
}
|
|
|
|
# Extract tarball
|
|
extract_nushell_tarball $tarball_path $version
|
|
}
|
|
|
|
# Verify download checksum (optional)
|
|
def verify_download_checksum [
|
|
tarball_path: string
|
|
version: string
|
|
] {
|
|
log_info "Calculating SHA256 checksum..."
|
|
|
|
let checksum = open $tarball_path --raw | hash sha256
|
|
log_info $"Checksum: ($checksum)"
|
|
|
|
# Note: GitHub doesn't provide checksums for source archives
|
|
# This is just for verification and logging
|
|
log_warn "GitHub source archives don't have published checksums"
|
|
log_info "Checksum calculated for local verification only"
|
|
}
|
|
|
|
# Extract nushell tarball
|
|
def extract_nushell_tarball [
|
|
tarball_path: string
|
|
version: string
|
|
] {
|
|
log_info "Extracting tarball..."
|
|
|
|
let tmp_extract_dir = "./tmp/nushell-extract"
|
|
ensure_dir $tmp_extract_dir
|
|
|
|
# Extract to temp directory
|
|
let extract_result = try {
|
|
^tar -xzf $tarball_path -C $tmp_extract_dir
|
|
{success: true}
|
|
} catch { |err|
|
|
{success: false, error: $err}
|
|
}
|
|
|
|
if not $extract_result.success {
|
|
log_error "Failed to extract tarball"
|
|
exit 1
|
|
}
|
|
|
|
# GitHub creates a directory like "nushell-0.108.0"
|
|
let extracted_dir = $"($tmp_extract_dir)/nushell-($version)"
|
|
|
|
if not ($extracted_dir | path exists) {
|
|
log_error $"Expected directory not found: [$extracted_dir]"
|
|
log_info "Checking available directories..."
|
|
ls $tmp_extract_dir | each {|it| log_info $" Found: ($it.name)"}
|
|
exit 1
|
|
}
|
|
|
|
# Move to final location
|
|
let target_dir = "./nushell"
|
|
if ($target_dir | path exists) {
|
|
log_warn "Target directory already exists, removing..."
|
|
rm -rf $target_dir
|
|
}
|
|
|
|
mv $extracted_dir $target_dir
|
|
log_success $"Extracted to: ($target_dir)"
|
|
|
|
# Cleanup
|
|
rm -rf $tmp_extract_dir
|
|
rm $tarball_path
|
|
log_info "Cleaned up temporary files"
|
|
}
|
|
|
|
# Verify nushell source was extracted correctly
|
|
def verify_nushell_source [
|
|
version: string
|
|
] {
|
|
log_info "Verifying nushell source..."
|
|
|
|
let nushell_dir = "./nushell"
|
|
let cargo_toml = $"($nushell_dir)/Cargo.toml"
|
|
|
|
# Check main Cargo.toml exists
|
|
if not ($cargo_toml | path exists) {
|
|
log_error $"Cargo.toml not found at [$cargo_toml]"
|
|
exit 1
|
|
}
|
|
|
|
# Verify version in Cargo.toml
|
|
let cargo_version = try {
|
|
open $cargo_toml | get package.version
|
|
} catch {
|
|
log_error "Could not read version from Cargo.toml"
|
|
exit 1
|
|
}
|
|
|
|
if $cargo_version != $version {
|
|
log_warn $"Version mismatch: Cargo.toml shows [$cargo_version], expected [$version]"
|
|
log_info "This might be normal if the version doesn't exactly match the tag"
|
|
} else {
|
|
log_success $"Version verified: [$cargo_version]"
|
|
}
|
|
|
|
# Check workspace structure
|
|
let workspace_members = try {
|
|
open $cargo_toml | get workspace.members
|
|
} catch {
|
|
log_error "Could not read workspace members from Cargo.toml"
|
|
exit 1
|
|
}
|
|
|
|
let member_count = $workspace_members | length
|
|
log_success $"Found ($member_count) workspace members"
|
|
|
|
# Check for system plugins
|
|
let system_plugins = $workspace_members | where {|it| $it | str starts-with "crates/nu_plugin_"}
|
|
let plugin_count = $system_plugins | length
|
|
log_info $"System plugins: ($plugin_count)"
|
|
|
|
# List system plugins
|
|
if $plugin_count > 0 {
|
|
log_info "System plugins found:"
|
|
$system_plugins | each {|plugin|
|
|
let plugin_name = $plugin | str replace "crates/" ""
|
|
log_info $" • ($plugin_name)"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Show current nushell source info
|
|
def "main info" [] {
|
|
let nushell_dir = "./nushell"
|
|
|
|
if not ($nushell_dir | path exists) {
|
|
log_error "Nushell source not found"
|
|
log_info "Run: download_nushell.nu <version>"
|
|
exit 1
|
|
}
|
|
|
|
let cargo_toml = $"($nushell_dir)/Cargo.toml"
|
|
let version = open $cargo_toml | get package.version
|
|
|
|
log_info "Nushell Source Information"
|
|
log_info $" Version: [$version]"
|
|
log_info $" Location: ($nushell_dir)"
|
|
|
|
let workspace_members = open $cargo_toml | get workspace.members
|
|
let member_count = $workspace_members | length
|
|
log_info $" Workspace members: ($member_count)"
|
|
|
|
let system_plugins = $workspace_members | where {|it| $it | str starts-with "crates/nu_plugin_"}
|
|
log_info $" System plugins: ($system_plugins | length)"
|
|
}
|
|
|
|
# Clean up downloaded files
|
|
def "main clean" [] {
|
|
clean_nushell_directory
|
|
|
|
let tmp_dir = "./tmp"
|
|
if ($tmp_dir | path exists) {
|
|
rm -rf $tmp_dir
|
|
log_success "Removed tmp directory"
|
|
}
|
|
}
|