diff --git a/distribution/.gitignore b/distribution/.gitignore
deleted file mode 100644
index 9c0d8ae..0000000
--- a/distribution/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-target
-nu
-nu_plugin_*
diff --git a/distribution/LICENSE b/distribution/LICENSE
deleted file mode 100644
index 1ecbafd..0000000
--- a/distribution/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 - 2025 The Nushell Project Developers
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/distribution/README b/distribution/README
deleted file mode 100644
index 356c39c..0000000
--- a/distribution/README
+++ /dev/null
@@ -1,3 +0,0 @@
-To use Nu plugins, use the register command to tell Nu where to find the plugin. For example:
-
-> register ./nu_plugin_query
\ No newline at end of file
diff --git a/distribution/collect-install.sh b/distribution/collect-install.sh
deleted file mode 100755
index 8647f18..0000000
--- a/distribution/collect-install.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash
-
-[ -r ../env ] && . ../env
-[ -r env ] && . ./env
-
-[ -z "$INSTALL_FILE" ] && echo "Check env values && exit 1
-[ -z "$INSTALL_BIN_PATH" ] && echo "Check env values && exit 1
-
-echo "------------------------------"
-echo "Collect binaries from $TARGET_PATH ... "
-echo "------------------------------"
-
-[ -r ../nushell/target/release/nu ] && cp -v ../nushell/target/release/nu .
-
-cp -v ../nu_plugin_*/target/release/nu_plugin_* .
-rm -f nu_plugin_*.d
-
-echo "------------------------------"
-echo "Generate installer for nushell in $INSTALL_FILE ..."
-echo "------------------------------"
-echo "#!/usr/bin/env nu" > $INSTALL_FILE
-for plgn in $(ls -d nu_plugin_*)
-do
- echo "plugin add $INSTALL_BIN_PATH/$plgn ">>$INSTALL_FILE
- echo "$plgn"
-done
-chmod +x $INSTALL_FILE
-
-[ -x "install.sh" ] && ./install.sh
diff --git a/distribution/install.sh b/distribution/install.sh
deleted file mode 100755
index 336792b..0000000
--- a/distribution/install.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-[ -r ../env ] && . ../env
-[ -r env ] && . ./env
-
-[ -z "$INSTALL_FILE" ] && echo "Check env values && exit 1
-[ -z "$INSTALL_BIN_PATH" ] && echo "Check env values && exit 1
-
-echo "------------------------------"
-echo "Install nu plugins in $INSTALL_BIN_PATH ..."
-echo "------------------------------"
-[ -r nu ] && cp -v nu $INSTALL_BIN_PATH
-cp -pv nu_plugin* $INSTALL_BIN_PATH
-
-if [ -x "$INSTALL_FILE" ] ; then
- echo "------------------------------"
- echo "To add plugins to Nushell run: "
- echo "./$INSTALL_FILE"
-fi
-if [ -x "./kcl-install.sh" ] ; then
- echo "------------------------------"
- echo "Install KCL for nu_plugin_kcl as CLI wrapper "
- ./kcl-install.sh
-fi
-
diff --git a/distribution/install_nu_plugins.nu b/distribution/install_nu_plugins.nu
deleted file mode 100755
index 7eb982c..0000000
--- a/distribution/install_nu_plugins.nu
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env nu
-plugin add /usr/local/bin/nu_plugin_clipboard
-plugin add /usr/local/bin/nu_plugin_desktop_notifications
-plugin add /usr/local/bin/nu_plugin_hashes
-plugin add /usr/local/bin/nu_plugin_highlight
-plugin add /usr/local/bin/nu_plugin_image
-plugin add /usr/local/bin/nu_plugin_kcl
-plugin add /usr/local/bin/nu_plugin_port_extension
-plugin add /usr/local/bin/nu_plugin_qr_maker
-plugin add /usr/local/bin/nu_plugin_tera
diff --git a/distribution/kcl-install.sh b/distribution/kcl-install.sh
deleted file mode 100755
index 073fdf0..0000000
--- a/distribution/kcl-install.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-
-[ -r env ] && . ./env
-[ -r ../env ] && . ../env
-
-# KCL_VERSION="0.11.2"
-KCL_SOURCE="https://github.com/kcl-lang/cli/releases"
-KCL_TAGS="https://github.com/kcl-lang/cli/tags"
-KCL_SITE="https://kcl-lang.io"
-
-export INSTALL_BIN_PATH=${INSTALL_BIN_PATH:-/usr/local/bin}
-
-if [ -z "$KCL_VERSION" ] ; then
- echo "KCL_VERSION not set in env"
- exit 1
-fi
-if [ "$1" == "check" ] ; then
- CHECK_ONLY="yes"
-fi
-OS="$(uname | tr '[:upper:]' '[:lower:]')"
-ORG_OS=$(uname)
-ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
-ORG_ARCH="$(uname -m)"
-
-has_kcl=$(type -P kcl)
-num_version=0
-[ -n "$has_kcl" ] && kcl_version=$(kcl -v | cut -f3 -d" " | sed 's/ //g') && num_version=${kcl_version//\./}
-expected_version_num=${KCL_VERSION//\./}
-[ -z "$num_version" ] && num_version=0
-if [ -z "$CHECK_ONLY" ] && [ "$num_version" -lt "$expected_version_num" ] ; then
- curl -fsSLO "https://github.com/kcl-lang/cli/releases/download/v${KCL_VERSION}/kcl-v${KCL_VERSION}-${OS}-${ARCH}.tar.gz" &&
- tar -xzf "kcl-v${KCL_VERSION}-${OS}-${ARCH}.tar.gz" &&
- sudo mv kcl $INSTALL_BIN_PATH &&
- rm -f "kcl-v${KCL_VERSION}-${OS}-${ARCH}.tar.gz" &&
- printf "%s\t%s\n" "kcl" "installed $KCL_VERSION"
-elif [ -n "$CHECK_ONLY" ] ; then
- printf "%s\t%s\t%s\n" "kcl" "$kcl_version" "expected $KCL_VERSION"
-else
- printf "%s\t%s\n" "kcl" "already $KCL_VERSION"
-fi
diff --git a/justfile b/justfile
index fe98b00..52160e9 100644
--- a/justfile
+++ b/justfile
@@ -1,256 +1,55 @@
# Nushell Plugins Development Justfile
-# Convenient recipes for common development tasks
+# Modular task runner with organized command categories
# Set shell to bash for compatibility
set shell := ["bash", "-c"]
-# Default recipe - show help
+# Import all module justfiles
+import 'justfiles/alias.just'
+import 'justfiles/help.just'
+import 'justfiles/build.just'
+import 'justfiles/distro.just'
+import 'justfiles/upstream.just'
+import 'justfiles/qa.just'
+import 'justfiles/tools.just'
+
+# Default recipe - show modular help
+[no-cd]
default:
- @just --list
+ @just help
-# ๐ Version Validation Commands
-# Check nushell version consistency
-validate-nushell:
- @echo "๐ Validating nushell version consistency..."
- @./scripts/run.sh --check-only
-
-# Fix nushell version mismatches
-fix-nushell:
- @echo "๐ง Fixing nushell version mismatches..."
- @./scripts/run.sh --fix --check-only
-
-# ๐ Status and Information Commands
+# ๐ CORE STATUS COMMANDS (Most frequently used)
# Show plugin status dashboard
+[no-cd]
status:
@echo "๐ Plugin Status Dashboard"
- @./scripts/run.sh plugin_status.nu
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu
# Show detailed status for all plugins
+[no-cd]
status-all:
@echo "๐ All Plugins Status"
- @./scripts/run.sh plugin_status.nu --all
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu --all
# Show plugins requiring attention
+[no-cd]
status-attention:
@echo "๐จ Plugins Requiring Attention"
- @./scripts/run.sh plugin_status.nu attention
-
-# Show summary only
-status-summary:
- @echo "๐ Quick Summary"
- @./scripts/run.sh plugin_status.nu summary
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu attention
# Update plugin status manually
+[no-cd]
status-update PLUGIN STATUS:
@echo "๐ Updating {{PLUGIN}} status to {{STATUS}}..."
- @./scripts/run.sh plugin_status.nu update {{PLUGIN}} {{STATUS}}
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu update {{PLUGIN}} {{STATUS}}
-# Mark local development plugins as OK
-status-mark-locals-ok:
- @echo "โ
Marking local development plugins as OK..."
- @./scripts/run.sh plugin_status.nu update nu_plugin_image ok
- @./scripts/run.sh plugin_status.nu update nu_plugin_hashes ok
- @./scripts/run.sh plugin_status.nu update nu_plugin_desktop_notifications ok
- @echo "โ
All local plugins marked as OK"
+# ๐ฏ MULTI-MODULE WORKFLOW COMMANDS
+# These workflows combine commands from multiple modules
-# ๐ Upstream Tracking Commands
-
-# Check upstream changes for all plugins
-upstream-check:
- @echo "๐ Checking upstream changes..."
- @./scripts/run.sh check_upstream_changes.nu
-
-# Check upstream for specific plugin
-upstream-check-plugin PLUGIN:
- @echo "๐ Checking upstream for {{PLUGIN}}..."
- @./scripts/run.sh check_upstream_changes.nu --plugin {{PLUGIN}}
-
-# Preview merge changes for a plugin
-upstream-preview PLUGIN:
- @echo "๐ Preview merge for {{PLUGIN}}..."
- @./scripts/run.sh safe_merge_upstream.nu --preview {{PLUGIN}}
-
-# Safely merge upstream changes for a plugin
-upstream-merge PLUGIN:
- @echo "๐ Merging upstream changes for {{PLUGIN}}..."
- @./scripts/run.sh safe_merge_upstream.nu {{PLUGIN}}
-
-# Merge all pending upstream changes
-upstream-merge-all:
- @echo "๐ Merging all pending upstream changes..."
- @./scripts/run.sh safe_merge_upstream.nu --all
-
-# Force merge upstream for a plugin (even if status is OK)
-upstream-merge-force PLUGIN:
- @echo "๐ช Force merging {{PLUGIN}}..."
- @./scripts/run.sh safe_merge_upstream.nu --force {{PLUGIN}}
-
-# ๐ง Development Commands
-
-# Build all plugins
-build:
- @echo "๐จ Building all plugins..."
- @./scripts/run.sh build_all.nu
-
-# Build all plugins with verbose output
-build-verbose:
- @echo "๐จ Building all plugins (verbose)..."
- @./scripts/run.sh build_all.nu --verbose
-
-# Build all plugins in parallel (experimental)
-build-parallel:
- @echo "โก Building all plugins in parallel..."
- @./scripts/run.sh build_all.nu --parallel
-
-# Create a new plugin from template
-make-plugin PLUGIN_NAME:
- @echo "๐ Creating new plugin: {{PLUGIN_NAME}}"
- @./scripts/run.sh make_plugin.nu {{PLUGIN_NAME}}
-
-# Update nu dependency versions
-update-nu-versions:
- @echo "๐ Updating nu dependency versions..."
- @./scripts/run.sh update_nu_versions.nu
-
-# List current nu dependency versions
-list-nu-versions:
- @echo "๐ Current nu dependency versions:"
- @./scripts/run.sh update_nu_versions.nu list
-
-# Update nushell submodule
-update-nushell:
- @echo "๐ Updating nushell submodule..."
- @bash scripts/sh/update_nushell.sh update
-
-# ๐ฆ Distribution Commands
-
-# Collect built plugins for distribution
-collect:
- @echo "๐ฆ Collecting plugins for distribution..."
- @./scripts/run.sh collect_install.nu
-
-# List available built plugins
-collect-list:
- @echo "๐ Available built plugins:"
- @./scripts/run.sh collect_install.nu --list
-
-# Create distribution package
-pack:
- @echo "๐ฆ Creating distribution package..."
- @./scripts/run.sh pack_dist.nu
-
-# Show what would be packaged
-pack-list:
- @echo "๐ Files that would be packaged:"
- @./scripts/run.sh pack_dist.nu --list
-
-# ๐งช Testing and Quality Commands
-
-# Run cargo check on all plugins
-check:
- @echo "๐ Running cargo check on all plugins..."
- @for plugin in nu_plugin_*; do \
- if [ -d "$$plugin" ]; then \
- echo "Checking $$plugin..."; \
- cd "$$plugin" && cargo check && cd ..; \
- fi; \
- done
-
-# Run cargo test on all plugins
-test:
- @echo "๐งช Running tests on all plugins..."
- @for plugin in nu_plugin_*; do \
- if [ -d "$$plugin" ]; then \
- echo "Testing $$plugin..."; \
- cd "$$plugin" && cargo test && cd ..; \
- fi; \
- done
-
-# Run cargo clippy on all plugins
-lint:
- @echo "๐ Running clippy on all plugins..."
- @for plugin in nu_plugin_*; do \
- if [ -d "$$plugin" ]; then \
- echo "Linting $$plugin..."; \
- cd "$$plugin" && cargo clippy -- -D warnings && cd ..; \
- fi; \
- done
-
-# Format all Rust code
-fmt:
- @echo "๐จ Formatting Rust code..."
- @for plugin in nu_plugin_*; do \
- if [ -d "$$plugin" ]; then \
- echo "Formatting $$plugin..."; \
- cd "$$plugin" && cargo fmt && cd ..; \
- fi; \
- done
-
-# ๐ Security and Maintenance Commands
-
-# Run cargo audit on all plugins
-audit:
- @echo "๐ Running security audit..."
- @for plugin in nu_plugin_*; do \
- if [ -d "$$plugin" ]; then \
- echo "Auditing $$plugin..."; \
- cd "$$plugin" && cargo audit && cd ..; \
- fi; \
- done
-
-# Update all dependencies (careful!)
-update-deps:
- @echo "โฌ๏ธ Updating dependencies (this may break things)..."
- @for plugin in nu_plugin_*; do \
- if [ -d "$$plugin" ]; then \
- echo "Updating deps in $$plugin..."; \
- cd "$$plugin" && cargo update && cd ..; \
- fi; \
- done
-
-# Clean all build artifacts
-clean:
- @echo "๐งน Cleaning build artifacts..."
- @for plugin in nu_plugin_*; do \
- if [ -d "$$plugin" ]; then \
- echo "Cleaning $$plugin..."; \
- cd "$$plugin" && cargo clean && cd ..; \
- fi; \
- done
-
-# ๐ Plugin-specific Commands
-
-# Run command on specific plugin
-plugin PLUGIN CMD:
- @echo "๐ง Running '{{CMD}}' on {{PLUGIN}}"
- @cd {{PLUGIN}} && {{CMD}}
-
-# Build specific plugin
-build-plugin PLUGIN:
- @echo "๐จ Building {{PLUGIN}}..."
- @cd {{PLUGIN}} && cargo build --release
-
-# Test specific plugin
-test-plugin PLUGIN:
- @echo "๐งช Testing {{PLUGIN}}..."
- @cd {{PLUGIN}} && cargo test
-
-# Check specific plugin
-check-plugin PLUGIN:
- @echo "๐ Checking {{PLUGIN}}..."
- @cd {{PLUGIN}} && cargo check
-
-# Install specific plugin locally
-install-plugin PLUGIN:
- @echo "๐ฅ Installing {{PLUGIN}} locally..."
- @cd {{PLUGIN}} && cargo build --release
- @echo "To add to nushell: plugin add ./{{PLUGIN}}/target/release/{{PLUGIN}}"
-
-# ๐ฏ Workflow Commands
-
-# Complete development workflow: check version, upstream, build, test
+# Complete development workflow: validate โ upstream check โ build โ test โ status
+[no-cd]
dev-flow:
@echo "๐ฏ Running complete development workflow..."
@just validate-nushell
@@ -259,7 +58,8 @@ dev-flow:
@just test
@just status
-# Complete release workflow: check version, build, collect, package
+# Complete release workflow: validate โ build โ collect โ package
+[no-cd]
release-flow:
@echo "๐ Running complete release workflow..."
@just validate-nushell
@@ -267,15 +67,29 @@ release-flow:
@just collect
@just pack
-# Quality check workflow: check version, format, lint, test
-quality-flow:
- @echo "โจ Running quality check workflow..."
+# Cross-platform development workflow
+[no-cd]
+dev-flow-cross:
+ @echo "๐ Running cross-platform development workflow..."
@just validate-nushell
- @just fmt
- @just lint
- @just test
+ @just upstream-check
+ @just build-cross-all
+ @just status
-# Update workflow: update nushell, fix version, update versions, check upstream
+# CI simulation workflow (what GitHub Actions will run)
+[no-cd]
+ci-flow:
+ @echo "๐ค Simulating CI workflow..."
+ @just validate-nushell
+ @just fmt-check
+ @just lint
+ @just build-cross-all
+ @just test
+ @just collect-all
+ @just pack-checksums
+
+# Update workflow: update nushell โ fix version โ update versions โ check upstream
+[no-cd]
update-flow:
@echo "๐ Running update workflow..."
@just update-nushell
@@ -283,140 +97,3 @@ update-flow:
@just update-nu-versions
@just upstream-check
-# ๐ Help and Information
-
-# Show plugin registry information
-registry:
- @echo "๐ Plugin Registry Information:"
- @if [ -f etc/plugin_registry.toml ]; then \
- echo "Registry file: etc/plugin_registry.toml"; \
- echo ""; \
- echo "Plugins with upstream:"; \
- grep -A2 "upstream_url.*=" etc/plugin_registry.toml | grep -v "^--" || true; \
- else \
- echo "Registry file not found!"; \
- fi
-
-# Manage upstream exclusions
-exclude PLUGIN ACTION="add":
- #!/usr/bin/env bash
- EXCLUDE_FILE="etc/upstream_exclude.toml"
- if [ "$ACTION" = "add" ]; then
- echo "๐ซ Adding {{PLUGIN}} to exclusion list..."
- # This is a simplified version - you might want to use a proper TOML parser
- if grep -q "^plugins = \[" "$EXCLUDE_FILE"; then
- sed -i.bak "/^plugins = \[/s/\]/\"{{PLUGIN}}\", \]/" "$EXCLUDE_FILE"
- echo "โ
Added {{PLUGIN}} to exclusions"
- else
- echo "โ ๏ธ Please manually add {{PLUGIN}} to $EXCLUDE_FILE"
- fi
- elif [ "$ACTION" = "remove" ]; then
- echo "โ
Removing {{PLUGIN}} from exclusion list..."
- sed -i.bak "s/\"{{PLUGIN}}\",*[[:space:]]*//" "$EXCLUDE_FILE"
- echo "โ
Removed {{PLUGIN}} from exclusions"
- elif [ "$ACTION" = "list" ]; then
- echo "๐ Currently excluded plugins:"
- if [ -f "$EXCLUDE_FILE" ]; then
- grep -A10 "\[exclude\]" "$EXCLUDE_FILE" | grep -E "^[[:space:]]*\"" | sed 's/[",]//g' | sed 's/^[[:space:]]*/ - /'
- else
- echo "No exclusions file found"
- fi
- else
- echo "โ Unknown action: $ACTION"
- echo "Usage: just exclude PLUGIN [add|remove|list]"
- fi
-
-# Show excluded plugins
-exclude-list:
- @just exclude "" list
-
-# Show environment configuration
-env-info:
- @echo "๐ Environment Configuration:"
- @if [ -f env ]; then \
- cat env; \
- else \
- echo "No env file found"; \
- fi
-
-# Show system information
-system-info:
- @echo "๐ป System Information:"
- @echo "OS: $$(uname -s)"
- @echo "Architecture: $$(uname -m)"
- @echo "Nushell: $$(nu --version 2>/dev/null || echo 'Not installed')"
- @echo "Rust: $$(rustc --version 2>/dev/null || echo 'Not installed')"
- @echo "Cargo: $$(cargo --version 2>/dev/null || echo 'Not installed')"
- @echo "Just: $$(just --version 2>/dev/null || echo 'Not installed')"
-
-# Validate setup and dependencies
-validate:
- @echo "โ
Validating setup..."
- @echo "Checking required tools:"
- @command -v nu >/dev/null 2>&1 && echo "โ
nushell" || echo "โ nushell (required)"
- @command -v cargo >/dev/null 2>&1 && echo "โ
cargo" || echo "โ cargo (required)"
- @command -v git >/dev/null 2>&1 && echo "โ
git" || echo "โ git (required)"
- @command -v just >/dev/null 2>&1 && echo "โ
just" || echo "โ just (optional but recommended)"
- @echo ""
- @echo "Checking directory structure:"
- @[ -d scripts ] && echo "โ
scripts directory" || echo "โ scripts directory"
- @[ -d etc ] && echo "โ
etc directory" || echo "โ etc directory"
- @[ -f etc/plugin_registry.toml ] && echo "โ
plugin registry" || echo "โ plugin registry"
- @[ -f etc/upstream_exclude.toml ] && echo "โ
upstream exclusions" || echo "โ ๏ธ upstream exclusions (optional)"
- @[ -f env ] && echo "โ
env file" || echo "โ ๏ธ env file (optional)"
- @echo ""
- @echo "Plugin directories:"
- @ls -d nu_plugin_* 2>/dev/null | wc -l | xargs echo "๐ฆ Found plugins:"
-
-# ๐ Documentation Commands
-
-# Generate plugin documentation
-docs:
- @echo "๐ Generating documentation..."
- @for plugin in nu_plugin_*; do \
- if [ -d "$$plugin" ]; then \
- echo "Generating docs for $$plugin..."; \
- cd "$$plugin" && cargo doc --no-deps && cd ..; \
- fi; \
- done
-
-# Open documentation in browser
-docs-open PLUGIN:
- @echo "๐ Opening documentation for {{PLUGIN}}..."
- @cd {{PLUGIN}} && cargo doc --open
-
-# ๐งฐ Advanced Commands
-
-# Interactive plugin selection (requires fzf)
-interactive:
- #!/usr/bin/env bash
- if command -v fzf >/dev/null 2>&1; then
- echo "๐ฏ Interactive Plugin Selection"
- PLUGIN=$(ls -d nu_plugin_* | fzf --prompt="Select plugin: ")
- if [ -n "$PLUGIN" ]; then
- ACTION=$(echo -e "build\ntest\ncheck\nlint\nupstream-check\nupstream-merge\ninstall" | fzf --prompt="Select action: ")
- if [ -n "$ACTION" ]; then
- case $ACTION in
- "upstream-check") just upstream-check-plugin $PLUGIN ;;
- "upstream-merge") just upstream-merge $PLUGIN ;;
- "build") just build-plugin $PLUGIN ;;
- "test") just test-plugin $PLUGIN ;;
- "check") just check-plugin $PLUGIN ;;
- "lint") cd $PLUGIN && cargo clippy ;;
- "install") just install-plugin $PLUGIN ;;
- esac
- fi
- fi
- else
- echo "โ fzf not installed. Install with: brew install fzf (macOS) or apt install fzf (Ubuntu)"
- fi
-
-# Watch for changes and rebuild (requires entr)
-watch PLUGIN:
- #!/usr/bin/env bash
- if command -v entr >/dev/null 2>&1; then
- echo "๐ Watching {{PLUGIN}} for changes..."
- find {{PLUGIN}}/src -name "*.rs" | entr just build-plugin {{PLUGIN}}
- else
- echo "โ entr not installed. Install with: brew install entr (macOS) or apt install entr (Ubuntu)"
- fi
\ No newline at end of file
diff --git a/justfiles/alias.just b/justfiles/alias.just
new file mode 100644
index 0000000..8bc9c8c
--- /dev/null
+++ b/justfiles/alias.just
@@ -0,0 +1,14 @@
+# Alias Module - Quick Access Shortcuts
+# Short aliases for commonly used commands
+
+# Help alias for quick access to help system
+alias h := help
+
+# Build alias for quick compilation
+alias b := build
+
+# Build alias to collect targets
+alias c := collect
+
+# Status alias for quick status check
+alias s := status
diff --git a/justfiles/build.just b/justfiles/build.just
new file mode 100644
index 0000000..fab4791
--- /dev/null
+++ b/justfiles/build.just
@@ -0,0 +1,159 @@
+# Build Module - Native and Cross-Platform Building
+# Commands for building plugins natively and for multiple platforms
+
+# ๐จ NATIVE BUILD COMMANDS
+
+# Build all plugins for current platform
+[no-cd]
+build:
+ @echo "๐จ Building all plugins..."
+ @{{justfile_directory()}}/scripts/run.sh build_all.nu
+
+# Build all plugins with verbose output
+[no-cd]
+build-verbose:
+ @echo "๐จ Building all plugins (verbose)..."
+ @{{justfile_directory()}}/scripts/run.sh build_all.nu --verbose
+
+# Build all plugins in parallel (experimental)
+[no-cd]
+build-parallel:
+ @echo "โก Building all plugins in parallel..."
+ @{{justfile_directory()}}/scripts/run.sh build_all.nu --parallel
+
+# Build specific plugin
+[no-cd]
+build-plugin PLUGIN:
+ @echo "๐จ Building {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo build --release
+
+# ๐ฏ CROSS-COMPILATION COMMANDS
+
+# List available build targets
+[no-cd]
+build-targets:
+ @echo "๐ Available build targets:"
+ @{{justfile_directory()}}/scripts/run.sh build_cross.nu --list-targets
+
+# Build for specific target
+[no-cd]
+build-cross TARGET:
+ @echo "๐ฏ Cross-compiling for {{TARGET}}..."
+ @{{justfile_directory()}}/scripts/run.sh build_cross.nu --targets {{TARGET}}
+
+# Build for all supported targets
+[no-cd]
+build-cross-all:
+ @echo "๐ Cross-compiling for all targets..."
+ @{{justfile_directory()}}/scripts/run.sh build_cross.nu --all-targets
+
+# Build for all targets in parallel
+[no-cd]
+build-cross-parallel:
+ @echo "โก Cross-compiling for all targets in parallel..."
+ @{{justfile_directory()}}/scripts/run.sh build_cross.nu --all-targets --parallel
+
+# Build for specific target with Docker
+[no-cd]
+build-docker TARGET:
+ @echo "๐ณ Building {{TARGET}} with Docker..."
+ @{{justfile_directory()}}/scripts/run.sh build_cross.nu --targets {{TARGET}} --docker
+
+# Force native compilation for target
+[no-cd]
+build-native TARGET:
+ @echo "๐ Building {{TARGET}} natively..."
+ @{{justfile_directory()}}/scripts/run.sh build_cross.nu --targets {{TARGET}} --native
+
+# ๐ณ DOCKER BUILD COMMANDS
+
+# Build Docker cross-compilation image
+[no-cd]
+build-docker-image:
+ @echo "๐ณ Building Docker cross-compilation image..."
+ @{{justfile_directory()}}/scripts/run.sh build_docker_cross.nu --build-image
+
+# Force rebuild Docker image from scratch
+[no-cd]
+build-docker-image-fresh:
+ @echo "๐ณ Rebuilding Docker image from scratch..."
+ @{{justfile_directory()}}/scripts/run.sh build_docker_cross.nu --build-image --force-rebuild --no-cache
+
+# Show Docker environment info
+[no-cd]
+build-docker-info:
+ @echo "๐ณ Docker environment information:"
+ @{{justfile_directory()}}/scripts/run.sh build_docker_cross.nu --info
+
+# Build specific plugin with Docker
+build-docker-plugin PLUGIN TARGET:
+ @echo "๐ณ Building {{PLUGIN}} for {{TARGET}} with Docker..."
+ @{{justfile_directory()}}/scripts/run.sh build_docker_cross.nu --plugin {{PLUGIN}} --target {{TARGET}}
+
+# Clean up Docker artifacts
+[no-cd]
+build-docker-cleanup:
+ @echo "๐งน Cleaning up Docker artifacts..."
+ @{{justfile_directory()}}/scripts/run.sh build_docker_cross.nu --cleanup
+
+# ๐งน BUILD MAINTENANCE
+
+# Clean all build artifacts
+[no-cd]
+build-clean:
+ @echo "๐งน Cleaning build artifacts..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Cleaning $$plugin..."; \
+ cd "$$plugin" && cargo clean && cd ..; \
+ fi; \
+ done
+
+# Update all dependencies (careful!)
+[no-cd]
+build-update-deps:
+ @echo "โฌ๏ธ Updating dependencies (this may break things)..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Updating deps in $$plugin..."; \
+ cd "$$plugin" && cargo update && cd ..; \
+ fi; \
+ done
+
+# ๐ BUILD INFORMATION
+
+# Show build help
+[no-cd]
+build-help:
+ @echo "๐จ Build Module Help"
+ @echo "==================="
+ @echo ""
+ @echo "NATIVE BUILDS:"
+ @echo " build - Build all plugins for current platform"
+ @echo " build-verbose - Build with verbose output"
+ @echo " build-parallel - Build in parallel (experimental)"
+ @echo " build-plugin PLUGIN - Build specific plugin"
+ @echo ""
+ @echo "CROSS-COMPILATION:"
+ @echo " build-targets - List available targets"
+ @echo " build-cross TARGET - Build for specific target"
+ @echo " build-cross-all - Build for all targets"
+ @echo " build-cross-parallel - Build all targets in parallel"
+ @echo " build-docker TARGET - Build with Docker"
+ @echo " build-native TARGET - Force native compilation"
+ @echo ""
+ @echo "DOCKER:"
+ @echo " build-docker-image - Build Docker image"
+ @echo " build-docker-image-fresh - Rebuild Docker image"
+ @echo " build-docker-info - Show Docker info"
+ @echo " build-docker-plugin PLUGIN TARGET - Build plugin with Docker"
+ @echo " build-docker-cleanup - Clean Docker artifacts"
+ @echo ""
+ @echo "MAINTENANCE:"
+ @echo " build-clean - Clean all artifacts"
+ @echo " build-update-deps - Update dependencies"
+ @echo ""
+ @echo "EXAMPLES:"
+ @echo " just build-cross linux-amd64"
+ @echo " just build-docker linux-arm64"
+ @echo " just build-plugin nu_plugin_clipboard"
diff --git a/justfiles/distro.just b/justfiles/distro.just
new file mode 100644
index 0000000..bd53a9e
--- /dev/null
+++ b/justfiles/distro.just
@@ -0,0 +1,250 @@
+# Distribution Module - Collection and Packaging
+# Commands for collecting built plugins and creating distribution packages
+
+# ๐ฆ COLLECTION COMMANDS
+
+# Collect built plugins for distribution
+[no-cd]
+collect:
+ @echo "๐ฆ Collecting plugins for distribution..."
+ @{{justfile_directory()}}/scripts/run.sh collect_install.nu --force
+
+# List available built plugins
+[no-cd]
+collect-list:
+ @echo "๐ Available built plugins:"
+ @{{justfile_directory()}}/scripts/run.sh collect_install.nu --list
+
+# List available platforms for collection
+[no-cd]
+collect-platforms:
+ @echo "๐ Available platforms for collection:"
+ @{{justfile_directory()}}/scripts/run.sh collect_install.nu --list-platforms
+
+# Collect specific platform
+[no-cd]
+collect-platform PLATFORM:
+ @echo "๐ฆ Collecting {{PLATFORM}} plugins..."
+ @{{justfile_directory()}}/scripts/run.sh collect_install.nu --platform {{PLATFORM}}
+
+# Collect all available platforms
+[no-cd]
+collect-all:
+ @echo "๐ Collecting all platforms..."
+ @{{justfile_directory()}}/scripts/run.sh collect_install.nu --all-platforms
+
+# Force collection (overwrite existing)
+[no-cd]
+collect-force:
+ @echo "๐ฆ Force collecting plugins..."
+ @{{justfile_directory()}}/scripts/run.sh collect_install.nu --force
+
+# ๐ PACKAGING COMMANDS
+
+# Create distribution package
+[no-cd]
+pack:
+ @echo "๐ฆ Creating distribution package..."
+ @{{justfile_directory()}}/scripts/run.sh pack_dist.nu --force
+
+# Show what would be packaged
+[no-cd]
+pack-list:
+ @echo "๐ Files that would be packaged:"
+ @{{justfile_directory()}}/scripts/run.sh pack_dist.nu --list
+
+# List available platforms for packaging
+[no-cd]
+pack-platforms:
+ @echo "๐ Available platforms for packaging:"
+ @{{justfile_directory()}}/scripts/run.sh pack_dist.nu --list-platforms
+
+# Package specific platform
+[no-cd]
+pack-platform PLATFORM:
+ @echo "๐ฆ Packaging {{PLATFORM}}..."
+ @{{justfile_directory()}}/scripts/run.sh pack_dist.nu --platform {{PLATFORM}}
+
+# Package all platforms
+[no-cd]
+pack-all:
+ @echo "๐ Packaging all platforms..."
+ @{{justfile_directory()}}/scripts/run.sh pack_dist.nu --all-platforms
+
+# Package with checksums
+[no-cd]
+pack-checksums:
+ @echo "๐ Packaging with checksums..."
+ @{{justfile_directory()}}/scripts/run.sh pack_dist.nu --all-platforms --checksums
+
+# Force packaging (overwrite existing)
+[no-cd]
+pack-force:
+ @echo "๐ฆ Force packaging..."
+ @{{justfile_directory()}}/scripts/run.sh pack_dist.nu --force
+
+# Package to custom output directory
+[no-cd]
+pack-output OUTPUT:
+ @echo "๐ฆ Packaging to {{OUTPUT}}..."
+ @{{justfile_directory()}}/scripts/run.sh pack_dist.nu --output {{OUTPUT}}
+
+# ๐ RELEASE WORKFLOWS
+
+# Complete cross-platform build and package workflow
+[no-cd]
+release-cross:
+ @echo "๐ Complete cross-platform release workflow..."
+ @just validate-nushell
+ @just build-cross-all
+ @just collect-all
+ @just pack-checksums
+
+# Quick release for current platform
+[no-cd]
+release-quick:
+ @echo "๐ Quick release for current platform..."
+ @just validate-nushell
+ @just build
+ @just collect
+ @just pack
+
+# Release with custom target
+[no-cd]
+release-target TARGET:
+ @echo "๐ Release for {{TARGET}}..."
+ @just validate-nushell
+ @just build-cross {{TARGET}}
+ @just collect-platform {{TARGET}}
+ @just pack-platform {{TARGET}}
+
+# ๐ DIRECTORY MANAGEMENT
+
+# Show distribution directory contents
+[no-cd]
+distro-show:
+ @echo "๐ Distribution directory contents:"
+ @if [ -d "distribution" ]; then \
+ find distribution -type f -exec ls -lh {} \; | head -20; \
+ else \
+ echo "No distribution directory found"; \
+ fi
+
+# Show archive directory contents
+[no-cd]
+distro-archives:
+ @echo "๐ Archive directory contents:"
+ @if [ -d "bin_archives" ]; then \
+ ls -lh bin_archives/; \
+ else \
+ echo "No bin_archives directory found"; \
+ fi
+
+# Clean distribution directories
+[no-cd]
+distro-clean:
+ @echo "๐งน Cleaning distribution directories..."
+ @rm -rf distribution bin_archives
+ @echo "โ
Cleaned distribution and bin_archives directories"
+
+# Archive size statistics
+[no-cd]
+distro-stats:
+ @echo "๐ Distribution Statistics:"
+ @if [ -d "bin_archives" ]; then \
+ echo "Archive sizes:"; \
+ du -h bin_archives/* 2>/dev/null | sort -h || echo "No archives found"; \
+ echo ""; \
+ echo "Total archive size:"; \
+ du -sh bin_archives 2>/dev/null || echo "No archives directory"; \
+ else \
+ echo "No bin_archives directory found"; \
+ fi
+
+# ๐ VERIFICATION COMMANDS
+
+# Verify checksums
+[no-cd]
+distro-verify:
+ @echo "๐ Verifying checksums..."
+ @if [ -f "bin_archives/checksums.txt" ]; then \
+ cd bin_archives && sha256sum -c checksums.txt; \
+ else \
+ echo "No checksums file found"; \
+ fi
+
+# Test archive contents
+[no-cd]
+distro-test ARCHIVE:
+ @echo "๐ Testing archive contents: {{ARCHIVE}}"
+ @if [ -f "bin_archives/{{ARCHIVE}}" ]; then \
+ case "{{ARCHIVE}}" in \
+ *.tar.gz) tar -tzf "bin_archives/{{ARCHIVE}}" ;; \
+ *.zip) unzip -l "bin_archives/{{ARCHIVE}}" ;; \
+ *) echo "Unsupported archive format" ;; \
+ esac; \
+ else \
+ echo "Archive not found: bin_archives/{{ARCHIVE}}"; \
+ fi
+
+# Test all archives
+[no-cd]
+distro-test-all:
+ @echo "๐ Testing all archives..."
+ @for archive in bin_archives/*.tar.gz bin_archives/*.zip; do \
+ if [ -f "$$archive" ]; then \
+ echo "Testing $$(basename "$$archive")..."; \
+ case "$$archive" in \
+ *.tar.gz) tar -tzf "$$archive" >/dev/null && echo "โ
OK" || echo "โ FAILED" ;; \
+ *.zip) unzip -t "$$archive" >/dev/null && echo "โ
OK" || echo "โ FAILED" ;; \
+ esac; \
+ fi; \
+ done
+
+# ๐ DISTRIBUTION INFORMATION
+
+# Show distribution help
+[no-cd]
+distro-help:
+ @echo "๐ฆ Distribution Module Help"
+ @echo "=========================="
+ @echo ""
+ @echo "COLLECTION:"
+ @echo " collect - Collect plugins for distribution"
+ @echo " collect-list - List available built plugins"
+ @echo " collect-platforms - List available platforms"
+ @echo " collect-platform PLATFORM - Collect specific platform"
+ @echo " collect-all - Collect all platforms"
+ @echo " collect-force - Force collection (overwrite)"
+ @echo ""
+ @echo "PACKAGING:"
+ @echo " pack - Create distribution package"
+ @echo " pack-list - Show what would be packaged"
+ @echo " pack-platforms - List packaging platforms"
+ @echo " pack-platform PLATFORM - Package specific platform"
+ @echo " pack-all - Package all platforms"
+ @echo " pack-checksums - Package with checksums"
+ @echo " pack-force - Force packaging"
+ @echo " pack-output OUTPUT - Package to custom directory"
+ @echo ""
+ @echo "RELEASE WORKFLOWS:"
+ @echo " release-cross - Complete cross-platform release"
+ @echo " release-quick - Quick release for current platform"
+ @echo " release-target TARGET - Release for specific target"
+ @echo ""
+ @echo "DIRECTORY MANAGEMENT:"
+ @echo " distro-show - Show distribution contents"
+ @echo " distro-archives - Show archive contents"
+ @echo " distro-clean - Clean distribution directories"
+ @echo " distro-stats - Show distribution statistics"
+ @echo ""
+ @echo "VERIFICATION:"
+ @echo " distro-verify - Verify checksums"
+ @echo " distro-test ARCHIVE - Test specific archive"
+ @echo " distro-test-all - Test all archives"
+ @echo ""
+ @echo "EXAMPLES:"
+ @echo " just collect-platform linux-amd64"
+ @echo " just pack-checksums"
+ @echo " just release-cross"
+ @echo " just distro-test linux-amd64-nushell-plugins.tar.gz"
diff --git a/justfiles/help.just b/justfiles/help.just
new file mode 100644
index 0000000..bda08b6
--- /dev/null
+++ b/justfiles/help.just
@@ -0,0 +1,238 @@
+# Help Module - Comprehensive Help System
+# Organized help areas with navigation and guidance
+
+# Show help system with optional area argument
+[no-cd]
+help AREA="":
+ #!/usr/bin/env bash
+ case "{{AREA}}" in
+ "")
+ # Default basic help overview
+ echo "๐ Nushell Plugins Development Environment"
+ echo "========================================"
+ echo ""
+ echo "๐ HELP AREAS - Use: just help "
+ echo "======================================"
+ echo ""
+ echo " modules - Available modules and their commands"
+ echo " status - Status and information commands"
+ echo " get-started - Getting started guide"
+ echo " docs - Documentation and resources"
+ echo ""
+ echo "๐ก QUICK ACCESS:"
+ echo "==============="
+ echo " just h - Short alias for help"
+ echo " just b - Build all plugins (alias for build)"
+ echo " just c - Collect all plugins targets (alias for collect)"
+ echo " just s - Show plugin status (alias for status)"
+ echo " just validate-nushell - Check version consistency (START HERE)"
+ echo " just dev-flow - Complete development workflow"
+ echo ""
+ echo "๐ง Most Common Commands:"
+ echo "======================="
+ echo " just build - Build all plugins"
+ echo " just test - Run all tests"
+ echo " just upstream-check - Check for upstream changes"
+ echo " just release-cross - Cross-platform release"
+ ;;
+ "modules")
+ echo "๐ AVAILABLE MODULES"
+ echo "==================="
+ echo ""
+ echo "๐จ BUILD MODULE"
+ echo " Commands: build, build-cross, build-docker-*"
+ echo " Help: just build-help"
+ echo " Purpose: Native and cross-platform compilation"
+ echo ""
+ echo "๐ฆ DISTRIBUTION MODULE"
+ echo " Commands: collect, pack, release-*"
+ echo " Help: just distro-help"
+ echo " Purpose: Collection and packaging of built plugins"
+ echo ""
+ echo "๐ UPSTREAM MODULE"
+ echo " Commands: upstream-*, status-*"
+ echo " Help: just upstream-help"
+ echo " Purpose: Repository tracking and synchronization"
+ echo ""
+ echo "๐งช QA MODULE"
+ echo " Commands: test, lint, fmt, audit, qa-*"
+ echo " Help: just qa-help"
+ echo " Purpose: Testing, linting, and code quality"
+ echo ""
+ echo "๐ ๏ธ TOOLS MODULE"
+ echo " Commands: validate-*, make-plugin, interactive"
+ echo " Help: just tools-help"
+ echo " Purpose: Development tools and utilities"
+ echo ""
+ echo "๐ก TIP: Use 'just -help' for detailed commands in each module"
+ ;;
+ "status" | "info")
+ echo "๐ STATUS & INFORMATION COMMANDS"
+ echo "================================"
+ echo ""
+ echo "๐ System Status:"
+ echo " just status - Plugin status dashboard"
+ echo " just status-all - Detailed status for all plugins"
+ echo " just status-attention - Plugins requiring attention"
+ echo " just system-info - System information"
+ echo " just validate - Validate setup and dependencies"
+ echo ""
+ echo "๐ Project Information:"
+ echo " just modules - List all available modules"
+ echo " just list-plugins - List all plugins"
+ echo " just stats - Project statistics"
+ echo " just config-list - Show configuration files"
+ echo ""
+ echo "๐ง Version Management:"
+ echo " just validate-nushell - Check nushell version consistency"
+ echo " just list-nu-versions - List current nu dependency versions"
+ echo " just build-targets - List available build targets"
+ ;;
+ "get-started" | "start")
+ echo "๐ก GETTING STARTED GUIDE"
+ echo "========================"
+ echo ""
+ echo "๐ FIRST TIME SETUP:"
+ echo "1. Validate your environment:"
+ echo " just validate # Check tools and setup"
+ echo " just validate-nushell # Check version consistency (CRITICAL)"
+ echo ""
+ echo "2. Check project status:"
+ echo " just status # See plugin status dashboard"
+ echo " just upstream-check # Check for upstream changes"
+ echo ""
+ echo "๐
DAILY DEVELOPMENT WORKFLOW:"
+ echo "1. Run the development workflow:"
+ echo " just dev-flow # validate โ upstream โ build โ test โ status"
+ echo ""
+ echo "2. Or run individual steps:"
+ echo " just validate-nushell # Always start here"
+ echo " just upstream-check # Check for updates"
+ echo " just b # Build all plugins (short alias)"
+ echo " just test # Run tests"
+ echo ""
+ echo "๐ CROSS-PLATFORM BUILD:"
+ echo "1. See available platforms:"
+ echo " just build-targets # List supported platforms"
+ echo ""
+ echo "2. Build for all platforms:"
+ echo " just release-cross # Full cross-platform release"
+ echo ""
+ echo "๐ NEED HELP?"
+ echo " just help modules # See all available modules"
+ echo " just build-help # Build-specific commands"
+ echo " just qa-help # Testing and quality commands"
+ ;;
+ "docs" | "documentation")
+ echo "๐ DOCUMENTATION & RESOURCES"
+ echo "============================"
+ echo ""
+ echo "๐ Main Documentation:"
+ echo " docs/BUILDING.md - Complete build documentation"
+ echo " README.md - Project overview"
+ echo ""
+ echo "โ๏ธ Configuration Files:"
+ echo " etc/plugin_registry.toml - Plugin tracking configuration"
+ echo " etc/build_targets.toml - Cross-compilation targets"
+ echo " etc/upstream_exclude.toml - Upstream exclusion rules"
+ echo ""
+ echo "๐ง Auto-Generated Documentation:"
+ echo " just docs - Generate Rust documentation"
+ echo " just docs-open PLUGIN - Open plugin docs in browser"
+ echo ""
+ echo "๐ก Examples & Help:"
+ echo " just help modules - Module overview"
+ echo " just help get-started - Getting started guide"
+ echo " just -help - Detailed module help"
+ echo ""
+ echo "๐ Online Resources:"
+ echo " Nushell: https://nushell.sh"
+ echo " Rust: https://rust-lang.org"
+ echo " Just: https://github.com/casey/just"
+ ;;
+ *)
+ echo "โ Unknown help area: {{AREA}}"
+ echo ""
+ echo "Available help areas:"
+ echo " modules - Available modules and commands"
+ echo " status - Status and information commands"
+ echo " get-started - Getting started guide"
+ echo " docs - Documentation and resources"
+ echo ""
+ echo "Usage: just help [area]"
+ echo " just h [area] # Short alias"
+ ;;
+ esac
+
+# List all available modules
+[no-cd]
+modules:
+ @echo "๐ Available Justfile Modules:"
+ @echo "============================="
+ @echo ""
+ @echo "๐จ BUILD MODULE (justfiles/build.just)"
+ @echo " Native and cross-platform compilation"
+ @echo " Commands: build, build-cross, build-docker-*"
+ @echo " Help: just build-help"
+ @echo ""
+ @echo "๐ฆ DISTRIBUTION MODULE (justfiles/distro.just)"
+ @echo " Collection and packaging"
+ @echo " Commands: collect, pack, release-*"
+ @echo " Help: just distro-help"
+ @echo ""
+ @echo "๐ UPSTREAM MODULE (justfiles/upstream.just)"
+ @echo " Repository tracking and synchronization"
+ @echo " Commands: upstream-*, status-*"
+ @echo " Help: just upstream-help"
+ @echo ""
+ @echo "๐งช QA MODULE (justfiles/qa.just)"
+ @echo " Testing, linting, and code quality"
+ @echo " Commands: test, lint, fmt, audit, qa-*"
+ @echo " Help: just qa-help"
+ @echo ""
+ @echo "๐ ๏ธ TOOLS MODULE (justfiles/tools.just)"
+ @echo " Development tools and utilities"
+ @echo " Commands: validate-*, make-plugin, interactive"
+ @echo " Help: just tools-help"
+ @echo ""
+ @echo "๐ฏ ALIAS MODULE (justfiles/alias.just)"
+ @echo " Quick access shortcuts"
+ @echo " Aliases: h (help), b (build), s (status)"
+ @echo ""
+ @echo "๐ HELP MODULE (justfiles/help.just)"
+ @echo " Comprehensive help system"
+ @echo " Commands: help, modules"
+
+# Quick access to all module help commands
+[no-cd]
+help-all:
+ @echo "๐ Complete Help for All Modules"
+ @echo "================================"
+ @echo ""
+ @just build-help
+ @echo ""
+ @just distro-help
+ @echo ""
+ @just upstream-help
+ @echo ""
+ @just qa-help
+ @echo ""
+ @just tools-help
+
+# List all available commands across all modules
+[no-cd]
+list-all:
+ @echo "๐ All Available Commands:"
+ @echo "========================="
+ @echo ""
+ @echo "Use 'just --list' to see all commands, or:"
+ @echo " just help - Main help with module overview"
+ @echo " just modules - List all modules"
+ @echo " just help-all - Complete help for all modules"
+ @echo ""
+ @echo "Module-specific help:"
+ @echo " just build-help - Build module commands"
+ @echo " just distro-help - Distribution module commands"
+ @echo " just upstream-help - Upstream module commands"
+ @echo " just qa-help - QA module commands"
+ @echo " just tools-help - Tools module commands"
diff --git a/justfiles/qa.just b/justfiles/qa.just
new file mode 100644
index 0000000..bdd318e
--- /dev/null
+++ b/justfiles/qa.just
@@ -0,0 +1,416 @@
+# Quality Assurance Module - Testing, Linting, and Code Quality
+# Commands for ensuring code quality, running tests, and maintaining standards
+
+# ๐งช TESTING COMMANDS
+
+# Run cargo check on all plugins
+[no-cd]
+check:
+ @echo "๐ Running cargo check on all plugins..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Checking $$plugin..."; \
+ cd "$$plugin" && cargo check && cd ..; \
+ fi; \
+ done
+
+# Run cargo test on all plugins
+[no-cd]
+test:
+ @echo "๐งช Running tests on all plugins..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Testing $$plugin..."; \
+ cd "$$plugin" && cargo test && cd ..; \
+ fi; \
+ done
+
+# Run tests with verbose output
+[no-cd]
+test-verbose:
+ @echo "๐งช Running tests (verbose)..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Testing $$plugin..."; \
+ cd "$$plugin" && cargo test -- --nocapture && cd ..; \
+ fi; \
+ done
+
+# Run tests in parallel
+[no-cd]
+test-parallel:
+ @echo "โก Running tests in parallel..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Testing $$plugin..."; \
+ cd "$$plugin" && cargo test --jobs 8 && cd ..; \
+ fi; \
+ done
+
+# Test specific plugin
+[no-cd]
+test-plugin PLUGIN:
+ @echo "๐งช Testing {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo test
+
+# Run integration tests
+[no-cd]
+test-integration:
+ @echo "๐ Running integration tests..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Integration testing $$plugin..."; \
+ cd "$$plugin" && cargo test --test integration 2>/dev/null || echo "No integration tests for $$plugin" && cd ..; \
+ fi; \
+ done
+
+# Run doc tests
+[no-cd]
+test-docs:
+ @echo "๐ Running documentation tests..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Doc testing $$plugin..."; \
+ cd "$$plugin" && cargo test --doc && cd ..; \
+ fi; \
+ done
+
+# ๐ LINTING COMMANDS
+
+# Run cargo clippy on all plugins
+[no-cd]
+lint:
+ @echo "๐ Running clippy on all plugins..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Linting $$plugin..."; \
+ cd "$$plugin" && cargo clippy -- -D warnings && cd ..; \
+ fi; \
+ done
+
+# Run clippy with additional lints
+[no-cd]
+lint-pedantic:
+ @echo "๐ Running pedantic clippy..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Pedantic linting $$plugin..."; \
+ cd "$$plugin" && cargo clippy -- -W clippy::pedantic -D warnings && cd ..; \
+ fi; \
+ done
+
+# Lint specific plugin
+[no-cd]
+lint-plugin PLUGIN:
+ @echo "๐ Linting {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo clippy -- -D warnings
+
+# Fix lint issues automatically
+[no-cd]
+lint-fix:
+ @echo "๐ง Fixing lint issues automatically..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Fixing $$plugin..."; \
+ cd "$$plugin" && cargo clippy --fix --allow-dirty --allow-staged && cd ..; \
+ fi; \
+ done
+
+# ๐จ FORMATTING COMMANDS
+
+# Format all Rust code
+[no-cd]
+fmt:
+ @echo "๐จ Formatting Rust code..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Formatting $$plugin..."; \
+ cd "$$plugin" && cargo fmt && cd ..; \
+ fi; \
+ done
+
+# Check formatting without making changes
+[no-cd]
+fmt-check:
+ @echo "๐จ Checking code formatting..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Checking format of $$plugin..."; \
+ cd "$$plugin" && cargo fmt -- --check && cd ..; \
+ fi; \
+ done
+
+# Format specific plugin
+[no-cd]
+fmt-plugin PLUGIN:
+ @echo "๐จ Formatting {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo fmt
+
+# Format with custom configuration
+[no-cd]
+fmt-custom CONFIG:
+ @echo "๐จ Formatting with custom config: {{CONFIG}}..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Formatting $$plugin..."; \
+ cd "$$plugin" && cargo fmt --config {{CONFIG}} && cd ..; \
+ fi; \
+ done
+
+# ๐ SECURITY COMMANDS
+
+# Run cargo audit on all plugins
+[no-cd]
+audit:
+ @echo "๐ Running security audit..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Auditing $$plugin..."; \
+ cd "$$plugin" && cargo audit && cd ..; \
+ fi; \
+ done
+
+# Audit specific plugin
+[no-cd]
+audit-plugin PLUGIN:
+ @echo "๐ Auditing {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo audit
+
+# Check for outdated dependencies
+[no-cd]
+audit-outdated:
+ @echo "๐
Checking for outdated dependencies..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Checking $$plugin..."; \
+ cd "$$plugin" && cargo outdated || echo "cargo-outdated not available" && cd ..; \
+ fi; \
+ done
+
+# Generate dependency report
+[no-cd]
+audit-deps:
+ @echo "๐ Generating dependency report..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "=== $$plugin ==="; \
+ cd "$$plugin" && cargo tree --depth 1 && cd ..; \
+ echo ""; \
+ fi; \
+ done
+
+# ๐ BENCHMARKING COMMANDS
+
+# Run benchmarks on all plugins
+[no-cd]
+bench:
+ @echo "๐ Running benchmarks..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Benchmarking $$plugin..."; \
+ cd "$$plugin" && cargo bench 2>/dev/null || echo "No benchmarks for $$plugin" && cd ..; \
+ fi; \
+ done
+
+# Benchmark specific plugin
+[no-cd]
+bench-plugin PLUGIN:
+ @echo "๐ Benchmarking {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo bench
+
+# Run performance tests
+[no-cd]
+perf-test:
+ @echo "โก Running performance tests..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Performance testing $$plugin..."; \
+ cd "$$plugin" && cargo test --release perf 2>/dev/null || echo "No perf tests for $$plugin" && cd ..; \
+ fi; \
+ done
+
+# ๐ DOCUMENTATION COMMANDS
+
+# Generate documentation for all plugins
+[no-cd]
+docs:
+ @echo "๐ Generating documentation..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Generating docs for $$plugin..."; \
+ cd "$$plugin" && cargo doc --no-deps && cd ..; \
+ fi; \
+ done
+
+# Open documentation in browser
+[no-cd]
+docs-open PLUGIN:
+ @echo "๐ Opening documentation for {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo doc --open
+
+# Generate documentation with private items
+[no-cd]
+docs-private:
+ @echo "๐ Generating documentation (including private)..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Generating docs for $$plugin..."; \
+ cd "$$plugin" && cargo doc --no-deps --document-private-items && cd ..; \
+ fi; \
+ done
+
+# Check documentation links
+[no-cd]
+docs-check:
+ @echo "๐ Checking documentation links..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Checking docs for $$plugin..."; \
+ cd "$$plugin" && cargo doc --no-deps 2>&1 | grep -i "warning\|error" || echo "โ
OK" && cd ..; \
+ fi; \
+ done
+
+# ๐ WORKFLOW COMMANDS
+
+# Complete quality check workflow
+[no-cd]
+qa-flow:
+ @echo "โจ Running complete quality check workflow..."
+ @just validate-nushell
+ @just fmt-check
+ @just lint
+ @just test
+ @just audit
+
+# Quick quality check
+[no-cd]
+qa-quick:
+ @echo "โก Running quick quality checks..."
+ @just fmt-check
+ @just check
+ @just lint
+
+# Pre-commit checks
+[no-cd]
+qa-pre-commit:
+ @echo "๐ Running pre-commit checks..."
+ @just fmt-check
+ @just lint
+ @just test
+
+# CI simulation
+[no-cd]
+qa-ci:
+ @echo "๐ค Simulating CI workflow..."
+ @just validate-nushell
+ @just fmt-check
+ @just lint
+ @just test
+ @just audit
+ @echo "โ
All CI checks passed!"
+
+# Full quality suite
+[no-cd]
+qa-full:
+ @echo "๐ฏ Running full quality suite..."
+ @just fmt-check
+ @just lint-pedantic
+ @just test-verbose
+ @just test-docs
+ @just audit
+ @just docs-check
+ @just bench
+
+# ๐ QUALITY INFORMATION
+
+# Show quality metrics
+[no-cd]
+qa-metrics:
+ @echo "๐ Quality Metrics:"
+ @echo "=================="
+ @echo ""
+ @echo "Code Coverage:"
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo -n " $$plugin: "; \
+ cd "$$plugin" && cargo tarpaulin --skip-clean --out Stdout 2>/dev/null | grep -o "[0-9]*\.[0-9]*%" | tail -1 || echo "Not available" && cd ..; \
+ fi; \
+ done
+ @echo ""
+ @echo "Lines of Code:"
+ @find nu_plugin_*/src -name "*.rs" -exec wc -l {} + | tail -1 | awk '{print " Total: " $1 " lines"}'
+
+# Show test statistics
+[no-cd]
+qa-stats:
+ @echo "๐ Test Statistics:"
+ @echo "=================="
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo -n "$$plugin: "; \
+ cd "$$plugin" && cargo test 2>&1 | grep -o "[0-9]* passed" || echo "No tests" && cd ..; \
+ fi; \
+ done
+
+# ๐ QA INFORMATION
+
+# Show QA help
+[no-cd]
+qa-help:
+ @echo "๐งช Quality Assurance Module Help"
+ @echo "================================"
+ @echo ""
+ @echo "TESTING:"
+ @echo " check - Run cargo check on all plugins"
+ @echo " test - Run tests on all plugins"
+ @echo " test-verbose - Run tests with verbose output"
+ @echo " test-parallel - Run tests in parallel"
+ @echo " test-plugin PLUGIN - Test specific plugin"
+ @echo " test-integration - Run integration tests"
+ @echo " test-docs - Run documentation tests"
+ @echo ""
+ @echo "LINTING:"
+ @echo " lint - Run clippy on all plugins"
+ @echo " lint-pedantic - Run pedantic clippy"
+ @echo " lint-plugin PLUGIN - Lint specific plugin"
+ @echo " lint-fix - Fix lint issues automatically"
+ @echo ""
+ @echo "FORMATTING:"
+ @echo " fmt - Format all code"
+ @echo " fmt-check - Check formatting"
+ @echo " fmt-plugin PLUGIN - Format specific plugin"
+ @echo " fmt-custom CONFIG - Format with custom config"
+ @echo ""
+ @echo "SECURITY:"
+ @echo " audit - Run security audit"
+ @echo " audit-plugin PLUGIN - Audit specific plugin"
+ @echo " audit-outdated - Check outdated dependencies"
+ @echo " audit-deps - Generate dependency report"
+ @echo ""
+ @echo "BENCHMARKING:"
+ @echo " bench - Run benchmarks"
+ @echo " bench-plugin PLUGIN - Benchmark specific plugin"
+ @echo " perf-test - Run performance tests"
+ @echo ""
+ @echo "DOCUMENTATION:"
+ @echo " docs - Generate documentation"
+ @echo " docs-open PLUGIN - Open docs in browser"
+ @echo " docs-private - Generate with private items"
+ @echo " docs-check - Check documentation links"
+ @echo ""
+ @echo "WORKFLOWS:"
+ @echo " qa-flow - Complete quality workflow"
+ @echo " qa-quick - Quick quality checks"
+ @echo " qa-pre-commit - Pre-commit checks"
+ @echo " qa-ci - CI simulation"
+ @echo " qa-full - Full quality suite"
+ @echo ""
+ @echo "METRICS:"
+ @echo " qa-metrics - Show quality metrics"
+ @echo " qa-stats - Show test statistics"
+ @echo ""
+ @echo "EXAMPLES:"
+ @echo " just qa-flow"
+ @echo " just test-plugin nu_plugin_clipboard"
+ @echo " just lint-fix"
+ @echo " just docs-open nu_plugin_image"
diff --git a/justfiles/tools.just b/justfiles/tools.just
new file mode 100644
index 0000000..886f669
--- /dev/null
+++ b/justfiles/tools.just
@@ -0,0 +1,345 @@
+# Tools Module - Development Tools and Utilities
+# Commands for development utilities, plugin management, and system tools
+
+# ๐ VERSION AND VALIDATION COMMANDS
+
+# Check nushell version consistency
+[no-cd]
+validate-nushell:
+ @echo "๐ Validating nushell version consistency..."
+ @{{justfile_directory()}}/scripts/run.sh --check-only
+
+# Fix nushell version mismatches
+[no-cd]
+fix-nushell:
+ @echo "๐ง Fixing nushell version mismatches..."
+ @{{justfile_directory()}}/scripts/run.sh --fix --check-only
+
+# Update nu dependency versions
+[no-cd]
+update-nu-versions:
+ @echo "๐ Updating nu dependency versions..."
+ @{{justfile_directory()}}/scripts/run.sh update_nu_versions.nu
+
+# List current nu dependency versions
+[no-cd]
+list-nu-versions:
+ @echo "๐ Current nu dependency versions:"
+ @{{justfile_directory()}}/scripts/run.sh update_nu_versions.nu list
+
+# Update nushell submodule
+[no-cd]
+update-nushell:
+ @echo "๐ Updating nushell submodule..."
+ @bash {{justfile_directory()}}/scripts/sh/update_nushell.sh update
+
+# ๐ PLUGIN MANAGEMENT COMMANDS
+
+# Create a new plugin from template
+[no-cd]
+make-plugin PLUGIN_NAME:
+ @echo "๐ Creating new plugin: {{PLUGIN_NAME}}"
+ @{{justfile_directory()}}/scripts/run.sh make_plugin.nu {{PLUGIN_NAME}}
+
+# Install specific plugin locally
+[no-cd]
+install-plugin PLUGIN:
+ @echo "๐ฅ Installing {{PLUGIN}} locally..."
+ @cd {{PLUGIN}} && cargo build --release
+ @echo "To add to nushell: plugin add ./{{PLUGIN}}/target/release/{{PLUGIN}}"
+
+# Remove plugin from workspace
+[no-cd]
+remove-plugin PLUGIN:
+ @echo "๐๏ธ Removing plugin {{PLUGIN}}..."
+ @if [ -d "{{PLUGIN}}" ]; then \
+ echo "Are you sure you want to remove {{PLUGIN}}? (y/N)"; \
+ read -r confirm; \
+ if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
+ rm -rf "{{PLUGIN}}"; \
+ echo "โ
Removed {{PLUGIN}}"; \
+ else \
+ echo "โ Cancelled"; \
+ fi; \
+ else \
+ echo "Plugin {{PLUGIN}} not found"; \
+ fi
+
+# List all plugins
+[no-cd]
+list-plugins:
+ @echo "๐ Available plugins:"
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo " - $$plugin"; \
+ fi; \
+ done
+
+# Show plugin information
+[no-cd]
+plugin-info PLUGIN:
+ @echo "โน๏ธ Plugin Information: {{PLUGIN}}"
+ @if [ -d "{{PLUGIN}}" ]; then \
+ echo "Name: {{PLUGIN}}"; \
+ echo "Path: $(pwd)/{{PLUGIN}}"; \
+ if [ -f "{{PLUGIN}}/Cargo.toml" ]; then \
+ echo "Version: $(grep '^version' {{PLUGIN}}/Cargo.toml | cut -d'"' -f2)"; \
+ echo "Description: $(grep '^description' {{PLUGIN}}/Cargo.toml | cut -d'"' -f2 || echo 'Not available')"; \
+ fi; \
+ echo "Binary exists: $([ -f {{PLUGIN}}/target/release/{{PLUGIN}} ] && echo 'Yes' || echo 'No')"; \
+ echo "Last modified: $(stat -c %y {{PLUGIN}} 2>/dev/null || stat -f %m {{PLUGIN}} 2>/dev/null || echo 'Unknown')"; \
+ else \
+ echo "Plugin {{PLUGIN}} not found"; \
+ fi
+
+# ๐ ๏ธ DEVELOPMENT TOOLS
+
+# Run command on specific plugin
+plugin PLUGIN CMD:
+ @echo "๐ง Running '{{CMD}}' on {{PLUGIN}}"
+ @cd {{PLUGIN}} && {{CMD}}
+
+# Check specific plugin
+[no-cd]
+check-plugin PLUGIN:
+ @echo "๐ Checking {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo check
+
+# Watch for changes and rebuild (requires entr)
+[no-cd]
+watch PLUGIN:
+ #!/usr/bin/env bash
+ if command -v entr >/dev/null 2>&1; then
+ echo "๐ Watching {{PLUGIN}} for changes..."
+ find {{PLUGIN}}/src -name "*.rs" | entr just build-plugin {{PLUGIN}}
+ else
+ echo "โ entr not installed. Install with: brew install entr (macOS) or apt install entr (Ubuntu)"
+ fi
+
+# Interactive plugin selection (requires fzf)
+[no-cd]
+interactive:
+ #!/usr/bin/env bash
+ if command -v fzf >/dev/null 2>&1; then
+ echo "๐ฏ Interactive Plugin Selection"
+ PLUGIN=$(ls -d nu_plugin_* | fzf --prompt="Select plugin: ")
+ if [ -n "$PLUGIN" ]; then
+ ACTION=$(echo -e "build\ntest\ncheck\nlint\nupstream-check\nupstream-merge\ninstall" | fzf --prompt="Select action: ")
+ if [ -n "$ACTION" ]; then
+ case $ACTION in
+ "upstream-check") just upstream-check-plugin $PLUGIN ;;
+ "upstream-merge") just upstream-merge $PLUGIN ;;
+ "build") just build-plugin $PLUGIN ;;
+ "test") just test-plugin $PLUGIN ;;
+ "check") just check-plugin $PLUGIN ;;
+ "lint") cd $PLUGIN && cargo clippy ;;
+ "install") just install-plugin $PLUGIN ;;
+ esac
+ fi
+ fi
+ else
+ echo "โ fzf not installed. Install with: brew install fzf (macOS) or apt install fzf (Ubuntu)"
+ fi
+
+# ๐ SYSTEM INFORMATION
+
+# Show environment configuration
+[no-cd]
+env-info:
+ @echo "๐ Environment Configuration:"
+ @if [ -f env ]; then \
+ cat env; \
+ else \
+ echo "No env file found"; \
+ fi
+
+# Show system information
+[no-cd]
+system-info:
+ #!/usr/bin/env bash
+ echo "๐ป System Information:"
+ echo "OS: $(uname -s)"
+ echo "Architecture: $(uname -m)"
+ echo "Nushell: $(nu --version 2>/dev/null || echo 'Not installed')"
+ echo "Rust: $(rustc --version 2>/dev/null || echo 'Not installed')"
+ echo "Cargo: $(cargo --version 2>/dev/null || echo 'Not installed')"
+ echo "Just: $(just --version 2>/dev/null || echo 'Not installed')"
+ echo "Docker: $(docker --version 2>/dev/null || echo 'Not installed')"
+ echo "Git: $(git --version 2>/dev/null || echo 'Not installed')"
+
+# Validate setup and dependencies
+[no-cd]
+validate:
+ @echo "โ
Validating setup..."
+ @echo "Checking required tools:"
+ @command -v nu >/dev/null 2>&1 && echo "โ
nushell" || echo "โ nushell (required)"
+ @command -v cargo >/dev/null 2>&1 && echo "โ
cargo" || echo "โ cargo (required)"
+ @command -v git >/dev/null 2>&1 && echo "โ
git" || echo "โ git (required)"
+ @command -v just >/dev/null 2>&1 && echo "โ
just" || echo "โ just (optional but recommended)"
+ @command -v docker >/dev/null 2>&1 && echo "โ
docker" || echo "โ ๏ธ docker (optional for cross-compilation)"
+ @echo ""
+ @echo "Checking directory structure:"
+ @[ -d scripts ] && echo "โ
scripts directory" || echo "โ scripts directory"
+ @[ -d etc ] && echo "โ
etc directory" || echo "โ etc directory"
+ @[ -f etc/plugin_registry.toml ] && echo "โ
plugin registry" || echo "โ plugin registry"
+ @[ -f etc/upstream_exclude.toml ] && echo "โ
upstream exclusions" || echo "โ ๏ธ upstream exclusions (optional)"
+ @[ -f env ] && echo "โ
env file" || echo "โ ๏ธ env file (optional)"
+ @echo ""
+ @echo "Plugin directories:"
+ @ls -d nu_plugin_* 2>/dev/null | wc -l | xargs echo "๐ฆ Found plugins:"
+
+# ๐งน CLEANUP COMMANDS
+
+# Clean all build artifacts
+[no-cd]
+clean:
+ @echo "๐งน Cleaning build artifacts..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Cleaning $$plugin..."; \
+ cd "$$plugin" && cargo clean && cd ..; \
+ fi; \
+ done
+
+# Clean specific plugin
+[no-cd]
+clean-plugin PLUGIN:
+ @echo "๐งน Cleaning {{PLUGIN}}..."
+ @cd {{PLUGIN}} && cargo clean
+
+# Clean distribution files
+[no-cd]
+clean-dist:
+ @echo "๐งน Cleaning distribution files..."
+ @rm -rf distribution bin_archives
+ @echo "โ
Cleaned distribution and bin_archives"
+
+# Clean all caches
+[no-cd]
+clean-all:
+ @echo "๐งน Cleaning everything..."
+ @just clean
+ @just clean-dist
+ @echo "โ
All clean!"
+
+# ๐ MAINTENANCE COMMANDS
+
+# Update all dependencies (careful!)
+[no-cd]
+update-deps:
+ @echo "โฌ๏ธ Updating dependencies (this may break things)..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin" ]; then \
+ echo "Updating deps in $$plugin..."; \
+ cd "$$plugin" && cargo update && cd ..; \
+ fi; \
+ done
+
+# Fix common issues automatically
+[no-cd]
+auto-fix:
+ @echo "๐ง Running automatic fixes..."
+ @just fix-nushell
+ @just fmt
+ @just lint-fix
+ @echo "โ
Automatic fixes completed"
+
+# Generate project statistics
+[no-cd]
+stats:
+ @echo "๐ Project Statistics:"
+ @echo "===================="
+ @echo "Plugins: $(ls -d nu_plugin_* 2>/dev/null | wc -l)"
+ @echo "Rust files: $(find nu_plugin_*/src -name "*.rs" 2>/dev/null | wc -l)"
+ @echo "Lines of code: $(find nu_plugin_*/src -name "*.rs" -exec wc -l {} + 2>/dev/null | tail -1 | awk '{print $1}' || echo '0')"
+ @echo "Test files: $(find nu_plugin_* -name "*test*.rs" -o -name "tests" -type d 2>/dev/null | wc -l)"
+ @echo "Documentation files: $(find . -name "*.md" 2>/dev/null | wc -l)"
+
+# ๐ง CONFIGURATION MANAGEMENT
+
+# Show configuration files
+[no-cd]
+config-list:
+ @echo "๐ Configuration Files:"
+ @echo "======================"
+ @echo "Main configuration:"
+ @[ -f etc/plugin_registry.toml ] && echo "โ
etc/plugin_registry.toml" || echo "โ etc/plugin_registry.toml"
+ @[ -f etc/build_targets.toml ] && echo "โ
etc/build_targets.toml" || echo "โ etc/build_targets.toml"
+ @[ -f etc/upstream_exclude.toml ] && echo "โ
etc/upstream_exclude.toml" || echo "โ ๏ธ etc/upstream_exclude.toml"
+ @echo ""
+ @echo "Environment:"
+ @[ -f env ] && echo "โ
env" || echo "โ ๏ธ env (optional)"
+ @echo ""
+ @echo "Build configuration:"
+ @[ -f justfile ] && echo "โ
justfile" || echo "โ justfile"
+ @[ -f Dockerfile.cross ] && echo "โ
Dockerfile.cross" || echo "โ Dockerfile.cross"
+
+# Edit configuration file
+[no-cd]
+config-edit FILE:
+ @echo "โ๏ธ Editing configuration: {{FILE}}"
+ @${EDITOR:-nano} {{FILE}}
+
+# Backup configuration
+[no-cd]
+config-backup:
+ @echo "๐พ Backing up configuration..."
+ @mkdir -p backups/config-$(date +%Y%m%d-%H%M%S)
+ @cp etc/*.toml backups/config-$(date +%Y%m%d-%H%M%S)/ 2>/dev/null || true
+ @[ -f env ] && cp env backups/config-$(date +%Y%m%d-%H%M%S)/ || true
+ @echo "โ
Configuration backed up to backups/config-$(date +%Y%m%d-%H%M%S)/"
+
+# ๐ TOOLS INFORMATION
+
+# Show tools help
+[no-cd]
+tools-help:
+ @echo "๐ ๏ธ Tools Module Help"
+ @echo "===================="
+ @echo ""
+ @echo "VERSION & VALIDATION:"
+ @echo " validate-nushell - Check nushell version consistency"
+ @echo " fix-nushell - Fix version mismatches"
+ @echo " update-nu-versions - Update nu dependency versions"
+ @echo " list-nu-versions - List current versions"
+ @echo " update-nushell - Update nushell submodule"
+ @echo ""
+ @echo "PLUGIN MANAGEMENT:"
+ @echo " make-plugin NAME - Create new plugin from template"
+ @echo " install-plugin PLUGIN - Install plugin locally"
+ @echo " remove-plugin PLUGIN - Remove plugin from workspace"
+ @echo " list-plugins - List all plugins"
+ @echo " plugin-info PLUGIN - Show plugin information"
+ @echo ""
+ @echo "DEVELOPMENT TOOLS:"
+ @echo " plugin PLUGIN CMD - Run command on plugin"
+ @echo " check-plugin PLUGIN - Check specific plugin"
+ @echo " watch PLUGIN - Watch for changes (requires entr)"
+ @echo " interactive - Interactive plugin selection (requires fzf)"
+ @echo ""
+ @echo "SYSTEM INFORMATION:"
+ @echo " env-info - Show environment configuration"
+ @echo " system-info - Show system information"
+ @echo " validate - Validate setup and dependencies"
+ @echo ""
+ @echo "CLEANUP:"
+ @echo " clean - Clean all build artifacts"
+ @echo " clean-plugin PLUGIN - Clean specific plugin"
+ @echo " clean-dist - Clean distribution files"
+ @echo " clean-all - Clean everything"
+ @echo ""
+ @echo "MAINTENANCE:"
+ @echo " update-deps - Update all dependencies"
+ @echo " auto-fix - Run automatic fixes"
+ @echo " stats - Generate project statistics"
+ @echo ""
+ @echo "CONFIGURATION:"
+ @echo " config-list - Show configuration files"
+ @echo " config-edit FILE - Edit configuration file"
+ @echo " config-backup - Backup configuration"
+ @echo ""
+ @echo "EXAMPLES:"
+ @echo " just make-plugin nu_plugin_myfeature"
+ @echo " just watch nu_plugin_clipboard"
+ @echo " just interactive"
+ @echo " just plugin nu_plugin_image 'cargo bench'"
diff --git a/justfiles/upstream.just b/justfiles/upstream.just
new file mode 100644
index 0000000..a40a0e5
--- /dev/null
+++ b/justfiles/upstream.just
@@ -0,0 +1,286 @@
+# Upstream Module - Repository Tracking and Synchronization
+# Commands for managing upstream repositories and automated tracking
+
+# ๐ UPSTREAM CHECK COMMANDS
+
+# Check upstream changes for all plugins
+[no-cd]
+upstream-check:
+ @echo "๐ Checking upstream changes..."
+ @{{justfile_directory()}}/scripts/run.sh check_upstream_changes.nu
+
+# Check upstream for specific plugin
+[no-cd]
+upstream-check-plugin PLUGIN:
+ @echo "๐ Checking upstream for {{PLUGIN}}..."
+ @{{justfile_directory()}}/scripts/run.sh check_upstream_changes.nu --plugin {{PLUGIN}}
+
+# Check upstream with verbose output
+[no-cd]
+upstream-check-verbose:
+ @echo "๐ Checking upstream changes (verbose)..."
+ @{{justfile_directory()}}/scripts/run.sh check_upstream_changes.nu --verbose
+
+# Check only plugins with pending status
+[no-cd]
+upstream-check-pending:
+ @echo "๐ Checking only pending plugins..."
+ @{{justfile_directory()}}/scripts/run.sh check_upstream_changes.nu --pending-only
+
+# ๐ UPSTREAM PREVIEW COMMANDS
+
+# Preview merge changes for a plugin
+[no-cd]
+upstream-preview PLUGIN:
+ @echo "๐ Preview merge for {{PLUGIN}}..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --preview {{PLUGIN}}
+
+# Preview all pending merges
+[no-cd]
+upstream-preview-all:
+ @echo "๐ Preview all pending merges..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --preview --all
+
+# Show diff for plugin
+[no-cd]
+upstream-diff PLUGIN:
+ @echo "๐ Showing diff for {{PLUGIN}}..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --diff {{PLUGIN}}
+
+# ๐ UPSTREAM MERGE COMMANDS
+
+# Safely merge upstream changes for a plugin
+[no-cd]
+upstream-merge PLUGIN:
+ @echo "๐ Merging upstream changes for {{PLUGIN}}..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu {{PLUGIN}}
+
+# Merge all pending upstream changes
+[no-cd]
+upstream-merge-all:
+ @echo "๐ Merging all pending upstream changes..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --all
+
+# Force merge upstream for a plugin (even if status is OK)
+[no-cd]
+upstream-merge-force PLUGIN:
+ @echo "๐ช Force merging {{PLUGIN}}..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --force {{PLUGIN}}
+
+# Merge with auto-approval of dependency-only changes
+[no-cd]
+upstream-merge-auto PLUGIN:
+ @echo "๐ค Auto-merging {{PLUGIN}}..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --auto-approve {{PLUGIN}}
+
+# Merge all with auto-approval
+[no-cd]
+upstream-merge-auto-all:
+ @echo "๐ค Auto-merging all pending changes..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --auto-approve --all
+
+# ๐ UPSTREAM ROLLBACK COMMANDS
+
+# Rollback last merge for plugin
+[no-cd]
+upstream-rollback PLUGIN:
+ @echo "๐ Rolling back {{PLUGIN}}..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --rollback {{PLUGIN}}
+
+# Show rollback options for plugin
+[no-cd]
+upstream-rollback-info PLUGIN:
+ @echo "โน๏ธ Rollback info for {{PLUGIN}}..."
+ @{{justfile_directory()}}/scripts/run.sh safe_merge_upstream.nu --rollback-info {{PLUGIN}}
+
+# ๐ UPSTREAM STATUS COMMANDS
+
+# Show upstream status for all plugins
+[no-cd]
+upstream-status:
+ @echo "๐ Upstream Status"
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu
+
+# Show detailed upstream status
+[no-cd]
+upstream-status-detailed:
+ @echo "๐ Detailed Upstream Status"
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu --all
+
+# Show plugins requiring attention
+[no-cd]
+upstream-attention:
+ @echo "๐จ Plugins Requiring Attention"
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu attention
+
+# Show upstream summary
+[no-cd]
+upstream-summary:
+ @echo "๐ Upstream Summary"
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu summary
+
+# Update plugin status manually
+upstream-status-update PLUGIN STATUS:
+ @echo "๐ Updating {{PLUGIN}} status to {{STATUS}}..."
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu update {{PLUGIN}} {{STATUS}}
+
+# Mark local development plugins as OK
+[no-cd]
+upstream-mark-locals-ok:
+ @echo "โ
Marking local development plugins as OK..."
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu update nu_plugin_image ok
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu update nu_plugin_hashes ok
+ @{{justfile_directory()}}/scripts/run.sh plugin_status.nu update nu_plugin_desktop_notifications ok
+ @echo "โ
All local plugins marked as OK"
+
+# ๐ง UPSTREAM CONFIGURATION
+
+# Show plugin registry information
+[no-cd]
+upstream-registry:
+ @echo "๐ Plugin Registry Information:"
+ @if [ -f etc/plugin_registry.toml ]; then \
+ echo "Registry file: etc/plugin_registry.toml"; \
+ echo ""; \
+ echo "Plugins with upstream:"; \
+ grep -A2 "upstream_url.*=" etc/plugin_registry.toml | grep -v "^--" || true; \
+ else \
+ echo "Registry file not found!"; \
+ fi
+
+# Add plugin to upstream exclusion list
+[no-cd]
+upstream-exclude PLUGIN:
+ @echo "๐ซ Adding {{PLUGIN}} to exclusion list..."
+ @EXCLUDE_FILE="etc/upstream_exclude.toml"; \
+ if grep -q "^plugins = \[" "$$EXCLUDE_FILE" 2>/dev/null; then \
+ sed -i.bak "/^plugins = \[/s/\]/\"{{PLUGIN}}\", \]/" "$$EXCLUDE_FILE"; \
+ echo "โ
Added {{PLUGIN}} to exclusions"; \
+ else \
+ echo "โ ๏ธ Please manually add {{PLUGIN}} to $$EXCLUDE_FILE"; \
+ fi
+
+# Remove plugin from upstream exclusion list
+[no-cd]
+upstream-include PLUGIN:
+ @echo "โ
Removing {{PLUGIN}} from exclusion list..."
+ @EXCLUDE_FILE="etc/upstream_exclude.toml"; \
+ sed -i.bak "s/\"{{PLUGIN}}\",*[[:space:]]*//" "$$EXCLUDE_FILE"; \
+ echo "โ
Removed {{PLUGIN}} from exclusions"
+
+# Show excluded plugins
+[no-cd]
+upstream-excluded:
+ @echo "๐ Currently excluded plugins:"
+ @EXCLUDE_FILE="etc/upstream_exclude.toml"; \
+ if [ -f "$$EXCLUDE_FILE" ]; then \
+ grep -A10 "\[exclude\]" "$$EXCLUDE_FILE" | grep -E "^[[:space:]]*\"" | sed 's/[",]//g' | sed 's/^[[:space:]]*/ - /' || echo "No exclusions found"; \
+ else \
+ echo "No exclusions file found"; \
+ fi
+
+# ๐ UPSTREAM MAINTENANCE
+
+# Fetch all upstream repositories
+[no-cd]
+upstream-fetch-all:
+ @echo "๐ Fetching all upstream repositories..."
+ @for plugin in nu_plugin_*; do \
+ if [ -d "$$plugin/.git" ]; then \
+ echo "Fetching $$plugin..."; \
+ cd "$$plugin" && git fetch --all && cd ..; \
+ fi; \
+ done
+
+# Show outdated upstream references
+[no-cd]
+upstream-outdated:
+ @echo "๐
Checking for outdated upstream references..."
+ @{{justfile_directory()}}/scripts/run.sh check_upstream_changes.nu --show-outdated
+
+# Cleanup upstream tracking data
+[no-cd]
+upstream-cleanup:
+ @echo "๐งน Cleaning up upstream tracking data..."
+ @find . -name ".upstream_*" -type f -delete
+ @echo "โ
Cleanup completed"
+
+# ๐จ UPSTREAM CONFLICT RESOLUTION
+
+# Show conflicts for plugin
+[no-cd]
+upstream-conflicts PLUGIN:
+ @echo "๐จ Showing conflicts for {{PLUGIN}}..."
+ @cd {{PLUGIN}} && git status --porcelain | grep "^UU" || echo "No conflicts found"
+
+# Reset plugin to clean state
+[no-cd]
+upstream-reset PLUGIN:
+ @echo "๐ Resetting {{PLUGIN}} to clean state..."
+ @cd {{PLUGIN}} && git reset --hard HEAD && git clean -fd
+
+# Create backup branch before merge
+[no-cd]
+upstream-backup PLUGIN:
+ @echo "๐พ Creating backup branch for {{PLUGIN}}..."
+ @cd {{PLUGIN}} && git branch "backup-$(date +%Y%m%d-%H%M%S)" && echo "โ
Backup branch created"
+
+# ๐ UPSTREAM INFORMATION
+
+# Show upstream help
+[no-cd]
+upstream-help:
+ @echo "๐ Upstream Module Help"
+ @echo "======================"
+ @echo ""
+ @echo "CHECK COMMANDS:"
+ @echo " upstream-check - Check all upstream changes"
+ @echo " upstream-check-plugin PLUGIN - Check specific plugin"
+ @echo " upstream-check-verbose - Check with verbose output"
+ @echo " upstream-check-pending - Check only pending plugins"
+ @echo ""
+ @echo "PREVIEW COMMANDS:"
+ @echo " upstream-preview PLUGIN - Preview merge changes"
+ @echo " upstream-preview-all - Preview all pending merges"
+ @echo " upstream-diff PLUGIN - Show diff for plugin"
+ @echo ""
+ @echo "MERGE COMMANDS:"
+ @echo " upstream-merge PLUGIN - Merge upstream changes"
+ @echo " upstream-merge-all - Merge all pending changes"
+ @echo " upstream-merge-force PLUGIN - Force merge"
+ @echo " upstream-merge-auto PLUGIN - Auto-merge dependencies"
+ @echo " upstream-merge-auto-all - Auto-merge all dependencies"
+ @echo ""
+ @echo "ROLLBACK COMMANDS:"
+ @echo " upstream-rollback PLUGIN - Rollback last merge"
+ @echo " upstream-rollback-info PLUGIN - Show rollback info"
+ @echo ""
+ @echo "STATUS COMMANDS:"
+ @echo " upstream-status - Show status for all plugins"
+ @echo " upstream-status-detailed - Show detailed status"
+ @echo " upstream-attention - Show plugins needing attention"
+ @echo " upstream-summary - Show summary"
+ @echo " upstream-status-update PLUGIN STATUS - Update status"
+ @echo " upstream-mark-locals-ok - Mark local plugins as OK"
+ @echo ""
+ @echo "CONFIGURATION:"
+ @echo " upstream-registry - Show registry information"
+ @echo " upstream-exclude PLUGIN - Add to exclusion list"
+ @echo " upstream-include PLUGIN - Remove from exclusion list"
+ @echo " upstream-excluded - Show excluded plugins"
+ @echo ""
+ @echo "MAINTENANCE:"
+ @echo " upstream-fetch-all - Fetch all repositories"
+ @echo " upstream-outdated - Show outdated references"
+ @echo " upstream-cleanup - Clean tracking data"
+ @echo ""
+ @echo "CONFLICT RESOLUTION:"
+ @echo " upstream-conflicts PLUGIN - Show conflicts"
+ @echo " upstream-reset PLUGIN - Reset to clean state"
+ @echo " upstream-backup PLUGIN - Create backup branch"
+ @echo ""
+ @echo "EXAMPLES:"
+ @echo " just upstream-check-plugin nu_plugin_clipboard"
+ @echo " just upstream-preview nu_plugin_highlight"
+ @echo " just upstream-merge-auto-all"
+ @echo " just upstream-exclude nu_plugin_custom"
diff --git a/scripts/build_all.nu b/scripts/build_all.nu
index a9f4ef2..a8741e1 100755
--- a/scripts/build_all.nu
+++ b/scripts/build_all.nu
@@ -1,7 +1,7 @@
#!/usr/bin/env nu
# Build All Plugins Script
-# Builds all nu_plugin_* directories in release mode
+# Builds all nu_plugin_* directories with support for cross-compilation
# Version check - mandatory for all plugin operations
def version_check [] {
@@ -20,26 +20,112 @@ def get_plugin_directories [] {
}
# Build a single plugin
-def build_plugin [plugin_dir: string] {
- print $"๐จ Building ($plugin_dir)..."
+def build_plugin [
+ plugin_dir: string,
+ target: string = "",
+ use_docker: bool = false,
+ verbose: bool = false
+] {
+ if ($target | str length) > 0 {
+ print $"๐จ Building ($plugin_dir) for ($target)..."
+ } else {
+ print $"๐จ Building ($plugin_dir)..."
+ }
try {
cd $plugin_dir
- let result = cargo build --release
+
+ mut build_cmd = ["cargo", "build", "--release"]
+
+ if ($target | str length) > 0 and not $use_docker {
+ $build_cmd = ($build_cmd | append ["--target", $target])
+ }
+
+ if $verbose {
+ print $" Command: ($build_cmd | str join ' ')"
+ }
+
+ if $use_docker {
+ # Delegate to Docker cross-compilation
+ let docker_result = (nu ../scripts/build_docker_cross.nu --plugin $plugin_dir --target $target | complete)
+ if $docker_result.exit_code != 0 {
+ error make {msg: $"Docker build failed: ($docker_result.stderr)"}
+ }
+ } else {
+ # Native build
+ run-external "cargo" ...($build_cmd | skip 1)
+ }
+
cd ..
print $"โ
Created ($plugin_dir)"
- {plugin: $plugin_dir, status: "success", error: null}
+ {plugin: $plugin_dir, target: $target, status: "success", error: null}
} catch {|err|
cd ..
print $"โ Error in ($plugin_dir): ($err.msg)"
- {plugin: $plugin_dir, status: "error", error: $err.msg}
+ {plugin: $plugin_dir, target: $target, status: "error", error: $err.msg}
}
}
+# Check if cross-compilation is requested and delegate to build_cross.nu
+def check_cross_compilation [
+ target: string,
+ all_targets: bool,
+ docker: bool,
+ native: bool,
+ plugins: list,
+ parallel: bool,
+ verbose: bool
+] {
+ if $all_targets or ($target | str length) > 0 {
+ print "๐ฏ Cross-compilation requested - delegating to build_cross.nu"
+
+ mut args = []
+
+ if $all_targets {
+ $args = ($args | append "--all-targets")
+ }
+
+ if ($target | str length) > 0 {
+ $args = ($args | append ["--targets", $target])
+ }
+
+ if ($plugins | length) > 0 {
+ $args = ($args | append ["--plugins", ($plugins | str join ",")])
+ }
+
+ if $docker {
+ $args = ($args | append "--docker")
+ }
+
+ if $native {
+ $args = ($args | append "--native")
+ }
+
+ if $parallel {
+ $args = ($args | append "--parallel")
+ }
+
+ if $verbose {
+ $args = ($args | append "--verbose")
+ }
+
+ # Execute cross-compilation script
+ nu scripts/build_cross.nu ...$args
+ return true
+ }
+
+ false
+}
+
# Main function
def main [
--verbose (-v) # Verbose output
--parallel (-p) # Build plugins in parallel (experimental)
+ --target (-t): string = "" # Cross-compilation target (e.g., linux-amd64, darwin-arm64)
+ --all-targets (-a) # Build for all enabled cross-compilation targets
+ --plugins: list = [] # Specific plugins to build
+ --docker (-d) # Force use of Docker for cross-compilation
+ --native (-n) # Force native compilation only
] {
# Mandatory version check before any plugin operations
version_check
@@ -49,12 +135,29 @@ def main [
error make {msg: "Please run this script from the nushell-plugins repository root directory"}
}
- print "๐ Building all nushell plugins..."
+ # Check if cross-compilation is requested
+ let is_cross_compilation = check_cross_compilation $target $all_targets $docker $native $plugins $parallel $verbose
+ if $is_cross_compilation {
+ return # Cross-compilation handled by build_cross.nu
+ }
- let plugin_dirs = get_plugin_directories
+ print "๐ Building all nushell plugins (native compilation)..."
+
+ # Determine plugins to build
+ let all_plugin_dirs = get_plugin_directories
+ let plugin_dirs = if ($plugins | length) > 0 {
+ $all_plugin_dirs | where $it in $plugins
+ } else {
+ $all_plugin_dirs
+ }
if ($plugin_dirs | length) == 0 {
- print "โ No nu_plugin_* directories found"
+ if ($plugins | length) > 0 {
+ print $"โ No matching plugins found for: ($plugins | str join ', ')"
+ print $"๐ก Available plugins: ($all_plugin_dirs | str join ', ')"
+ } else {
+ print "โ No nu_plugin_* directories found"
+ }
return
}
@@ -62,6 +165,12 @@ def main [
for dir in $plugin_dirs {
print $" - ($dir)"
}
+
+ if ($target | str length) > 0 {
+ print $"๐ฏ Target: ($target) (native compilation)"
+ } else {
+ print "๐ฏ Target: host platform (native compilation)"
+ }
print ""
let start_time = date now
@@ -70,11 +179,11 @@ def main [
if $parallel {
# Experimental parallel building (may have issues with cargo lock)
print "โก Building in parallel mode (experimental)..."
- $results = ($plugin_dirs | par-each {|dir| build_plugin $dir})
+ $results = ($plugin_dirs | par-each {|dir| build_plugin $dir $target false $verbose})
} else {
# Sequential building (safer)
for dir in $plugin_dirs {
- let result = build_plugin $dir
+ let result = build_plugin $dir $target false $verbose
$results = ($results | append $result)
print "---"
}
@@ -92,6 +201,17 @@ def main [
print $"โ Failed: ($failed | length)"
print $"โฑ๏ธ Total time: ($duration)"
+ if ($successful | length) > 0 {
+ print "\nโ
Successfully built:"
+ for success in $successful {
+ if ($success.target | str length) > 0 {
+ print $" - ($success.plugin) โ ($success.target)"
+ } else {
+ print $" - ($success.plugin)"
+ }
+ }
+ }
+
if ($failed | length) > 0 {
print "\nโ Failed builds:"
for failure in $failed {
@@ -100,6 +220,10 @@ def main [
exit 1
} else {
print "\n๐ All plugins built successfully!"
+ print "๐ก Next steps:"
+ print " - Test plugins: just test"
+ print " - Collect binaries: just collect"
+ print " - Cross-compile: just build-cross-all"
}
}
diff --git a/scripts/collect_install.nu b/scripts/collect_install.nu
index 2686e21..d16f497 100755
--- a/scripts/collect_install.nu
+++ b/scripts/collect_install.nu
@@ -12,15 +12,37 @@ def load_env_vars [] {
| where not ($it | str starts-with "#")
| each {|line|
if ($line | str contains "=") {
- let parts = $line | split column "=" key value
- let key = $parts | get 0 | str replace "export " "" | str trim
- let value = $parts | get 1 | str trim
- {$key: $value}
+ 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| $acc | merge $item}
+ | reduce -f {} {|item, acc|
+ if ($item | is-empty) {
+ $acc
+ } else {
+ $acc | merge $item
+ }
+ }
$content
} else {
@@ -33,23 +55,147 @@ def load_env_vars [] {
}
}
-# Get all built plugin binaries
-def get_built_plugins [] {
- glob "nu_plugin_*/target/release/nu_plugin_*"
+# 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
+ 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) {
@@ -102,10 +248,11 @@ def copy_additional_files [target_path: string] {
# Create installation script
def create_install_script [target_path: string, install_file: string] {
- let install_script_content = $"#!/usr/bin/env nu
+ 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: (date now)
+# Generated at: " + $timestamp + "
def main [
--bin-path (-b): string = \"/usr/local/bin\" # Installation path
@@ -115,57 +262,60 @@ def main [
] {
let available_plugins = ls | where type == file and name =~ \"nu_plugin_\" | get name
- if \\$list {
+ if " + '$list' + " {
print \"๐ฆ Available plugins:\"
- for plugin in \\$available_plugins {
- print \\$\" - (\\$plugin)\"
+ for plugin in " + '$available_plugins' + " {
+ print " + '$" - ($plugin)"' + "
}
return
}
- let plugins_to_install = if (\\$plugins | length) > 0 {
- \\$plugins | where \\$it in \\$available_plugins
+ let plugins_to_install = if (" + '$plugins' + " | length) > 0 {
+ " + '$plugins' + " | where " + '$it' + " in " + '$available_plugins' + "
} else {
- \\$available_plugins
+ " + '$available_plugins' + "
}
- if (\\$plugins_to_install | length) == 0 {
+ if (" + '$plugins_to_install' + " | length) == 0 {
print \"โ No plugins to install\"
return
}
- print \\$\"๐ Installing (\\$plugins_to_install | length) plugins to (\\$bin_path)...\"
+ 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)\"
+ 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)\"
+ cp " + '$plugin' + " " + '$"($bin_path)/($plugin)"' + "
+ chmod +x " + '$"($bin_path)/($plugin)"' + "
+ print " + '$" โ
Installed ($plugin)"' + "
} catch {|err|
- print \\$\" โ Failed to install (\\$plugin): (\\$err.msg)\"
+ print " + '$" โ Failed to install ($plugin): ($err.msg)"' + "
}
}
}
- if not \\$dry_run {
+ if not " + '$dry_run' + " {
print \"\\n๐ก Don't forget to run 'plugin add' for each plugin in nushell!\"
}
}
"
- $install_script_content | save $"($target_path)/($install_file)"
- chmod +x $"($target_path)/($install_file)"
+ $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 (-t): string = "" # Override target path
- --force (-f) # Force overwrite existing files
- --list (-l) # List available plugins only
+ --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) {
@@ -176,66 +326,146 @@ def main [
# Load environment variables
let env_vars = load_env_vars
- let target_path = if ($target | str length) > 0 { $target } else { $env_vars.TARGET_PATH? | default "distribution" }
+ 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"
- # Get built plugins
- let plugins = get_built_plugins
-
- if $list {
- if ($plugins | length) == 0 {
- print "โ No built plugins found"
- print "๐ก Run './scripts/sh/build-all.sh' first to build plugins"
+ # 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 $"๐ฆ Found ($plugins | length) built plugins:"
- for plugin in $plugins {
- print $" โ
($plugin.name) (($plugin.size)) from ($plugin.source_dir)"
+ print "๐ Available built platforms:"
+ for target in $available {
+ print $" โ
($target.name) ($target.platform_name): ($target.count) plugins"
+ print $" ($target.description)"
}
}
return
}
- if ($plugins | length) == 0 {
- print "โ No built plugins found"
- print "๐ก Run './scripts/sh/build-all.sh' first to build plugins"
- exit 1
- }
+ # Determine platforms to collect
+ let available_targets = get_available_targets
+ let host_info = get_host_info
- print $"๐ฆ Found ($plugins | length) built plugins to collect"
-
- # Check if target exists and handle accordingly
- if ($target_path | path exists) and not $force {
- print $"โ ๏ธ Target directory '($target_path)' already exists"
- let confirm = input "Continue and overwrite? [y/N]: "
- if ($confirm | str downcase) != "y" {
- print "โ Aborted"
+ 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
+ }
}
- # Create target structure
- create_target_structure $target_path
+ 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
+ }
- # Copy plugins
- copy_plugins $plugins $target_path
+ print $"๐ฏ Platforms to collect: ($platforms_to_collect | length)"
+ for platform in $platforms_to_collect {
+ print $" - ($platform.name): ($platform.count) plugins"
+ }
- # Copy additional files
- print "๐ Copying additional files..."
- copy_additional_files $target_path
+ # 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
- # Create installation script
- create_install_script $target_path $install_file
+ 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 $"๐ Target directory: ($target_path)"
- print $"๐ฆ Plugins collected: ($plugins | length)"
- print $"๐ Installation script: ($target_path)/($install_file)"
+ 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:"
- print $" 1. Test installation: cd ($target_path) && nu ($install_file) --dry-run"
- print $" 2. Package for distribution: ./scripts/sh/pack-dist.sh"
- print $" 3. Install locally: cd ($target_path) && nu ($install_file)"
+ 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") {
diff --git a/scripts/pack_dist.nu b/scripts/pack_dist.nu
index 41aceb3..240d959 100755
--- a/scripts/pack_dist.nu
+++ b/scripts/pack_dist.nu
@@ -1,7 +1,7 @@
#!/usr/bin/env nu
# Pack Distribution Script
-# Creates distribution archives for built plugins
+# Creates distribution archives for built plugins with multi-platform support
# Load environment variables from env file
def load_env_vars [] {
@@ -12,15 +12,37 @@ def load_env_vars [] {
| where not ($it | str starts-with "#")
| each {|line|
if ($line | str contains "=") {
- let parts = $line | split column "=" key value
- let key = $parts | get 0 | str replace "export " "" | str trim
- let value = $parts | get 1 | str trim
- {$key: $value}
+ 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| $acc | merge $item}
+ | reduce -f {} {|item, acc|
+ if ($item | is-empty) {
+ $acc
+ } else {
+ $acc | merge $item
+ }
+ }
$content
} else {
@@ -35,23 +57,86 @@ def load_env_vars [] {
}
}
+# Load build targets configuration
+def load_targets_config [] {
+ if ("etc/build_targets.toml" | path exists) {
+ open etc/build_targets.toml
+ } else {
+ {targets: {}}
+ }
+}
+
# Get system architecture info
def get_system_info [] {
- let arch = match (uname -m) {
+ let arch = match (^uname -m) {
"x86_64" => "amd64",
"aarch64" => "arm64",
$arch if ($arch | str starts-with "arm") => "arm64",
$other => $other
}
- let platform = match (uname -s | str downcase) {
+ 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}
+ {platform: $platform, arch: $arch, full: $"($platform)-($arch)"}
+}
+
+# Get available distribution platforms
+def get_available_platforms [base_path: string] {
+ let config = load_targets_config
+
+ mut platforms = []
+
+ # Check for single platform in base directory
+ let base_plugins = glob ($base_path | path join "nu_plugin_*") | where ($it | path type) == "file"
+ if ($base_plugins | length) > 0 {
+ let host_info = get_system_info
+ $platforms = ($platforms | append {
+ name: "host",
+ platform_name: $host_info.full,
+ path: $base_path,
+ plugin_count: ($base_plugins | length),
+ description: "Host platform distribution"
+ })
+ }
+
+ # Check for platform-specific subdirectories
+ if ($config.targets | transpose name config | length) > 0 {
+ for target in ($config.targets | transpose name config) {
+ let platform_path = ($base_path | path join $target.name)
+ if ($platform_path | path exists) {
+ let platform_plugins = glob ($platform_path | path join "nu_plugin_*") | where ($it | path type) == "file"
+ if ($platform_plugins | length) > 0 {
+ $platforms = ($platforms | append {
+ name: $target.name,
+ platform_name: $target.config.platform_name,
+ path: $platform_path,
+ plugin_count: ($platform_plugins | length),
+ description: $target.config.description,
+ archive_format: $target.config.archive_format
+ })
+ }
+ }
+ }
+ }
+
+ $platforms
+}
+
+# Generate checksums for a file
+def generate_checksums [file_path: string] {
+ let sha256 = (open $file_path | hash sha256)
+ let size = (ls $file_path | get 0.size)
+
+ {
+ file: ($file_path | path basename),
+ sha256: $sha256,
+ size: $size
+ }
}
# Check if target directory has required files
@@ -67,7 +152,7 @@ def validate_target [target_path: string] {
}
for file in $required_files {
- if not ($"($target_path)/($file)" | path exists) {
+ if not (($target_path | path join $file) | path exists) {
$issues = ($issues | append $"Required file missing: ($file)")
}
}
@@ -79,19 +164,22 @@ def validate_target [target_path: string] {
def create_archive [target_path: string, archive_path: string, env_vars: record] {
# Copy env file to target temporarily
if ("env" | path exists) {
- cp env $"($target_path)/env"
+ cp env ($target_path | path join "env")
}
- let files_to_archive = [
- $"($target_path)/nu_plugin_*",
- $"($target_path)/($env_vars.INSTALL_FILE)",
- $"($target_path)/LICENSE",
- $"($target_path)/README",
- $"($target_path)/env"
+ # Get plugin files using glob
+ let plugin_files = glob ($target_path | path join "nu_plugin_*") | where ($it | path type) == "file"
+
+ let metadata_files = [
+ ($target_path | path join $env_vars.INSTALL_FILE),
+ ($target_path | path join "LICENSE"),
+ ($target_path | path join "README"),
+ ($target_path | path join "env")
]
- # Filter files that actually exist
- let existing_files = $files_to_archive | where ($it | path exists)
+ # Filter metadata files that actually exist and combine with plugin files
+ let existing_metadata_files = $metadata_files | where ($it | path exists)
+ let existing_files = $plugin_files | append $existing_metadata_files
if ($existing_files | length) == 0 {
error make {msg: "No files found to archive"}
@@ -104,8 +192,8 @@ def create_archive [target_path: string, archive_path: string, env_vars: record]
tar czf $archive_path ...$existing_files
# Clean up temporary env file
- if ($"($target_path)/env" | path exists) {
- rm $"($target_path)/env"
+ if (($target_path | path join "env") | path exists) {
+ rm ($target_path | path join "env")
}
let archive_size = ls $archive_path | get 0.size
@@ -124,10 +212,14 @@ def create_archive [target_path: string, archive_path: string, env_vars: record]
# Main function
def main [
--target (-t): string = "" # Override target path
+ --platform (-p): string = "" # Specific platform to package
+ --all-platforms (-a) # Package all available platforms
--output (-o): string = "" # Override output archive path
- --archive-dir (-a): string = "" # Override archive directory
+ --archive-dir: string = "" # Override archive directory
--force (-f) # Force overwrite existing archive
--list (-l) # List what would be archived
+ --list-platforms # List available platforms
+ --checksums # Generate checksums file
] {
# Ensure we're in the repository root directory
if not ("nu_plugin_clipboard" | path exists) {
@@ -138,90 +230,197 @@ def main [
# Load environment variables
let env_vars = load_env_vars
- print $"๐ Loaded configuration:"
- for var in ($env_vars | transpose key value) {
- print $" ($var.key): ($var.value)"
- }
+ let base_target_path = if ($target | str length) > 0 { $target } else { $env_vars.TARGET_PATH }
+ let archive_dir_path = if ($archive_dir | str length) > 0 { $archive_dir } else { $env_vars.BIN_ARCHIVES_DIR_PATH? | default "bin_archives" }
- # Determine paths
- let target_path = if ($target | str length) > 0 { $target } else { $env_vars.TARGET_PATH }
- let archive_dir = if ($archive_dir | str length) > 0 { $archive_dir } else { $env_vars.BIN_ARCHIVES_DIR_PATH? | default "." }
-
- # Validate target directory
- if not ($target_path | path exists) {
- print $"โ Target directory not found: ($target_path)"
- print "๐ก Run './scripts/sh/collect-install.sh' first"
+ # Validate base target directory
+ if not ($base_target_path | path exists) {
+ print $"โ Target directory not found: ($base_target_path)"
+ print "๐ก Run 'just collect' first to collect plugins"
exit 1
}
- let validation = validate_target $target_path
- if not $validation.valid {
- print "โ Target directory validation failed:"
- for issue in $validation.issues {
- print $" - ($issue)"
+ # Get available platforms
+ let available_platforms = get_available_platforms $base_target_path
+
+ # List platforms mode
+ if $list_platforms {
+ if ($available_platforms | length) == 0 {
+ print "โ No platforms found for packaging"
+ print "๐ก Run 'just collect --all-platforms' first"
+ } else {
+ print "๐ Available platforms for packaging:"
+ for platform in $available_platforms {
+ let format = $platform | get archive_format? | default "tar.gz"
+ print $" โ
($platform.name) ($platform.platform_name): ($platform.plugin_count) plugins โ .($format)"
+ print $" Path: ($platform.path)"
+ print $" ($platform.description)"
+ }
}
+ return
+ }
+
+ # Determine platforms to package
+ let platforms_to_package = if $all_platforms {
+ $available_platforms
+ } else if ($platform | str length) > 0 {
+ let selected = $available_platforms | where name == $platform
+ if ($selected | length) == 0 {
+ print $"โ Platform not found: ($platform)"
+ print $"๐ก Available platforms: ($available_platforms | get name | str join ', ')"
+ exit 1
+ }
+ $selected
+ } else {
+ # Default to host platform or first available
+ let host_platform = $available_platforms | where name == "host"
+ if ($host_platform | length) > 0 {
+ $host_platform
+ } else {
+ $available_platforms | first 1
+ }
+ }
+
+ if ($platforms_to_package | length) == 0 {
+ print "โ No platforms to package"
+ print "๐ก Run 'just collect' first to collect plugins"
exit 1
}
- print $"โ
Target directory validated: ($validation.plugin_count) plugins found"
+ print $"๐ฏ Platforms to package: ($platforms_to_package | length)"
+ for platform in $platforms_to_package {
+ print $" - ($platform.name): ($platform.plugin_count) plugins"
+ }
- # Get system info and create archive name
- let sys_info = get_system_info
- let archive_name = $"($sys_info.platform)-($sys_info.arch)-($env_vars.APP_NAME).tar.gz"
-
- # Determine final archive path
- let archive_path = if ($output | str length) > 0 {
- $output
- } else if ($archive_dir | path exists) {
- $"($archive_dir)/($archive_name)"
- } else {
- $archive_name
+ # Create archive directory if needed
+ if not ($archive_dir_path | path exists) {
+ mkdir $archive_dir_path
+ print $"๐ Created archive directory: ($archive_dir_path)"
}
# List mode
if $list {
- print $"๐ Files that would be archived from ($target_path):"
- let files = ls $target_path | where type == "file"
- for file in $files {
- print $" ๐ ($file.name) (($file.size))"
+ print "\n๐ Files that would be archived:"
+ for platform in $platforms_to_package {
+ print $"\n($platform.name) ($platform.platform_name):"
+ let files = ls $platform.path | where type == "file"
+ for file in $files {
+ print $" ๐ ($file.name) (($file.size))"
+ }
}
- print $"\n๐ฆ Would create archive: ($archive_path)"
return
}
- # Check if archive already exists
- if ($archive_path | path exists) and not $force {
- print $"โ ๏ธ Archive already exists: ($archive_path)"
- let confirm = input "Overwrite? [y/N]: "
- if ($confirm | str downcase) != "y" {
- print "โ Aborted"
- exit 1
+ # Package each platform
+ mut created_archives = []
+ mut total_size = 0
+
+ for platform in $platforms_to_package {
+ let platform_name = $platform.platform_name
+ let platform_path = $platform.path
+ let archive_format = $platform | get archive_format? | default "tar.gz"
+
+ # Validate platform directory
+ let validation = validate_target $platform_path
+ if not $validation.valid {
+ print $"โ Platform directory validation failed for ($platform.name):"
+ for issue in $validation.issues {
+ print $" - ($issue)"
+ }
+ continue
+ }
+
+ # Create archive name
+ let archive_name = $"($platform_name)-($env_vars.APP_NAME).($archive_format)"
+ let archive_path = if ($output | str length) > 0 and ($platforms_to_package | length) == 1 {
+ $output
+ } else {
+ $"($archive_dir_path)/($archive_name)"
+ }
+
+ # Check if archive already exists
+ if ($archive_path | path exists) and not $force {
+ print $"โ ๏ธ Archive already exists: ($archive_path)"
+ if ($platforms_to_package | length) == 1 {
+ let confirm = input "Overwrite? [y/N]: "
+ if ($confirm | str downcase) != "y" {
+ print "โ Skipping ($platform.name)"
+ continue
+ }
+ } else {
+ print "๐ Overwriting existing archive (use --force to skip this check)"
+ }
+ }
+
+ print $"\n๐ฆ Creating archive for ($platform.name) ($platform_name)..."
+ print $"๐ Source: ($platform_path)"
+ print $"๐ฆ Archive: ($archive_path)"
+
+ try {
+ create_archive $platform_path $archive_path $env_vars
+ let archive_size = ls $archive_path | get 0.size
+ $total_size = $total_size + ($archive_size | into int)
+
+ $created_archives = ($created_archives | append {
+ platform: $platform.name,
+ platform_name: $platform_name,
+ archive_path: $archive_path,
+ size: $archive_size,
+ plugin_count: $platform.plugin_count
+ })
+
+ print $"โ
Created archive for ($platform.name): ($archive_size)"
+ } catch {|err|
+ print $"โ Failed to create archive for ($platform.name): ($err.msg)"
}
}
- # Create archive directory if needed
- let archive_parent = $archive_path | path dirname
- if not ($archive_parent | path exists) {
- mkdir $archive_parent
- print $"๐ Created archive directory: ($archive_parent)"
+ # Generate checksums if requested
+ if $checksums and ($created_archives | length) > 0 {
+ print "\n๐ Generating checksums..."
+ let checksums_file = $"($archive_dir_path)/checksums.txt"
+
+ mut checksum_data = []
+ for archive in $created_archives {
+ let checksum_info = generate_checksums $archive.archive_path
+ $checksum_data = ($checksum_data | append $checksum_info)
+ print $" โ
($checksum_info.file): ($checksum_info.sha256)"
+ }
+
+ # Write checksums file
+ let checksums_content = ($checksum_data | each {|item|
+ $"($item.sha256) ($item.file)"
+ } | str join "\n")
+
+ $checksums_content | save $checksums_file
+ print $"๐พ Checksums saved to: ($checksums_file)"
}
- # Create the archive
- print $"๐ฆ Creating archive for ($sys_info.platform)-($sys_info.arch)..."
- create_archive $target_path $archive_path $env_vars
-
# Summary
- print $"\nโ
Distribution package created!"
- print $"๐ฆ Archive: ($archive_path)"
- print $"๐๏ธ Platform: ($sys_info.platform)-($sys_info.arch)"
+ print $"\n๐ Distribution packaging completed!"
+ print $"๐ Archive directory: ($archive_dir_path)"
+ print $"๐ฆ Archives created: ($created_archives | length)"
+ print $"๐ Total size: ($total_size | into filesize)"
- let archive_size = ls $archive_path | get 0.size
- print $"๐ Size: ($archive_size)"
+ if ($created_archives | length) > 0 {
+ print "\nโ
Created archives:"
+ for archive in $created_archives {
+ print $" - ($archive.platform_name): ($archive.size) ($archive.plugin_count) plugins"
+ print $" ๐ฆ ($archive.archive_path)"
+ }
+ }
print "\n๐ก Next steps:"
- print $" 1. Test archive: tar -tzf ($archive_path)"
- print $" 2. Distribute: Upload or copy ($archive_path) to target systems"
- print $" 3. Install: Extract and run the installation script"
+ if ($created_archives | length) > 1 {
+ print " 1. Test archives: tar -tzf bin_archives/*.tar.gz"
+ print " 2. Upload to GitHub Releases or distribution server"
+ print " 3. Update installation documentation"
+ } else if ($created_archives | length) == 1 {
+ let archive = $created_archives.0
+ print $" 1. Test archive: tar -tzf ($archive.archive_path)"
+ print $" 2. Distribute: Upload or copy to target systems"
+ print $" 3. Install: Extract and run the installation script"
+ }
}
if ($env.NUSHELL_EXECUTION_CONTEXT? | default "" | str contains "run") {