
## Summary Comprehensive repository cleanup focusing on plugin dependency management, documentation improvements, and git tracking optimization. ## Key Changes ### 🔧 Core Infrastructure - Synchronized all nu-* dependencies across plugins for version consistency - Enhanced upstream tracking and automation systems - Removed nushell directory from git tracking for cleaner repository management ### 📚 Documentation - Significantly expanded README.md with comprehensive development guides - Added detailed workflow documentation and command references - Improved plugin collection overview and usage examples ### 🧹 Repository Cleanup - Removed legacy bash scripts (build-all.sh, collect-install.sh, make_plugin.sh) - Streamlined automation through unified justfile and nushell script approach - Updated .gitignore with nushell directory and archive patterns - Removed nushell directory from git tracking to prevent unwanted changes ### 🔌 Plugin Updates - **nu_plugin_image**: Major refactoring with modular architecture improvements - **nu_plugin_hashes**: Enhanced functionality and build system improvements - **nu_plugin_highlight**: Updated for new plugin API compatibility - **nu_plugin_clipboard**: Dependency synchronization - **nu_plugin_desktop_notifications**: Version alignment - **nu_plugin_port_extension & nu_plugin_qr_maker**: Consistency updates - **nu_plugin_kcl & nu_plugin_tera**: Submodule synchronization ### 🏗️ Git Tracking Optimization - Removed nushell directory from version control for cleaner repository management - Added comprehensive .gitignore patterns for build artifacts and archives ## Statistics - 2,082 files changed - 2,373 insertions, 339,936 deletions - Net reduction of 337,563 lines (primarily from removing nushell directory tracking) ## Benefits - Complete version consistency across all plugins - Cleaner repository with optimized git tracking - Improved developer experience with streamlined workflows - Enhanced documentation and automation - Reduced repository size and complexity 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
473 lines
16 KiB
Plaintext
Executable File
473 lines
16 KiB
Plaintext
Executable File
#!/usr/bin/env nu
|
|
|
|
# Collect Install Script
|
|
# Collects built plugins and prepares them for installation/distribution
|
|
|
|
# Load environment variables from env file
|
|
def load_env_vars [] {
|
|
let env_file = "env"
|
|
if ($env_file | path exists) {
|
|
let content = open $env_file | lines
|
|
| where ($it | str trim | str length) > 0
|
|
| where not ($it | str starts-with "#")
|
|
| each {|line|
|
|
if ($line | str contains "=") {
|
|
let parts = ($line | split row "=")
|
|
if ($parts | length) >= 2 {
|
|
let key = ($parts | get 0 | str replace "export " "" | str trim)
|
|
let raw_value = ($parts | get 1 | str trim)
|
|
# Handle bash-style default values like ${VAR:-default}
|
|
let value = if ($raw_value | str starts-with "${") and ($raw_value | str contains ":-") {
|
|
# Extract default value from ${VAR:-default}
|
|
let parts = ($raw_value | str replace "${" "" | str replace "}" "" | split row ":-")
|
|
if ($parts | length) >= 2 {
|
|
$parts | get 1
|
|
} else {
|
|
$raw_value
|
|
}
|
|
} else {
|
|
$raw_value
|
|
}
|
|
{$key: $value}
|
|
} else {
|
|
{}
|
|
}
|
|
} else {
|
|
{}
|
|
}
|
|
}
|
|
| reduce -f {} {|item, acc|
|
|
if ($item | is-empty) {
|
|
$acc
|
|
} else {
|
|
$acc | merge $item
|
|
}
|
|
}
|
|
|
|
$content
|
|
} else {
|
|
{
|
|
TARGET_PATH: "distribution",
|
|
INSTALL_BIN_PATH: "/usr/local/bin",
|
|
ARCHIVE_DIR_PATH: "/tmp",
|
|
BIN_ARCHIVES_DIR_PATH: "bin_archives"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Load build targets configuration
|
|
def load_targets_config [] {
|
|
if ("etc/build_targets.toml" | path exists) {
|
|
open etc/build_targets.toml
|
|
} else {
|
|
{targets: {}}
|
|
}
|
|
}
|
|
|
|
# Get host platform information
|
|
def get_host_info [] {
|
|
let arch = match (^uname -m) {
|
|
"x86_64" => "amd64",
|
|
"aarch64" => "arm64",
|
|
"arm64" => "arm64",
|
|
$arch if ($arch | str starts-with "arm") => "arm64",
|
|
$other => $other
|
|
}
|
|
|
|
let platform = match (^uname -s | str downcase) {
|
|
$os if ($os | str contains "linux") => "linux",
|
|
$os if ($os | str contains "darwin") => "darwin",
|
|
$os if ($os | str contains "windows") => "windows",
|
|
$other => $other
|
|
}
|
|
|
|
{platform: $platform, arch: $arch, full: $"($platform)-($arch)"}
|
|
}
|
|
|
|
# Get all built plugin binaries for a specific target or all targets
|
|
def get_built_plugins [target: string = ""] {
|
|
let config = load_targets_config
|
|
let host_info = get_host_info
|
|
|
|
if ($target | str length) > 0 {
|
|
# Special handling for "host" target or detected host platform
|
|
if ($target == "host") or ($target == $host_info.full) {
|
|
# Get plugins for host platform (native build)
|
|
glob "nu_plugin_*/target/release/nu_plugin_*"
|
|
| where ($it | path type) == "file"
|
|
| where ($it | path exists)
|
|
| where not ($it | str ends-with ".d")
|
|
| each {|path|
|
|
let plugin_name = $path | path basename
|
|
let plugin_dir = $path | path dirname | path dirname | path dirname
|
|
{
|
|
name: $plugin_name,
|
|
path: $path,
|
|
source_dir: $plugin_dir,
|
|
target: $host_info.full,
|
|
size: (ls $path | get size | get 0)
|
|
}
|
|
}
|
|
} else if ($target in ($config.targets | transpose name config | get name)) {
|
|
# Get plugins for specific target
|
|
let target_config = $config.targets | get $target
|
|
get_plugins_for_target $target $target_config
|
|
} else {
|
|
print $"❌ Unknown target: ($target)"
|
|
[]
|
|
}
|
|
} else {
|
|
# Get plugins for host platform - use actual detected platform
|
|
glob "nu_plugin_*/target/release/nu_plugin_*"
|
|
| where ($it | path type) == "file"
|
|
| where ($it | path exists)
|
|
| where not ($it | str ends-with ".d")
|
|
| each {|path|
|
|
let plugin_name = $path | path basename
|
|
let plugin_dir = $path | path dirname | path dirname | path dirname
|
|
{
|
|
name: $plugin_name,
|
|
path: $path,
|
|
source_dir: $plugin_dir,
|
|
target: $host_info.full,
|
|
size: (ls $path | get 0.size)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# Get plugins for a specific target
|
|
def get_plugins_for_target [target_name: string, target_config: record] {
|
|
let rust_target = $target_config.rust_target
|
|
let binary_ext = $target_config | get binary_extension? | default ""
|
|
|
|
# Look for binaries in target-specific directories
|
|
let target_pattern = $"nu_plugin_*/target/($rust_target)/release/nu_plugin_*"
|
|
|
|
glob $target_pattern
|
|
| where ($it | path type) == "file"
|
|
| where ($it | path exists)
|
|
| where not ($it | str ends-with ".d")
|
|
| each {|path|
|
|
let plugin_name = $path | path basename
|
|
let plugin_dir = $path | path dirname | path dirname | path dirname | path dirname
|
|
{
|
|
name: $plugin_name,
|
|
path: $path,
|
|
source_dir: $plugin_dir,
|
|
target: $target_name,
|
|
size: (ls $path | get 0.size)
|
|
}
|
|
}
|
|
}
|
|
|
|
# Get all available built targets
|
|
def get_available_targets [] {
|
|
let config = load_targets_config
|
|
let host_info = get_host_info
|
|
|
|
mut available = []
|
|
|
|
# Check host platform first
|
|
let host_plugins = glob "nu_plugin_*/target/release/nu_plugin_*" | where not ($it | str ends-with ".d")
|
|
if ($host_plugins | length) > 0 {
|
|
$available = ($available | append {
|
|
name: $host_info.full,
|
|
platform_name: $host_info.full,
|
|
count: ($host_plugins | length),
|
|
description: "Host platform binaries"
|
|
})
|
|
}
|
|
|
|
# Check cross-compiled targets
|
|
for target in ($config.targets | transpose name config) {
|
|
let rust_target = $target.config.rust_target
|
|
let target_plugins = glob $"nu_plugin_*/target/($rust_target)/release/nu_plugin_*" | where not ($it | str ends-with ".d")
|
|
if ($target_plugins | length) > 0 {
|
|
$available = ($available | append {
|
|
name: $target.name,
|
|
platform_name: $target.config.platform_name,
|
|
count: ($target_plugins | length),
|
|
description: $target.config.description
|
|
})
|
|
}
|
|
}
|
|
|
|
$available
|
|
}
|
|
|
|
# Create target directory structure
|
|
def create_target_structure [target_path: string] {
|
|
if not ($target_path | path exists) {
|
|
mkdir $target_path
|
|
print $"📁 Created target directory: ($target_path)"
|
|
}
|
|
|
|
# Create subdirectories if needed
|
|
let subdirs = ["scripts", "docs"]
|
|
for subdir in $subdirs {
|
|
let subdir_path = $"($target_path)/($subdir)"
|
|
if not ($subdir_path | path exists) {
|
|
mkdir $subdir_path
|
|
}
|
|
}
|
|
}
|
|
|
|
# Copy plugin binaries to target
|
|
def copy_plugins [plugins: list, target_path: string] {
|
|
print $"📦 Copying ($plugins | length) plugin binaries..."
|
|
|
|
for plugin in $plugins {
|
|
let dest_path = $"($target_path)/($plugin.name)"
|
|
cp $plugin.path $dest_path
|
|
|
|
# Make executable
|
|
chmod +x $dest_path
|
|
|
|
print $" ✅ ($plugin.name) (($plugin.size))"
|
|
}
|
|
}
|
|
|
|
# Copy additional files
|
|
def copy_additional_files [target_path: string] {
|
|
let files_to_copy = [
|
|
{src: "LICENSE", dest: "LICENSE", required: false},
|
|
{src: "README.md", dest: "README", required: false},
|
|
{src: "env", dest: "env", required: false}
|
|
]
|
|
|
|
for file in $files_to_copy {
|
|
if ($file.src | path exists) {
|
|
cp $file.src $"($target_path)/($file.dest)"
|
|
print $" 📄 Copied ($file.src) → ($file.dest)"
|
|
} else if $file.required {
|
|
print $" ⚠️ Required file not found: ($file.src)"
|
|
}
|
|
}
|
|
}
|
|
|
|
# Create installation script
|
|
def create_install_script [target_path: string, install_file: string] {
|
|
let timestamp = (date now | format date "%Y-%m-%d %H:%M:%S")
|
|
let install_script_content = "#!/usr/bin/env nu
|
|
|
|
# Auto-generated installation script for nushell plugins
|
|
# Generated at: " + $timestamp + "
|
|
|
|
def main [
|
|
--bin-path (-b): string = \"/usr/local/bin\" # Installation path
|
|
--plugins (-p): list<string> = [] # Specific plugins to install
|
|
--list (-l) # List available plugins
|
|
--dry-run (-d) # Show what would be done
|
|
] {
|
|
let available_plugins = ls | where type == file and name =~ \"nu_plugin_\" | get name
|
|
|
|
if " + '$list' + " {
|
|
print \"📦 Available plugins:\"
|
|
for plugin in " + '$available_plugins' + " {
|
|
print " + '$" - ($plugin)"' + "
|
|
}
|
|
return
|
|
}
|
|
|
|
let plugins_to_install = if (" + '$plugins' + " | length) > 0 {
|
|
" + '$plugins' + " | where " + '$it' + " in " + '$available_plugins' + "
|
|
} else {
|
|
" + '$available_plugins' + "
|
|
}
|
|
|
|
if (" + '$plugins_to_install' + " | length) == 0 {
|
|
print \"❓ No plugins to install\"
|
|
return
|
|
}
|
|
|
|
print " + '$"🚀 Installing ($plugins_to_install | length) plugins to ($bin_path)..."' + "
|
|
|
|
for plugin in " + '$plugins_to_install' + " {
|
|
if " + '$dry_run' + " {
|
|
print " + '$"Would install: ($plugin) → ($bin_path)/($plugin)"' + "
|
|
} else {
|
|
try {
|
|
cp " + '$plugin' + " " + '$"($bin_path)/($plugin)"' + "
|
|
chmod +x " + '$"($bin_path)/($plugin)"' + "
|
|
print " + '$" ✅ Installed ($plugin)"' + "
|
|
} catch {|err|
|
|
print " + '$" ❌ Failed to install ($plugin): ($err.msg)"' + "
|
|
}
|
|
}
|
|
}
|
|
|
|
if not " + '$dry_run' + " {
|
|
print \"\\n💡 Don't forget to run 'plugin add' for each plugin in nushell!\"
|
|
}
|
|
}
|
|
"
|
|
|
|
$install_script_content | save --force ($target_path | path join $install_file)
|
|
chmod +x ($target_path | path join $install_file)
|
|
print $"📜 Created installation script: ($install_file)"
|
|
}
|
|
|
|
# Main function
|
|
def main [
|
|
--target-path (-t): string = "" # Override target path
|
|
--platform (-p): string = "" # Specific platform to collect (e.g., linux-amd64)
|
|
--all-platforms (-a) # Collect all available platforms
|
|
--force (-f) # Force overwrite existing files
|
|
--list (-l) # List available plugins only
|
|
--list-platforms # List available platforms
|
|
] {
|
|
# Ensure we're in the repository root directory
|
|
if not ("nu_plugin_clipboard" | path exists) {
|
|
error make {msg: "Please run this script from the nushell-plugins repository root directory"}
|
|
}
|
|
|
|
print "📦 Nushell Plugin Collection & Installation Preparation"
|
|
|
|
# Load environment variables
|
|
let env_vars = load_env_vars
|
|
let base_target_path = if ($target_path | str length) > 0 { $target_path } else { $env_vars.TARGET_PATH? | default "distribution" }
|
|
let install_file = $env_vars.INSTALL_FILE? | default "install_nu_plugins.nu"
|
|
|
|
# List platforms mode
|
|
if $list_platforms {
|
|
let available = get_available_targets
|
|
if ($available | length) == 0 {
|
|
print "❓ No built platforms found"
|
|
print "💡 Run cross-compilation builds first"
|
|
} else {
|
|
print "📊 Available built platforms:"
|
|
for target in $available {
|
|
print $" ✅ ($target.name) ($target.platform_name): ($target.count) plugins"
|
|
print $" ($target.description)"
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
# Determine platforms to collect
|
|
let available_targets = get_available_targets
|
|
let host_info = get_host_info
|
|
|
|
let platforms_to_collect = if $all_platforms {
|
|
$available_targets
|
|
} else if ($platform | str length) > 0 {
|
|
# Handle "host" as a special case - map to actual platform
|
|
let target_to_find = if ($platform == "host") { $host_info.full } else { $platform }
|
|
let selected = $available_targets | where name == $target_to_find
|
|
if ($selected | length) == 0 {
|
|
print $"❌ Platform not found: ($platform)"
|
|
print $"💡 Available platforms: ($available_targets | get name | str join ', ')"
|
|
exit 1
|
|
}
|
|
$selected
|
|
} else {
|
|
# Default to host platform if available
|
|
let host_info = get_host_info
|
|
let host_target = $available_targets | where name == $host_info.full
|
|
if ($host_target | length) > 0 {
|
|
$host_target
|
|
} else {
|
|
# Fallback to first available platform
|
|
$available_targets | first 1
|
|
}
|
|
}
|
|
|
|
if ($platforms_to_collect | length) == 0 {
|
|
print "❓ No platforms to collect"
|
|
print "💡 Build plugins first with: just build or just build-cross-all"
|
|
exit 1
|
|
}
|
|
|
|
print $"🎯 Platforms to collect: ($platforms_to_collect | length)"
|
|
for platform in $platforms_to_collect {
|
|
print $" - ($platform.name): ($platform.count) plugins"
|
|
}
|
|
|
|
# Process each platform
|
|
mut total_collected = 0
|
|
for platform_info in $platforms_to_collect {
|
|
let platform_name = $platform_info.name
|
|
let plugins = get_built_plugins $platform_name
|
|
|
|
if $list {
|
|
if ($plugins | length) == 0 {
|
|
print $"❓ No built plugins found for ($platform_name)"
|
|
} else {
|
|
print $"\n📦 ($platform_name) - ($plugins | length) built plugins:"
|
|
for plugin in $plugins {
|
|
print $" ✅ ($plugin.name) (($plugin.size)) from ($plugin.source_dir)"
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
|
|
if ($plugins | length) == 0 {
|
|
print $"⚠️ No plugins found for platform: ($platform_name)"
|
|
continue
|
|
}
|
|
|
|
# Create platform-specific directory structure
|
|
let platform_target_path = if $all_platforms {
|
|
$"($base_target_path)/($platform_name)"
|
|
} else {
|
|
$base_target_path
|
|
}
|
|
|
|
print $"\n📦 Collecting ($plugins | length) plugins for ($platform_name)..."
|
|
print $"📁 Target: ($platform_target_path)"
|
|
|
|
# Check if target exists and handle accordingly
|
|
if ($platform_target_path | path exists) and not $force {
|
|
print $"⚠️ Target directory '($platform_target_path)' already exists"
|
|
let confirm = input "Continue and overwrite? [y/N]: "
|
|
if ($confirm | str downcase) != "y" {
|
|
print "❌ Skipping ($platform_name)"
|
|
continue
|
|
}
|
|
}
|
|
|
|
# Create target structure
|
|
create_target_structure $platform_target_path
|
|
|
|
# Copy plugins
|
|
copy_plugins $plugins $platform_target_path
|
|
|
|
# Copy additional files
|
|
print "📄 Copying additional files..."
|
|
copy_additional_files $platform_target_path
|
|
|
|
# Create platform-specific installation script
|
|
create_install_script $platform_target_path $install_file
|
|
|
|
$total_collected = $total_collected + ($plugins | length)
|
|
|
|
print $"✅ Collected ($plugins | length) plugins for ($platform_name)"
|
|
}
|
|
|
|
# List mode summary
|
|
if $list {
|
|
return
|
|
}
|
|
|
|
# Summary
|
|
print $"\n🎉 Collection completed!"
|
|
print $"📁 Base directory: ($base_target_path)"
|
|
print $"📦 Total plugins collected: ($total_collected)"
|
|
print $"🎯 Platforms: ($platforms_to_collect | get name | str join ', ')"
|
|
|
|
print "\n💡 Next steps:"
|
|
if $all_platforms {
|
|
print " 1. Package all platforms: just pack-cross"
|
|
print " 2. Test individual platforms: cd distribution/PLATFORM && nu install_nu_plugins.nu --dry-run"
|
|
} else {
|
|
let final_path = if $all_platforms { $"($base_target_path)/($platforms_to_collect.0.name)" } else { $base_target_path }
|
|
print $" 1. Test installation: cd ($final_path) && nu ($install_file) --dry-run"
|
|
print $" 2. Package for distribution: just pack"
|
|
print $" 3. Install locally: cd ($final_path) && nu ($install_file)"
|
|
}
|
|
}
|
|
|
|
if ($env.NUSHELL_EXECUTION_CONTEXT? | default "" | str contains "run") {
|
|
main
|
|
} |