nushell-plugins/scripts/plugin_status.nu

359 lines
11 KiB
Plaintext
Raw Normal View History

feat: major repository modernization and tracking cleanup ## Summary Comprehensive repository cleanup focusing on plugin dependency management, documentation improvements, and git tracking optimization. ## Key Changes ### 🔧 Core Infrastructure - Synchronized all nu-* dependencies across plugins for version consistency - Enhanced upstream tracking and automation systems - Removed nushell directory from git tracking for cleaner repository management ### 📚 Documentation - Significantly expanded README.md with comprehensive development guides - Added detailed workflow documentation and command references - Improved plugin collection overview and usage examples ### 🧹 Repository Cleanup - Removed legacy bash scripts (build-all.sh, collect-install.sh, make_plugin.sh) - Streamlined automation through unified justfile and nushell script approach - Updated .gitignore with nushell directory and archive patterns - Removed nushell directory from git tracking to prevent unwanted changes ### 🔌 Plugin Updates - **nu_plugin_image**: Major refactoring with modular architecture improvements - **nu_plugin_hashes**: Enhanced functionality and build system improvements - **nu_plugin_highlight**: Updated for new plugin API compatibility - **nu_plugin_clipboard**: Dependency synchronization - **nu_plugin_desktop_notifications**: Version alignment - **nu_plugin_port_extension & nu_plugin_qr_maker**: Consistency updates - **nu_plugin_kcl & nu_plugin_tera**: Submodule synchronization ### 🏗️ Git Tracking Optimization - Removed nushell directory from version control for cleaner repository management - Added comprehensive .gitignore patterns for build artifacts and archives ## Statistics - 2,082 files changed - 2,373 insertions, 339,936 deletions - Net reduction of 337,563 lines (primarily from removing nushell directory tracking) ## Benefits - Complete version consistency across all plugins - Cleaner repository with optimized git tracking - Improved developer experience with streamlined workflows - Enhanced documentation and automation - Reduced repository size and complexity 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-20 15:18:58 +01:00
#!/usr/bin/env nu
# Plugin Status Dashboard
# Shows the current status of all plugins and their upstream sync state
# Version check - mandatory for all plugin operations
def version_check [] {
try {
nu scripts/check_version.nu --quiet | ignore
} catch {
print "❌ Nushell version mismatch detected!"
print "🔧 Run: nu scripts/check_version.nu --fix"
exit 1
}
}
# Load plugin registry
def load_registry [] {
let registry_path = "etc/plugin_registry.toml"
if not ($registry_path | path exists) {
error make {msg: "Plugin registry not found. Please run from repository root directory."}
}
open $registry_path
}
# Load exclusions configuration
def load_exclusions [] {
let exclude_path = "etc/upstream_exclude.toml"
if ($exclude_path | path exists) {
let config = open $exclude_path
{
all: ($config.exclude.plugins? | default []),
check: ($config.exclude.check.plugins? | default []),
merge: ($config.exclude.merge.plugins? | default []),
patterns: ($config.exclude.patterns.plugins? | default [])
}
} else {
{all: [], check: [], merge: [], patterns: []}
}
}
# Check if plugin should be excluded
def is_plugin_excluded [plugin_name: string, exclusions: record] {
# Check direct exclusions
if $plugin_name in $exclusions.all {
return true
}
# Check pattern exclusions
for pattern in $exclusions.patterns {
if ($plugin_name | str contains ($pattern | str replace "*" "")) {
return true
}
}
false
}
# Filter plugins to only include existing directories and non-excluded plugins
def filter_plugins [plugins: record, exclusions: record] {
$plugins
| transpose name config
| where {
let plugin_name = $in.name
let plugin_path = $in.config.local_path
# Check if directory exists
let dir_exists = ($plugin_path | path exists)
# Check if plugin is excluded
let is_excluded = (is_plugin_excluded $plugin_name $exclusions)
$dir_exists and not $is_excluded
}
| reduce -f {} {|it, acc|
$acc | insert $it.name $it.config
}
}
# Save plugin registry
def save_registry [registry: record] {
$registry | to toml | save -f "etc/plugin_registry.toml"
}
# Get status emoji and description
def get_status_emoji [status: string] {
match $status {
"ok" => "✅",
"pending" => "⚠️",
"error" => "❌",
"local_only" => "🏠",
"unknown" => "❓",
"conflict" => "🔥",
_ => "📦"
}
}
# Get status description
def get_status_description [status: string] {
match $status {
"ok" => "Synchronized with upstream",
"pending" => "Changes detected - needs review",
"error" => "Error during upstream check",
"local_only" => "No upstream - local development",
"unknown" => "Not yet checked",
"conflict" => "Merge conflicts detected",
_ => "Unknown status"
}
}
# Format date for display
def format_date [date_str: string] {
if ($date_str | is-empty) {
"Never"
} else {
try {
$date_str | str substring 0..9 # Show just the date part
} catch {
$date_str
}
}
}
# Get plugin directory status
def get_directory_status [local_path: string] {
let full_path = $local_path
if ($full_path | path exists) {
if ($"($full_path)/Cargo.toml" | path exists) {
"📂 Present"
} else {
"📁 No Cargo.toml"
}
} else {
"❌ Missing"
}
}
# Display summary statistics
def show_summary [plugins: record] {
print "📊 Plugin Status Summary"
print "=================================================="
let status_counts = $plugins
| values
| group-by status
| transpose status plugins
| each {|entry| {
status: $entry.status,
count: ($entry.plugins | length),
emoji: (get_status_emoji $entry.status)
}}
| sort-by count --reverse
let total_plugins = ($plugins | values | length)
print $"📦 Total Plugins: ($total_plugins)"
print ""
for status in $status_counts {
let description = get_status_description $status.status
print $"($status.emoji) ($description): ($status.count) plugins"
}
print ""
# Show breakdown by type
let upstream_plugins = $plugins | values | where ($it.upstream_url | is-not-empty) | length
let local_plugins = $plugins | values | where ($it.upstream_url | is-empty) | length
print "📋 Plugin Types:"
print $" 🔗 With Upstream: ($upstream_plugins) plugins"
print $" 🏠 Local Only: ($local_plugins) plugins"
print ""
}
# Show detailed plugin table
def show_plugin_table [plugins: record, show_all: bool] {
let plugin_data = $plugins
| transpose name config
| each {|plugin|
{
Plugin: $plugin.name,
Status: $"(get_status_emoji $plugin.config.status) ($plugin.config.status)",
"Last Check": (format_date $plugin.config.last_checked_date),
"Directory": (get_directory_status $plugin.config.local_path),
"Upstream": (if ($plugin.config.upstream_url | is-empty) { "None" } else { "📡 Yes" }),
"Auto-OK": (if $plugin.config.auto_ok_on_nu_deps_only { "✓" } else { "✗" }),
"Description": $plugin.config.description
}
}
let filtered_data = if $show_all {
$plugin_data
} else {
$plugin_data | where Status !~ "local_only"
}
$filtered_data | table --expand
}
# Show plugins that need attention
def show_attention_needed [plugins: record] {
let needs_attention = $plugins
| transpose name config
| where $it.config.status in ["pending", "error", "conflict", "unknown"]
if ($needs_attention | length) > 0 {
print "\n🚨 Plugins Requiring Attention:"
print "========================================"
for plugin in $needs_attention {
let emoji = get_status_emoji $plugin.config.status
print $"($emoji) ($plugin.name): ($plugin.config.status)"
if not ($plugin.config.upstream_url | is-empty) {
print $" Upstream: ($plugin.config.upstream_url)"
}
if not ($plugin.config.last_checked_date | is-empty) {
print $" Last checked: ($plugin.config.last_checked_date)"
}
print ""
}
}
}
# Show recent activity
def show_recent_activity [plugins: record] {
let recent_plugins = $plugins
| transpose name config
| where not ($it.config.last_checked_date | is-empty)
| sort-by config.last_checked_date --reverse
| first 5
if ($recent_plugins | length) > 0 {
print "\n📅 Recently Checked Plugins:"
print "=" * 35
for plugin in $recent_plugins {
let emoji = get_status_emoji $plugin.config.status
print $"($emoji) ($plugin.name) - ($plugin.config.last_checked_date)"
}
print ""
}
}
# Update plugin status manually
def update_plugin_status [plugin_name: string, new_status: string] {
let registry = load_registry
if not ($plugin_name in ($registry.plugins | columns)) {
error make {msg: $"Plugin '($plugin_name)' not found in registry"}
}
let valid_statuses = ["ok", "pending", "error", "conflict", "unknown", "local_only"]
if not ($new_status in $valid_statuses) {
error make {msg: $"Invalid status. Valid options: ($valid_statuses | str join ', ')"}
}
let updated_registry = $registry | upsert $"plugins.($plugin_name).status" $new_status
save_registry $updated_registry
print $"✅ Updated ($plugin_name) status to '($new_status)'"
}
# Show help information
def show_help [] {
print "Plugin Status Dashboard - Nushell Plugin Upstream Tracker"
print ""
print "USAGE:"
print " nu plugin_status.nu [OPTIONS] [COMMAND]"
print ""
print "OPTIONS:"
print " --all, -a Show all plugins including local-only"
print " --json, -j Output in JSON format"
print " --help, -h Show this help message"
print ""
print "COMMANDS:"
print " status Show plugin status dashboard (default)"
print " update <plugin> <status> Update plugin status manually"
print " summary Show summary statistics only"
print " attention Show only plugins needing attention"
print ""
print "STATUS VALUES:"
print " ✅ ok - Synchronized with upstream"
print " ⚠️ pending - Changes detected - needs review"
print " ❌ error - Error during upstream check"
print " 🔥 conflict - Merge conflicts detected"
print " ❓ unknown - Not yet checked"
print " 🏠 local_only - No upstream - local development"
print ""
print "EXAMPLES:"
print " nu plugin_status.nu # Show status dashboard"
print " nu plugin_status.nu --all # Show all plugins"
print " nu plugin_status.nu summary # Show summary only"
print " nu plugin_status.nu update highlight ok # Mark plugin as OK"
}
# Main function
def main [
command?: string # Command to execute
plugin?: string # Plugin name (for update command)
status?: string # New status (for update command)
--all (-a) # Show all plugins including local-only
--json (-j) # Output in JSON format
--help (-h) # Show help
] {
if $help {
show_help
return
}
# Mandatory version check before any plugin operations
version_check
# Ensure we're in the repository root directory
if not ("nu_plugin_clipboard" | path exists) {
error make {msg: "Please run this script from the nushell-plugins repository root directory"}
}
# Load registry and exclusions
let registry = load_registry
let exclusions = load_exclusions
let filtered_plugins = filter_plugins $registry.plugins $exclusions
match ($command | default "status") {
"status" => {
if $json {
$filtered_plugins | to json
} else {
show_summary $filtered_plugins
show_plugin_table $filtered_plugins $all
show_attention_needed $filtered_plugins
show_recent_activity $filtered_plugins
print $"\n💡 Tips:"
print " • Run 'nu check_upstream_changes.nu' to check for updates"
print " • Use 'nu plugin_status.nu --all' to see all plugins"
print " • Use 'nu plugin_status.nu update <plugin> <status>' to manually update status"
}
},
"summary" => {
show_summary $filtered_plugins
},
"attention" => {
show_attention_needed $filtered_plugins
},
"update" => {
if ($plugin | is-empty) or ($status | is-empty) {
error make {msg: "Update command requires plugin name and status. Use: update <plugin> <status>"}
}
update_plugin_status $plugin $status
},
_ => {
error make {msg: $"Unknown command: ($command). Use --help for usage information."}
}
}
}
if ($env.NUSHELL_EXECUTION_CONTEXT? | default "" | str contains "run") {
main
}