chore: update all plugins to Nushell 0.111.0
Some checks failed
Build and Test / Validate Setup (push) Has been cancelled
Build and Test / Build (darwin-amd64) (push) Has been cancelled
Build and Test / Build (darwin-arm64) (push) Has been cancelled
Build and Test / Build (linux-amd64) (push) Has been cancelled
Build and Test / Build (windows-amd64) (push) Has been cancelled
Build and Test / Build (linux-arm64) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Package Results (push) Has been cancelled
Build and Test / Quality Gate (push) Has been cancelled
Nightly Build / Check for Changes (push) Has been cancelled
Nightly Build / Validate Setup (push) Has been cancelled
Nightly Build / Nightly Build (darwin-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (darwin-arm64) (push) Has been cancelled
Nightly Build / Nightly Build (linux-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (windows-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (linux-arm64) (push) Has been cancelled
Nightly Build / Create Nightly Pre-release (push) Has been cancelled
Nightly Build / Notify Build Status (push) Has been cancelled
Nightly Build / Nightly Maintenance (push) Has been cancelled
Some checks failed
Build and Test / Validate Setup (push) Has been cancelled
Build and Test / Build (darwin-amd64) (push) Has been cancelled
Build and Test / Build (darwin-arm64) (push) Has been cancelled
Build and Test / Build (linux-amd64) (push) Has been cancelled
Build and Test / Build (windows-amd64) (push) Has been cancelled
Build and Test / Build (linux-arm64) (push) Has been cancelled
Build and Test / Security Audit (push) Has been cancelled
Build and Test / Package Results (push) Has been cancelled
Build and Test / Quality Gate (push) Has been cancelled
Nightly Build / Check for Changes (push) Has been cancelled
Nightly Build / Validate Setup (push) Has been cancelled
Nightly Build / Nightly Build (darwin-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (darwin-arm64) (push) Has been cancelled
Nightly Build / Nightly Build (linux-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (windows-amd64) (push) Has been cancelled
Nightly Build / Nightly Build (linux-arm64) (push) Has been cancelled
Nightly Build / Create Nightly Pre-release (push) Has been cancelled
Nightly Build / Notify Build Status (push) Has been cancelled
Nightly Build / Nightly Maintenance (push) Has been cancelled
- Bump all 18 plugins from 0.110.0 to 0.111.0
- Update rust-toolchain.toml channel to 1.93.1 (nu 0.111.0 requires ≥1.91.1)
Fixes:
- interprocess pin =2.2.x → ^2.3.1 in nu_plugin_mcp, nu_plugin_nats, nu_plugin_typedialog
(required by nu-plugin-core 0.111.0)
- nu_plugin_typedialog: BackendType::Web initializer — add open_browser: false field
- nu_plugin_auth: implement missing user_info_to_value helper referenced in tests
Scripts:
- update_all_plugins.nu: fix [package].version update on minor bumps; add [dev-dependencies]
pass; add nu-plugin-test-support to managed crates
- download_nushell.nu: rustup override unset before rm -rf on nushell dir replace;
fix unclosed ) in string interpolation
This commit is contained in:
parent
b6eeaee4da
commit
d9ef2f0d5b
151
CHANGELOG.md
151
CHANGELOG.md
@ -1,10 +1,99 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## [0.111.0] - 2026-03-11 (NUSHELL 0.111.0 COMPATIBILITY)
|
||||||
|
|
||||||
|
### 🔧 Version Update
|
||||||
|
|
||||||
|
- Nushell 0.111.0 compatibility — all 18 plugins updated
|
||||||
|
- `rust-toolchain.toml` channel updated to `1.93.1` (nushell 0.111.0 requires rustc ≥1.91.1)
|
||||||
|
- Removed stale `rustup override` for `nushell/` directory from update toolchain
|
||||||
|
|
||||||
|
### 🐛 Fixes
|
||||||
|
|
||||||
|
- `interprocess` pin updated `=2.2.x` → `^2.3.1` in `nu_plugin_mcp`, `nu_plugin_nats`,
|
||||||
|
`nu_plugin_typedialog` — required by `nu-plugin-core 0.111.0`
|
||||||
|
- `nu_plugin_typedialog`: `BackendType::Web` initializer updated with new `open_browser: false`
|
||||||
|
field added in `typedialog-core`
|
||||||
|
- `nu_plugin_auth`: implemented missing `user_info_to_value` helper referenced in tests
|
||||||
|
- `download_nushell.nu`: fixed unclosed interpolation delimiter in version mismatch warning
|
||||||
|
- `update_all_plugins.nu`: fixed version update to also cover `[package].version` on minor bumps
|
||||||
|
and `[dev-dependencies]` section (`nu-plugin-test-support`); added `nu-plugin-test-support`
|
||||||
|
to managed crates list
|
||||||
|
- `download_nushell.nu`: `rustup override unset` before `rm -rf` on nushell directory replace —
|
||||||
|
prevents stale toolchain overrides surviving source replacement
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.110.0] - 2026-02-10 (TYPEDIALOG + MCP CLIENT PLUGINS)
|
||||||
|
|
||||||
|
### ✨ New Plugins
|
||||||
|
|
||||||
|
#### nu_plugin_typedialog
|
||||||
|
|
||||||
|
- Replaces `provisioning/core/shlib/` bash TTY wrappers with a native Nushell plugin
|
||||||
|
- `typedialog form <path> [--backend cli|web] [--port] [--initial <record>]` — execute
|
||||||
|
interactive form from TOML definition, returns record of results
|
||||||
|
- `typedialog nickel-roundtrip <ncl> <toml> <ncl> [--no-validate]` — read Nickel → form
|
||||||
|
→ write back, returns `{output_nickel, validation_passed, form_results, changed}`
|
||||||
|
- `typedialog text/confirm/select/multi-select/password` — direct prompt primitives
|
||||||
|
- ESC/cancel returns `null` (Value::nothing), never an error
|
||||||
|
- Backed by `typedialog-core` crate with CLI and Web backends
|
||||||
|
- Fixed `interprocess` API break via `=2.2.2` pin (nushell 0.110.0 compat)
|
||||||
|
|
||||||
|
#### nu_plugin_mcp
|
||||||
|
|
||||||
|
- MCP client plugin — spawns `provisioning-mcp-server` as child process
|
||||||
|
- Session state held in `Arc<Mutex<Option<McpSession>>>` on plugin struct (persists across
|
||||||
|
command calls within plugin process lifetime)
|
||||||
|
- `mcp connect <binary> [--provisioning-path]` — MCP handshake (initialize + initialized)
|
||||||
|
- `mcp tools list` — returns table `{name, description, required_args}`
|
||||||
|
- `mcp tool call <name> [--payload <record>]` — dispatches tool, maps content envelope
|
||||||
|
to Nu values (JSON-parsed text or `{error: true, message: ...}` record)
|
||||||
|
- `mcp disconnect` — kills child process, clears session
|
||||||
|
|
||||||
|
### 🔧 Infrastructure
|
||||||
|
|
||||||
|
- `provisioning-mcp-server/src/simple_main.rs` — raw JSON-RPC 2.0 stdio transport
|
||||||
|
replaces broken `rust-mcp-sdk` dependency; 37 tools restored from `main.rs.disabled`
|
||||||
|
- `plugin_registry.toml` — added entries for `nu_plugin_typedialog` and `nu_plugin_mcp`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [0.109.0] - 2025-12-15 (KCL & NICKEL PLUGINS WITH CACHING)
|
||||||
|
|
||||||
|
### ✨ New Features
|
||||||
|
|
||||||
|
#### Configuration Loading Plugins with Caching
|
||||||
|
|
||||||
|
- **nu_plugin_kcl** - Enhanced with automatic caching support
|
||||||
|
- Added `kcl-eval` command for primary config loading with cache
|
||||||
|
- Added `kcl-cache-status` command for cache diagnostics
|
||||||
|
- SHA256-based cache keys: `~/.cache/provisioning/config-cache/`
|
||||||
|
- Expected performance: 20-50x improvement (cache hit ~5ms vs CLI ~300ms)
|
||||||
|
|
||||||
|
- **nu_plugin_nickel** - New independent plugin for Nickel configs
|
||||||
|
- Complete implementation with identical caching architecture
|
||||||
|
- Added `nickel-eval` command for primary config loading with cache
|
||||||
|
- Added `nickel-cache-status` command for cache diagnostics
|
||||||
|
- Shared cache directory with KCL plugin
|
||||||
|
- Commands: `nickel-eval`, `nickel-export`, `nickel-format`, `nickel-validate`, `nickel-cache-status`
|
||||||
|
|
||||||
|
### 🔧 Plugin Registry Enhancements
|
||||||
|
|
||||||
|
- Restructured registry format: `[plugins.*]` nested structure
|
||||||
|
- Added `local_path` field for all plugins
|
||||||
|
- Added `upstream_branch` field for upstream tracking
|
||||||
|
- Added `[settings]` section for managed dependencies
|
||||||
|
- Updated nu_plugin_nickel registry entry with complete metadata
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [0.109.0] - 2025-12-11 (COMPREHENSIVE DOCUMENTATION & COMMIT PREPARATION)
|
## [0.109.0] - 2025-12-11 (COMPREHENSIVE DOCUMENTATION & COMMIT PREPARATION)
|
||||||
|
|
||||||
### 📚 Documentation Updates
|
### 📚 Documentation Updates
|
||||||
|
|
||||||
#### Repository Documentation
|
#### Repository Documentation
|
||||||
|
|
||||||
- **CHANGES.md** (provisioning/core): Complete summary of core system updates
|
- **CHANGES.md** (provisioning/core): Complete summary of core system updates
|
||||||
- CLI, libraries, plugins, and utilities changes
|
- CLI, libraries, plugins, and utilities changes
|
||||||
- File-by-file breakdown organized by directory
|
- File-by-file breakdown organized by directory
|
||||||
@ -16,6 +105,7 @@
|
|||||||
- Ready for: `git commit -F provisioning/core/COMMIT_MESSAGE.md`
|
- Ready for: `git commit -F provisioning/core/COMMIT_MESSAGE.md`
|
||||||
|
|
||||||
#### Repository Documentation (provisioning/)
|
#### Repository Documentation (provisioning/)
|
||||||
|
|
||||||
- **CHANGES.md**: Summary of configuration and documentation updates
|
- **CHANGES.md**: Summary of configuration and documentation updates
|
||||||
- Configuration files (config/, kcl/, core/, extensions/, platform/)
|
- Configuration files (config/, kcl/, core/, extensions/, platform/)
|
||||||
- Documentation updates across all modules
|
- Documentation updates across all modules
|
||||||
@ -41,6 +131,7 @@ All repositories now have:
|
|||||||
### 🎯 Plugin Exclusion System (2025-12-03)
|
### 🎯 Plugin Exclusion System (2025-12-03)
|
||||||
|
|
||||||
#### Architecture Implementation
|
#### Architecture Implementation
|
||||||
|
|
||||||
- **Configuration-Driven Plugin Exclusion**:
|
- **Configuration-Driven Plugin Exclusion**:
|
||||||
- Central registry in `etc/plugin_registry.toml` for managing exclusions
|
- Central registry in `etc/plugin_registry.toml` for managing exclusions
|
||||||
- Single source of truth for which plugins excluded from distributions
|
- Single source of truth for which plugins excluded from distributions
|
||||||
@ -48,23 +139,27 @@ All repositories now have:
|
|||||||
- Future-proof design supporting profiles and conditional exclusions
|
- Future-proof design supporting profiles and conditional exclusions
|
||||||
|
|
||||||
#### Collection System Enhancement (`scripts/collect_full_binaries.nu`)
|
#### Collection System Enhancement (`scripts/collect_full_binaries.nu`)
|
||||||
|
|
||||||
- Added `get_excluded_plugins()` helper function to load exclusion list
|
- Added `get_excluded_plugins()` helper function to load exclusion list
|
||||||
- Updated `get_workspace_plugins_info()` to filter excluded workspace plugins
|
- Updated `get_workspace_plugins_info()` to filter excluded workspace plugins
|
||||||
- Updated `get_custom_plugins_info()` to filter excluded custom plugins
|
- Updated `get_custom_plugins_info()` to filter excluded custom plugins
|
||||||
- Distribution collections now exclude specified plugins automatically
|
- Distribution collections now exclude specified plugins automatically
|
||||||
|
|
||||||
#### Packaging System Enhancement (`scripts/create_distribution_packages.nu`)
|
#### Packaging System Enhancement (`scripts/create_distribution_packages.nu`)
|
||||||
|
|
||||||
- Added `get_excluded_plugins_dist()` helper function
|
- Added `get_excluded_plugins_dist()` helper function
|
||||||
- Updated `get_plugin_components()` to filter both custom and workspace excluded plugins
|
- Updated `get_plugin_components()` to filter both custom and workspace excluded plugins
|
||||||
- Distribution packages now exclude specified plugins automatically
|
- Distribution packages now exclude specified plugins automatically
|
||||||
- Consistent filtering with collection system
|
- Consistent filtering with collection system
|
||||||
|
|
||||||
#### Installation Configuration (`scripts/templates/default_config.nu`)
|
#### Installation Configuration (`scripts/templates/default_config.nu`)
|
||||||
|
|
||||||
- Removed excluded plugins from auto-load plugin list
|
- Removed excluded plugins from auto-load plugin list
|
||||||
- Added documentation explaining why plugins are excluded
|
- Added documentation explaining why plugins are excluded
|
||||||
- Users won't see missing plugin errors in fresh installations
|
- Users won't see missing plugin errors in fresh installations
|
||||||
|
|
||||||
#### Documentation - Complete Coverage
|
#### Documentation - Complete Coverage
|
||||||
|
|
||||||
- **User Guide**: `docs/PLUGIN_EXCLUSION_GUIDE.md` (400+ lines)
|
- **User Guide**: `docs/PLUGIN_EXCLUSION_GUIDE.md` (400+ lines)
|
||||||
- Quick start for users, developers, release managers
|
- Quick start for users, developers, release managers
|
||||||
- Common tasks with step-by-step instructions
|
- Common tasks with step-by-step instructions
|
||||||
@ -107,6 +202,7 @@ All repositories now have:
|
|||||||
- Testing validation
|
- Testing validation
|
||||||
|
|
||||||
#### Configuration Updates
|
#### Configuration Updates
|
||||||
|
|
||||||
- **Registry**: `etc/plugin_registry.toml`
|
- **Registry**: `etc/plugin_registry.toml`
|
||||||
- Added `[distribution]` section with `excluded_plugins` list
|
- Added `[distribution]` section with `excluded_plugins` list
|
||||||
- Marked `nu_plugin_example` as excluded with reason documentation
|
- Marked `nu_plugin_example` as excluded with reason documentation
|
||||||
@ -114,12 +210,14 @@ All repositories now have:
|
|||||||
#### Files Modified (9 files total)
|
#### Files Modified (9 files total)
|
||||||
|
|
||||||
**Implementation** (4 files):
|
**Implementation** (4 files):
|
||||||
|
|
||||||
- `etc/plugin_registry.toml` - Config: Added `[distribution]` section
|
- `etc/plugin_registry.toml` - Config: Added `[distribution]` section
|
||||||
- `scripts/collect_full_binaries.nu` - Feature: Added filtering functions
|
- `scripts/collect_full_binaries.nu` - Feature: Added filtering functions
|
||||||
- `scripts/create_distribution_packages.nu` - Feature: Added filtering functions
|
- `scripts/create_distribution_packages.nu` - Feature: Added filtering functions
|
||||||
- `scripts/templates/default_config.nu` - Config: Removed excluded from auto-load
|
- `scripts/templates/default_config.nu` - Config: Removed excluded from auto-load
|
||||||
|
|
||||||
**Documentation** (5 files):
|
**Documentation** (5 files):
|
||||||
|
|
||||||
- `docs/PLUGIN_EXCLUSION_GUIDE.md` - NEW: User guide
|
- `docs/PLUGIN_EXCLUSION_GUIDE.md` - NEW: User guide
|
||||||
- `docs/architecture/README.md` - NEW: Navigation index
|
- `docs/architecture/README.md` - NEW: Navigation index
|
||||||
- `docs/architecture/PLUGIN_EXCLUSION_SYSTEM.md` - NEW: Technical spec
|
- `docs/architecture/PLUGIN_EXCLUSION_SYSTEM.md` - NEW: Technical spec
|
||||||
@ -128,6 +226,7 @@ All repositories now have:
|
|||||||
- `docs/PROVISIONING_PLUGINS_SUMMARY.md` - UPDATED: Added links
|
- `docs/PROVISIONING_PLUGINS_SUMMARY.md` - UPDATED: Added links
|
||||||
|
|
||||||
#### Impact & Behavior Changes
|
#### Impact & Behavior Changes
|
||||||
|
|
||||||
- ✅ Build system UNCHANGED - all plugins still built
|
- ✅ Build system UNCHANGED - all plugins still built
|
||||||
- ✅ Test system UNCHANGED - all plugins still tested
|
- ✅ Test system UNCHANGED - all plugins still tested
|
||||||
- ✅ Dev workflows UNCHANGED - developers can use excluded plugins
|
- ✅ Dev workflows UNCHANGED - developers can use excluded plugins
|
||||||
@ -136,6 +235,7 @@ All repositories now have:
|
|||||||
- ❌ Auto-load NOW excludes specified plugins from user configs
|
- ❌ Auto-load NOW excludes specified plugins from user configs
|
||||||
|
|
||||||
#### Example: nu_plugin_example
|
#### Example: nu_plugin_example
|
||||||
|
|
||||||
- ✅ Still built with `just build`
|
- ✅ Still built with `just build`
|
||||||
- ✅ Still tested with `just test`
|
- ✅ Still tested with `just test`
|
||||||
- ✅ Still available in build output for reference
|
- ✅ Still available in build output for reference
|
||||||
@ -144,6 +244,7 @@ All repositories now have:
|
|||||||
- ❌ NOT auto-loaded in user installations
|
- ❌ NOT auto-loaded in user installations
|
||||||
|
|
||||||
#### Testing & Verification
|
#### Testing & Verification
|
||||||
|
|
||||||
- ✅ Registry parses correctly
|
- ✅ Registry parses correctly
|
||||||
- ✅ Collection system excludes plugins
|
- ✅ Collection system excludes plugins
|
||||||
- ✅ Packaging system excludes plugins
|
- ✅ Packaging system excludes plugins
|
||||||
@ -154,6 +255,7 @@ All repositories now have:
|
|||||||
- ✅ All 1,400+ lines of documentation complete
|
- ✅ All 1,400+ lines of documentation complete
|
||||||
|
|
||||||
#### Quality Metrics
|
#### Quality Metrics
|
||||||
|
|
||||||
- **Code Changes**: 40 lines added, 1 line removed (net +39)
|
- **Code Changes**: 40 lines added, 1 line removed (net +39)
|
||||||
- **Documentation**: 1,400+ lines of comprehensive coverage
|
- **Documentation**: 1,400+ lines of comprehensive coverage
|
||||||
- **Error Handling**: 100% graceful degradation
|
- **Error Handling**: 100% graceful degradation
|
||||||
@ -168,6 +270,7 @@ All repositories now have:
|
|||||||
### 🚀 Bootstrap Installer & Distribution Improvements (2025-10-19)
|
### 🚀 Bootstrap Installer & Distribution Improvements (2025-10-19)
|
||||||
|
|
||||||
#### Install Script Architecture (DRY Design)
|
#### Install Script Architecture (DRY Design)
|
||||||
|
|
||||||
- **Implemented Symlink-Based DRY Architecture**:
|
- **Implemented Symlink-Based DRY Architecture**:
|
||||||
- Single source of truth: `installers/bootstrap/install.sh` (1,247 lines)
|
- Single source of truth: `installers/bootstrap/install.sh` (1,247 lines)
|
||||||
- Symlinks: `./install.sh` → `installers/bootstrap/install.sh`
|
- Symlinks: `./install.sh` → `installers/bootstrap/install.sh`
|
||||||
@ -176,6 +279,7 @@ All repositories now have:
|
|||||||
- No code duplication across installation paths
|
- No code duplication across installation paths
|
||||||
|
|
||||||
#### Archive Extraction Fixes (Critical)
|
#### Archive Extraction Fixes (Critical)
|
||||||
|
|
||||||
- **Fixed Archive Binary Detection (Version-Agnostic)**:
|
- **Fixed Archive Binary Detection (Version-Agnostic)**:
|
||||||
- Root cause: `find` command returning parent directory itself in results
|
- Root cause: `find` command returning parent directory itself in results
|
||||||
- Solution: Added `-not -path "$extract_dir"` to exclude starting directory
|
- Solution: Added `-not -path "$extract_dir"` to exclude starting directory
|
||||||
@ -191,6 +295,7 @@ All repositories now have:
|
|||||||
- Validates binaries exist before using them
|
- Validates binaries exist before using them
|
||||||
|
|
||||||
#### Plugin Registration Error Handling
|
#### Plugin Registration Error Handling
|
||||||
|
|
||||||
- **Improved Plugin Registration with Version Mismatch Detection**:
|
- **Improved Plugin Registration with Version Mismatch Detection**:
|
||||||
- Captures both stdout and stderr from plugin add commands
|
- Captures both stdout and stderr from plugin add commands
|
||||||
- Detects version incompatibility errors: "is not compatible with version"
|
- Detects version incompatibility errors: "is not compatible with version"
|
||||||
@ -202,6 +307,7 @@ All repositories now have:
|
|||||||
- Installation continues successfully even with version mismatches
|
- Installation continues successfully even with version mismatches
|
||||||
|
|
||||||
#### Shell Configuration PATH Update Messaging
|
#### Shell Configuration PATH Update Messaging
|
||||||
|
|
||||||
- **Fixed Confusing PATH Update Messages**:
|
- **Fixed Confusing PATH Update Messages**:
|
||||||
- Root cause: Script conflated "PATH found" with "PATH needs updating"
|
- Root cause: Script conflated "PATH found" with "PATH needs updating"
|
||||||
- Solution: Track two separate states:
|
- Solution: Track two separate states:
|
||||||
@ -213,6 +319,7 @@ All repositories now have:
|
|||||||
- ⚠️ "Could not find..." (when file doesn't exist)
|
- ⚠️ "Could not find..." (when file doesn't exist)
|
||||||
|
|
||||||
#### Installation Features
|
#### Installation Features
|
||||||
|
|
||||||
- **`--source-path` Option for Local Installation**:
|
- **`--source-path` Option for Local Installation**:
|
||||||
- Install from local archive: `--source-path archive.tar.gz`
|
- Install from local archive: `--source-path archive.tar.gz`
|
||||||
- Install from local directory: `--source-path /path/to/binaries`
|
- Install from local directory: `--source-path /path/to/binaries`
|
||||||
@ -226,6 +333,7 @@ All repositories now have:
|
|||||||
- Preserves user choice (keep or remove config)
|
- Preserves user choice (keep or remove config)
|
||||||
|
|
||||||
#### Documentation Updates
|
#### Documentation Updates
|
||||||
|
|
||||||
- **Updated CLAUDE.md** with:
|
- **Updated CLAUDE.md** with:
|
||||||
- Install Script Architecture (DRY Design) section
|
- Install Script Architecture (DRY Design) section
|
||||||
- Source of truth location and symlink structure
|
- Source of truth location and symlink structure
|
||||||
@ -241,6 +349,7 @@ All repositories now have:
|
|||||||
- How DRY Works (3-step explanation)
|
- How DRY Works (3-step explanation)
|
||||||
|
|
||||||
#### Files Modified
|
#### Files Modified
|
||||||
|
|
||||||
- `installers/bootstrap/install.sh` - All fixes (1,247 lines, +3 lines)
|
- `installers/bootstrap/install.sh` - All fixes (1,247 lines, +3 lines)
|
||||||
- `./install.sh` - Auto-updated via symlink
|
- `./install.sh` - Auto-updated via symlink
|
||||||
- `./scripts/templates/install.sh` - Auto-updated via symlink
|
- `./scripts/templates/install.sh` - Auto-updated via symlink
|
||||||
@ -248,6 +357,7 @@ All repositories now have:
|
|||||||
- `README.md` - Added install script section
|
- `README.md` - Added install script section
|
||||||
|
|
||||||
#### Testing & Verification
|
#### Testing & Verification
|
||||||
|
|
||||||
- ✅ Archive extraction works with version-agnostic detection
|
- ✅ Archive extraction works with version-agnostic detection
|
||||||
- ✅ Installation to `~/.local` successful (16 binaries)
|
- ✅ Installation to `~/.local` successful (16 binaries)
|
||||||
- ✅ Installation to `~/.local/bin` successful (21 plugins loaded)
|
- ✅ Installation to `~/.local/bin` successful (21 plugins loaded)
|
||||||
@ -256,6 +366,7 @@ All repositories now have:
|
|||||||
- ✅ Clean uninstall followed by fresh reinstall works perfectly
|
- ✅ Clean uninstall followed by fresh reinstall works perfectly
|
||||||
|
|
||||||
#### Impact
|
#### Impact
|
||||||
|
|
||||||
- ✅ Users can install from any version of nushell-full archive
|
- ✅ Users can install from any version of nushell-full archive
|
||||||
- ✅ Clear error messages if binaries not found in archive
|
- ✅ Clear error messages if binaries not found in archive
|
||||||
- ✅ Version mismatch plugins skipped without breaking installation
|
- ✅ Version mismatch plugins skipped without breaking installation
|
||||||
@ -270,6 +381,7 @@ All repositories now have:
|
|||||||
### 🎯 Help System & Build Process Fixes (2025-10-19)
|
### 🎯 Help System & Build Process Fixes (2025-10-19)
|
||||||
|
|
||||||
#### Help System Improvements
|
#### Help System Improvements
|
||||||
|
|
||||||
- **Added Version Update Module to Help System**:
|
- **Added Version Update Module to Help System**:
|
||||||
- Version-update module now discoverable via `just help modules`
|
- Version-update module now discoverable via `just help modules`
|
||||||
- Added to `just help` main output with key commands
|
- Added to `just help` main output with key commands
|
||||||
@ -277,11 +389,13 @@ All repositories now have:
|
|||||||
- Full integration into help system navigation
|
- Full integration into help system navigation
|
||||||
|
|
||||||
#### New Help Commands
|
#### New Help Commands
|
||||||
|
|
||||||
- **`just commands`**: New recipe showing all commands organized by group (alias for `just --list`)
|
- **`just commands`**: New recipe showing all commands organized by group (alias for `just --list`)
|
||||||
- Shows [version-update] group with all 30+ update recipes
|
- Shows [version-update] group with all 30+ update recipes
|
||||||
- Replaces need to manually run `just --list`
|
- Replaces need to manually run `just --list`
|
||||||
|
|
||||||
#### Build Process Fixes
|
#### Build Process Fixes
|
||||||
|
|
||||||
- **Fixed Plugin Archive Creation Bug**:
|
- **Fixed Plugin Archive Creation Bug**:
|
||||||
- Phase 3 "No plugins found" warning fixed
|
- Phase 3 "No plugins found" warning fixed
|
||||||
- Root cause: `each` command returns null, breaking count logic
|
- Root cause: `each` command returns null, breaking count logic
|
||||||
@ -301,6 +415,7 @@ All repositories now have:
|
|||||||
- Properly calculates archive file size in MB
|
- Properly calculates archive file size in MB
|
||||||
|
|
||||||
#### Plugin Dependency Update Optimization
|
#### Plugin Dependency Update Optimization
|
||||||
|
|
||||||
- **Fixed Unnecessary Plugin Rebuilds**:
|
- **Fixed Unnecessary Plugin Rebuilds**:
|
||||||
- Root cause: `update_all_plugins.nu` always touched all Cargo.toml files
|
- Root cause: `update_all_plugins.nu` always touched all Cargo.toml files
|
||||||
- Solution: Only save if content actually changed
|
- Solution: Only save if content actually changed
|
||||||
@ -309,6 +424,7 @@ All repositories now have:
|
|||||||
- Result: Only plugins with real changes trigger rebuilds (hashes, highlight)
|
- Result: Only plugins with real changes trigger rebuilds (hashes, highlight)
|
||||||
|
|
||||||
#### Files Modified
|
#### Files Modified
|
||||||
|
|
||||||
- `justfiles/help.just` - Added version-update module to help system
|
- `justfiles/help.just` - Added version-update module to help system
|
||||||
- `scripts/create_full_distribution.nu` - Fixed plugin collection filtering (exclude .d files)
|
- `scripts/create_full_distribution.nu` - Fixed plugin collection filtering (exclude .d files)
|
||||||
- `scripts/create_distribution_packages.nu` - Fixed get_plugin_components to look in correct directories
|
- `scripts/create_distribution_packages.nu` - Fixed get_plugin_components to look in correct directories
|
||||||
@ -316,6 +432,7 @@ All repositories now have:
|
|||||||
- `CHANGELOG.md` - Documented all fixes
|
- `CHANGELOG.md` - Documented all fixes
|
||||||
|
|
||||||
#### Archive Content & Structure Fixes (Critical Fix)
|
#### Archive Content & Structure Fixes (Critical Fix)
|
||||||
|
|
||||||
- **Fixed nushell-full archive missing plugins**:
|
- **Fixed nushell-full archive missing plugins**:
|
||||||
- Root cause: `get_plugin_components` looked in distribution directory (staging output)
|
- Root cause: `get_plugin_components` looked in distribution directory (staging output)
|
||||||
- Solution: Look in `nu_plugin_*/target/release/` (actual binaries)
|
- Solution: Look in `nu_plugin_*/target/release/` (actual binaries)
|
||||||
@ -343,6 +460,7 @@ All repositories now have:
|
|||||||
- Reduces archive size and keeps distribution focused
|
- Reduces archive size and keeps distribution focused
|
||||||
|
|
||||||
#### Impact
|
#### Impact
|
||||||
|
|
||||||
- ✅ Version-update commands now fully discoverable
|
- ✅ Version-update commands now fully discoverable
|
||||||
- ✅ Phase 3 bin archive creation works correctly
|
- ✅ Phase 3 bin archive creation works correctly
|
||||||
- ✅ nushell-full archive contains nu + all plugins
|
- ✅ nushell-full archive contains nu + all plugins
|
||||||
@ -357,23 +475,27 @@ All repositories now have:
|
|||||||
### 🎯 Nushell Core Update: 0.107.1 → 0.108.0
|
### 🎯 Nushell Core Update: 0.107.1 → 0.108.0
|
||||||
|
|
||||||
#### Major Changes
|
#### Major Changes
|
||||||
|
|
||||||
- **Updated Nushell to 0.108.0** with MCP (Model Context Protocol) support
|
- **Updated Nushell to 0.108.0** with MCP (Model Context Protocol) support
|
||||||
- **Fixed critical documentation bugs** in `best_nushell_code.md` affecting all code generation
|
- **Fixed critical documentation bugs** in `best_nushell_code.md` affecting all code generation
|
||||||
- **Created comprehensive automation framework** for future version updates
|
- **Created comprehensive automation framework** for future version updates
|
||||||
- **Built complete distribution** with nushell 0.108.0 + all plugins
|
- **Built complete distribution** with nushell 0.108.0 + all plugins
|
||||||
|
|
||||||
#### Critical Bug Fixes
|
#### Critical Bug Fixes
|
||||||
|
|
||||||
- **Rule 16 (Function Signatures)**: Fixed incorrect syntax `]: type {` → `]: nothing -> type {`
|
- **Rule 16 (Function Signatures)**: Fixed incorrect syntax `]: type {` → `]: nothing -> type {`
|
||||||
- **Rule 17 (String Interpolation)**: Fixed non-working syntax `[$var]` → `($var)`
|
- **Rule 17 (String Interpolation)**: Fixed non-working syntax `[$var]` → `($var)`
|
||||||
- Both bugs were in documentation and caused all generated code to fail parsing
|
- Both bugs were in documentation and caused all generated code to fail parsing
|
||||||
|
|
||||||
#### New Features
|
#### New Features
|
||||||
|
|
||||||
- ✅ **MCP Support**: Model Context Protocol for AI agent integration
|
- ✅ **MCP Support**: Model Context Protocol for AI agent integration
|
||||||
- ✅ **Enhanced SQLite**: Improved database operations
|
- ✅ **Enhanced SQLite**: Improved database operations
|
||||||
- ✅ **System Clipboard**: Native clipboard integration
|
- ✅ **System Clipboard**: Native clipboard integration
|
||||||
- ✅ **Trash Support**: Safe file deletion to trash
|
- ✅ **Trash Support**: Safe file deletion to trash
|
||||||
|
|
||||||
#### Breaking Changes
|
#### Breaking Changes
|
||||||
|
|
||||||
- **`into value` → `detect type`**: Command deprecated (still works with warning)
|
- **`into value` → `detect type`**: Command deprecated (still works with warning)
|
||||||
- Shows helpful migration message
|
- Shows helpful migration message
|
||||||
- Recommends `update cells {detect type}` instead
|
- Recommends `update cells {detect type}` instead
|
||||||
@ -382,6 +504,7 @@ All repositories now have:
|
|||||||
- Requires explicit error handling with `try`/`catch`
|
- Requires explicit error handling with `try`/`catch`
|
||||||
|
|
||||||
#### New Automation Scripts (8 scripts created)
|
#### New Automation Scripts (8 scripts created)
|
||||||
|
|
||||||
1. **`download_nushell.nu`** (285 lines) - Download from GitHub tags
|
1. **`download_nushell.nu`** (285 lines) - Download from GitHub tags
|
||||||
2. **`analyze_nushell_features.nu`** (350 lines) - Parse and validate features
|
2. **`analyze_nushell_features.nu`** (350 lines) - Parse and validate features
|
||||||
3. **`audit_crate_dependencies.nu`** (390 lines) - Audit plugin dependencies
|
3. **`audit_crate_dependencies.nu`** (390 lines) - Audit plugin dependencies
|
||||||
@ -392,18 +515,21 @@ All repositories now have:
|
|||||||
8. **`complete_update.nu`** (NEW) - All-in-one update script
|
8. **`complete_update.nu`** (NEW) - All-in-one update script
|
||||||
|
|
||||||
#### Documentation Created
|
#### Documentation Created
|
||||||
|
|
||||||
- **`updates/108/NUSHELL_0.108_UPDATE_SUMMARY.md`** - Complete update summary
|
- **`updates/108/NUSHELL_0.108_UPDATE_SUMMARY.md`** - Complete update summary
|
||||||
- **`updates/108/MIGRATION_0.108.0.md`** - Step-by-step migration guide
|
- **`updates/108/MIGRATION_0.108.0.md`** - Step-by-step migration guide
|
||||||
- **`updates/108/NUSHELL_UPDATE_AUTOMATION.md`** - Automation documentation
|
- **`updates/108/NUSHELL_UPDATE_AUTOMATION.md`** - Automation documentation
|
||||||
- **`guides/COMPLETE_VERSION_UPDATE_GUIDE.md`** - Comprehensive update guide
|
- **`guides/COMPLETE_VERSION_UPDATE_GUIDE.md`** - Comprehensive update guide
|
||||||
|
|
||||||
#### Build System Improvements
|
#### Build System Improvements
|
||||||
|
|
||||||
- **Build Time**: Optimized to 2m 55s (from 15+ minutes)
|
- **Build Time**: Optimized to 2m 55s (from 15+ minutes)
|
||||||
- **Features**: All desired features validated and included
|
- **Features**: All desired features validated and included
|
||||||
- **Workspace**: Proper `--workspace` flag for system plugins
|
- **Workspace**: Proper `--workspace` flag for system plugins
|
||||||
- **Artifacts**: Complete binary collection system
|
- **Artifacts**: Complete binary collection system
|
||||||
|
|
||||||
#### Validation & Testing
|
#### Validation & Testing
|
||||||
|
|
||||||
- ✅ All syntax patterns tested against actual 0.108.0 binary
|
- ✅ All syntax patterns tested against actual 0.108.0 binary
|
||||||
- ✅ Function signatures validated
|
- ✅ Function signatures validated
|
||||||
- ✅ String interpolation validated
|
- ✅ String interpolation validated
|
||||||
@ -412,12 +538,14 @@ All repositories now have:
|
|||||||
- ✅ Breaking changes verified
|
- ✅ Breaking changes verified
|
||||||
|
|
||||||
#### Impact
|
#### Impact
|
||||||
|
|
||||||
- **Developer Experience**: 80% reduction in update time with automation
|
- **Developer Experience**: 80% reduction in update time with automation
|
||||||
- **Code Quality**: All future code will use correct syntax
|
- **Code Quality**: All future code will use correct syntax
|
||||||
- **Maintainability**: Semi-automated updates with 3 manual checkpoints
|
- **Maintainability**: Semi-automated updates with 3 manual checkpoints
|
||||||
- **Documentation**: Comprehensive guides for all future updates
|
- **Documentation**: Comprehensive guides for all future updates
|
||||||
|
|
||||||
#### Files Modified
|
#### Files Modified
|
||||||
|
|
||||||
- `best_nushell_code.md` - Fixed Rules 16 & 17, Quick Reference, Summary
|
- `best_nushell_code.md` - Fixed Rules 16 & 17, Quick Reference, Summary
|
||||||
- `nushell/` - Updated to 0.108.0
|
- `nushell/` - Updated to 0.108.0
|
||||||
- `nu_plugin_*/Cargo.toml` - Dependency versions updated
|
- `nu_plugin_*/Cargo.toml` - Dependency versions updated
|
||||||
@ -426,6 +554,7 @@ All repositories now have:
|
|||||||
- `guides/` - New comprehensive guide
|
- `guides/` - New comprehensive guide
|
||||||
|
|
||||||
#### Migration Notes
|
#### Migration Notes
|
||||||
|
|
||||||
- Old `into value` usage still works but shows deprecation warning
|
- Old `into value` usage still works but shows deprecation warning
|
||||||
- Update to `detect type` or `update cells {detect type}` to remove warnings
|
- Update to `detect type` or `update cells {detect type}` to remove warnings
|
||||||
- Stream collection operations may need `try`/`catch` for error handling
|
- Stream collection operations may need `try`/`catch` for error handling
|
||||||
@ -438,6 +567,7 @@ All repositories now have:
|
|||||||
### 🚀 Major Feature: Complete Nushell Distribution System
|
### 🚀 Major Feature: Complete Nushell Distribution System
|
||||||
|
|
||||||
#### Full Distribution Infrastructure
|
#### Full Distribution Infrastructure
|
||||||
|
|
||||||
- **Complete Nushell binary distribution**: Added capability to build, package, and distribute Nushell itself alongside plugins
|
- **Complete Nushell binary distribution**: Added capability to build, package, and distribute Nushell itself alongside plugins
|
||||||
- **Zero-prerequisite installation**: Users can install complete Nushell environment without having Rust, Cargo, or Nushell pre-installed
|
- **Zero-prerequisite installation**: Users can install complete Nushell environment without having Rust, Cargo, or Nushell pre-installed
|
||||||
- **Cross-platform bootstrap installers**: Universal POSIX shell installer (`install.sh`) and Windows PowerShell installer (`install.ps1`)
|
- **Cross-platform bootstrap installers**: Universal POSIX shell installer (`install.sh`) and Windows PowerShell installer (`install.ps1`)
|
||||||
@ -445,6 +575,7 @@ All repositories now have:
|
|||||||
- **Self-contained distribution packages**: Complete packages including binaries, configuration, documentation, and installers
|
- **Self-contained distribution packages**: Complete packages including binaries, configuration, documentation, and installers
|
||||||
|
|
||||||
#### New Build System
|
#### New Build System
|
||||||
|
|
||||||
- **`scripts/build_nushell.nu`**: Comprehensive script to build nushell with all workspace plugins
|
- **`scripts/build_nushell.nu`**: Comprehensive script to build nushell with all workspace plugins
|
||||||
- **`scripts/collect_full_binaries.nu`**: Advanced binary collection system for nushell + all plugins
|
- **`scripts/collect_full_binaries.nu`**: Advanced binary collection system for nushell + all plugins
|
||||||
- **`scripts/create_distribution_packages.nu`**: Multi-platform package creator with manifest generation
|
- **`scripts/create_distribution_packages.nu`**: Multi-platform package creator with manifest generation
|
||||||
@ -452,6 +583,7 @@ All repositories now have:
|
|||||||
- **Enhanced justfile**: Added 40+ new recipes in `justfiles/full_distro.just` for complete distribution workflows
|
- **Enhanced justfile**: Added 40+ new recipes in `justfiles/full_distro.just` for complete distribution workflows
|
||||||
|
|
||||||
#### Installation and Configuration System
|
#### Installation and Configuration System
|
||||||
|
|
||||||
- **`scripts/install_full_nushell.nu`**: Advanced nu-based installer with plugin selection and configuration options
|
- **`scripts/install_full_nushell.nu`**: Advanced nu-based installer with plugin selection and configuration options
|
||||||
- **`scripts/verify_installation.nu`**: Comprehensive installation verification with detailed reporting
|
- **`scripts/verify_installation.nu`**: Comprehensive installation verification with detailed reporting
|
||||||
- **`scripts/templates/default_config.nu`**: Complete 500+ line Nushell configuration with optimizations
|
- **`scripts/templates/default_config.nu`**: Complete 500+ line Nushell configuration with optimizations
|
||||||
@ -459,6 +591,7 @@ All repositories now have:
|
|||||||
- **`etc/distribution_config.toml`**: Central distribution configuration management
|
- **`etc/distribution_config.toml`**: Central distribution configuration management
|
||||||
|
|
||||||
#### Bootstrap Installers (Zero Prerequisites)
|
#### Bootstrap Installers (Zero Prerequisites)
|
||||||
|
|
||||||
- **`installers/bootstrap/install.sh`**: 900+ line universal POSIX installer for Linux/macOS
|
- **`installers/bootstrap/install.sh`**: 900+ line universal POSIX installer for Linux/macOS
|
||||||
- Automatic platform detection and binary download
|
- Automatic platform detection and binary download
|
||||||
- Build from source fallback capability
|
- Build from source fallback capability
|
||||||
@ -468,12 +601,15 @@ All repositories now have:
|
|||||||
- **Complete documentation**: Installation guides, troubleshooting, and security considerations
|
- **Complete documentation**: Installation guides, troubleshooting, and security considerations
|
||||||
|
|
||||||
#### Uninstall System
|
#### Uninstall System
|
||||||
|
|
||||||
- **`scripts/templates/uninstall.sh`** and **`uninstall.ps1`**: Clean removal scripts for all platforms
|
- **`scripts/templates/uninstall.sh`** and **`uninstall.ps1`**: Clean removal scripts for all platforms
|
||||||
- **Complete cleanup**: Removes binaries, configurations, PATH entries with optional backup
|
- **Complete cleanup**: Removes binaries, configurations, PATH entries with optional backup
|
||||||
- **Plugin unregistration**: Clean removal from nushell registry
|
- **Plugin unregistration**: Clean removal from nushell registry
|
||||||
|
|
||||||
#### Key Distribution Workflows
|
#### Key Distribution Workflows
|
||||||
```bash
|
|
||||||
|
```nushell
|
||||||
|
bash
|
||||||
# Build complete distribution
|
# Build complete distribution
|
||||||
just build-full # Build nushell + all plugins
|
just build-full # Build nushell + all plugins
|
||||||
|
|
||||||
@ -489,6 +625,7 @@ just release-full-cross # Full cross-platform release
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Installation Experience
|
#### Installation Experience
|
||||||
|
|
||||||
- **One-liner installation**: `curl -sSf https://your-url/install.sh | sh`
|
- **One-liner installation**: `curl -sSf https://your-url/install.sh | sh`
|
||||||
- **Multiple installation modes**: User (~/.local/bin), system (/usr/local/bin), portable
|
- **Multiple installation modes**: User (~/.local/bin), system (/usr/local/bin), portable
|
||||||
- **Automatic plugin registration**: All plugins registered and verified with `nu -c "plugin list"`
|
- **Automatic plugin registration**: All plugins registered and verified with `nu -c "plugin list"`
|
||||||
@ -497,6 +634,7 @@ just release-full-cross # Full cross-platform release
|
|||||||
### 🎯 Major Updates
|
### 🎯 Major Updates
|
||||||
|
|
||||||
#### Documentation and Repository Structure
|
#### Documentation and Repository Structure
|
||||||
|
|
||||||
- **Enhanced README.md**: Significantly expanded documentation with 682 new lines covering:
|
- **Enhanced README.md**: Significantly expanded documentation with 682 new lines covering:
|
||||||
- Comprehensive plugin collection overview
|
- Comprehensive plugin collection overview
|
||||||
- Detailed development workflows and automation
|
- Detailed development workflows and automation
|
||||||
@ -505,12 +643,14 @@ just release-full-cross # Full cross-platform release
|
|||||||
- Complete command reference and usage examples
|
- Complete command reference and usage examples
|
||||||
|
|
||||||
#### Script and Automation Cleanup
|
#### Script and Automation Cleanup
|
||||||
|
|
||||||
- **Removed legacy scripts**: Cleaned up old bash scripts (build-all.sh, collect-install.sh, make_plugin.sh)
|
- **Removed legacy scripts**: Cleaned up old bash scripts (build-all.sh, collect-install.sh, make_plugin.sh)
|
||||||
- **Streamlined automation**: Consolidated script system in favor of unified approach via justfile and nushell scripts
|
- **Streamlined automation**: Consolidated script system in favor of unified approach via justfile and nushell scripts
|
||||||
|
|
||||||
### 🔧 Plugin Updates and Dependency Management
|
### 🔧 Plugin Updates and Dependency Management
|
||||||
|
|
||||||
#### Nushell Core Updates
|
#### Nushell Core Updates
|
||||||
|
|
||||||
- **Updated nushell submodule**: Comprehensive update to latest nushell version (0.107.1)
|
- **Updated nushell submodule**: Comprehensive update to latest nushell version (0.107.1)
|
||||||
- **Synchronized dependencies**: Updated all nu-* dependencies across all plugins for version consistency
|
- **Synchronized dependencies**: Updated all nu-* dependencies across all plugins for version consistency
|
||||||
- **Updated Cargo.lock files**: Refreshed dependency lock files for all plugins
|
- **Updated Cargo.lock files**: Refreshed dependency lock files for all plugins
|
||||||
@ -518,25 +658,30 @@ just release-full-cross # Full cross-platform release
|
|||||||
#### Plugin-Specific Changes
|
#### Plugin-Specific Changes
|
||||||
|
|
||||||
##### nu_plugin_clipboard
|
##### nu_plugin_clipboard
|
||||||
|
|
||||||
- Updated Cargo.toml with new dependency versions
|
- Updated Cargo.toml with new dependency versions
|
||||||
- Refreshed Cargo.lock with 253 dependency changes
|
- Refreshed Cargo.lock with 253 dependency changes
|
||||||
|
|
||||||
##### nu_plugin_desktop_notifications
|
##### nu_plugin_desktop_notifications
|
||||||
|
|
||||||
- Updated Cargo.toml for nushell 0.107.1 compatibility
|
- Updated Cargo.toml for nushell 0.107.1 compatibility
|
||||||
- Refreshed Cargo.lock with 218 dependency updates
|
- Refreshed Cargo.lock with 218 dependency updates
|
||||||
|
|
||||||
##### nu_plugin_hashes
|
##### nu_plugin_hashes
|
||||||
|
|
||||||
- **Enhanced functionality**: Updated hasher.rs implementation
|
- **Enhanced functionality**: Updated hasher.rs implementation
|
||||||
- **Build system improvements**: Modified build.rs configuration
|
- **Build system improvements**: Modified build.rs configuration
|
||||||
- Updated Cargo.toml with 24 configuration changes
|
- Updated Cargo.toml with 24 configuration changes
|
||||||
- Refreshed Cargo.lock with 283 dependency updates
|
- Refreshed Cargo.lock with 283 dependency updates
|
||||||
|
|
||||||
##### nu_plugin_highlight
|
##### nu_plugin_highlight
|
||||||
|
|
||||||
- **Code improvements**: Enhanced highlight.rs and plugin.rs implementations
|
- **Code improvements**: Enhanced highlight.rs and plugin.rs implementations
|
||||||
- Updated for new nushell plugin API compatibility
|
- Updated for new nushell plugin API compatibility
|
||||||
- Refreshed Cargo.lock with 476 dependency updates
|
- Refreshed Cargo.lock with 476 dependency updates
|
||||||
|
|
||||||
##### nu_plugin_image
|
##### nu_plugin_image
|
||||||
|
|
||||||
- **Major code refactoring**: Comprehensive updates to image processing modules
|
- **Major code refactoring**: Comprehensive updates to image processing modules
|
||||||
- **Removed deprecated code**: Deleted ansi_to_image.rs (replaced with modular approach)
|
- **Removed deprecated code**: Deleted ansi_to_image.rs (replaced with modular approach)
|
||||||
- **Enhanced modules**:
|
- **Enhanced modules**:
|
||||||
@ -548,19 +693,23 @@ just release-full-cross # Full cross-platform release
|
|||||||
- Refreshed Cargo.lock with 494 dependency updates
|
- Refreshed Cargo.lock with 494 dependency updates
|
||||||
|
|
||||||
##### nu_plugin_kcl and nu_plugin_tera
|
##### nu_plugin_kcl and nu_plugin_tera
|
||||||
|
|
||||||
- Updated submodule references
|
- Updated submodule references
|
||||||
- Synchronized with latest upstream changes
|
- Synchronized with latest upstream changes
|
||||||
|
|
||||||
##### nu_plugin_port_extension and nu_plugin_qr_maker
|
##### nu_plugin_port_extension and nu_plugin_qr_maker
|
||||||
|
|
||||||
- Updated Cargo.toml for version consistency
|
- Updated Cargo.toml for version consistency
|
||||||
- Refreshed Cargo.lock files
|
- Refreshed Cargo.lock files
|
||||||
|
|
||||||
#### API KCL Plugin
|
#### API KCL Plugin
|
||||||
|
|
||||||
- Updated Cargo.lock with 266 dependency changes
|
- Updated Cargo.lock with 266 dependency changes
|
||||||
|
|
||||||
### 🏗️ Repository Infrastructure Updates
|
### 🏗️ Repository Infrastructure Updates
|
||||||
|
|
||||||
#### Git Tracking Cleanup
|
#### Git Tracking Cleanup
|
||||||
|
|
||||||
- **Removed nushell directory from tracking**: The nushell submodule directory is now properly ignored
|
- **Removed nushell directory from tracking**: The nushell submodule directory is now properly ignored
|
||||||
- **Updated .gitignore**: Added patterns for nushell directory, nushell-*files, and*.tar.gz archives
|
- **Updated .gitignore**: Added patterns for nushell directory, nushell-*files, and*.tar.gz archives
|
||||||
|
|
||||||
|
|||||||
91
README.md
91
README.md
@ -1,20 +1,19 @@
|
|||||||
# 🚀 Nushell Plugins Repository
|
# 🚀 Nushell Plugins Repository
|
||||||
|
|
||||||
**Current Nushell Version**: 0.108.0 | **Last Updated**: 2025-10-18
|
**Current Nushell Version**: 0.111.0 | **Last Updated**: 2026-03-11
|
||||||
|
|
||||||
A comprehensive collection of nushell plugins with automated upstream tracking, dependency management, development workflows, **complete Nushell distribution system**, and **semi-automated version update framework**.
|
A comprehensive collection of nushell plugins with automated upstream tracking, dependency management, development workflows, **complete Nushell distribution system**, and **semi-automated version update framework**.
|
||||||
|
|
||||||
## 🎯 Latest Update: Nushell 0.108.0
|
## 🎯 Latest Update: Nushell 0.111.0
|
||||||
|
|
||||||
**Major highlights of the 0.108.0 update:**
|
**Highlights of the 0.111.0 update:**
|
||||||
- ✅ **MCP Support**: Model Context Protocol for AI agent integration
|
|
||||||
- ✅ **Critical Bug Fixes**: Fixed documentation syntax errors affecting all code generation
|
|
||||||
- ✅ **Automation Framework**: 8 new scripts for semi-automated version updates
|
|
||||||
- ✅ **Complete Documentation**: Migration guides, automation docs, and validation reports
|
|
||||||
- ✅ **80% Faster Updates**: Automated workflows with strategic manual checkpoints
|
|
||||||
|
|
||||||
**→ [START HERE: UPDATE.md](UPDATE.md)** for version update instructions
|
- ✅ **18 plugins updated** to Nushell 0.111.0
|
||||||
See [`CHANGELOG.md`](CHANGELOG.md) for complete details | Read [`updates/108/`](updates/108/) for full documentation
|
- ✅ **Rust toolchain** bumped to 1.93.1 (nushell 0.111.0 requires ≥1.91.1)
|
||||||
|
- ✅ **interprocess ^2.3.1** — resolved conflict with nu-plugin-core 0.111.0 across mcp/nats/typedialog
|
||||||
|
- ✅ **Update script fixes** — `[package].version` and `[dev-dependencies]` now correctly updated on minor version bumps
|
||||||
|
|
||||||
|
See [`CHANGELOG.md`](CHANGELOG.md) for complete details.
|
||||||
|
|
||||||
## 🆕 NEW: Full Nushell Distribution System
|
## 🆕 NEW: Full Nushell Distribution System
|
||||||
|
|
||||||
@ -23,6 +22,7 @@ See [`CHANGELOG.md`](CHANGELOG.md) for complete details | Read [`updates/108/`](
|
|||||||
This repository provides **complete Nushell distributions** that include Nushell itself plus all plugins, offering zero-prerequisite installation for end users:
|
This repository provides **complete Nushell distributions** that include Nushell itself plus all plugins, offering zero-prerequisite installation for end users:
|
||||||
|
|
||||||
### 🎯 End User Installation (Zero Prerequisites)
|
### 🎯 End User Installation (Zero Prerequisites)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# One-liner installation (Linux/macOS)
|
# One-liner installation (Linux/macOS)
|
||||||
curl -sSf https://your-url/install.sh | sh
|
curl -sSf https://your-url/install.sh | sh
|
||||||
@ -36,6 +36,7 @@ tar -xzf nushell-full-*.tar.gz && cd nushell-full-* && ./install.sh
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 🚀 Developer Distribution Commands
|
### 🚀 Developer Distribution Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
just build-full # Build nushell + all plugins
|
just build-full # Build nushell + all plugins
|
||||||
just pack-full # Create distribution package
|
just pack-full # Create distribution package
|
||||||
@ -45,6 +46,7 @@ just release-full-cross # Complete release workflow
|
|||||||
```
|
```
|
||||||
|
|
||||||
### ✨ Key Features
|
### ✨ Key Features
|
||||||
|
|
||||||
- **Zero Prerequisites**: No Rust, Cargo, or Nu installation required
|
- **Zero Prerequisites**: No Rust, Cargo, or Nu installation required
|
||||||
- **Cross-Platform**: Linux, macOS, Windows support
|
- **Cross-Platform**: Linux, macOS, Windows support
|
||||||
- **Complete Environment**: Nushell + all plugins + configuration
|
- **Complete Environment**: Nushell + all plugins + configuration
|
||||||
@ -83,6 +85,7 @@ tar -xzf nushell-full-*.tar.gz && cd nushell-full-* && ./install.sh
|
|||||||
### For Developers
|
### For Developers
|
||||||
|
|
||||||
#### Prerequisites
|
#### Prerequisites
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install required tools
|
# Install required tools
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Rust
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Rust
|
||||||
@ -91,6 +94,7 @@ cargo install just # Just (optional
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Development Workflow
|
#### Development Workflow
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repository
|
# Clone the repository
|
||||||
git clone <repository-url>
|
git clone <repository-url>
|
||||||
@ -130,6 +134,7 @@ The Full Distribution System transforms this repository from a **development-foc
|
|||||||
### End User Experience
|
### End User Experience
|
||||||
|
|
||||||
**Before**: Complex development setup required
|
**Before**: Complex development setup required
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Users needed to:
|
# Users needed to:
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Install Rust
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Install Rust
|
||||||
@ -139,6 +144,7 @@ just validate-nushell && just build # Build everythin
|
|||||||
```
|
```
|
||||||
|
|
||||||
**After**: Zero-prerequisite installation
|
**After**: Zero-prerequisite installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Users now only need:
|
# Users now only need:
|
||||||
curl -sSf https://your-url/install.sh | sh # Done!
|
curl -sSf https://your-url/install.sh | sh # Done!
|
||||||
@ -149,6 +155,7 @@ curl -sSf https://your-url/install.sh | sh # Done!
|
|||||||
#### Building Complete Distributions
|
#### Building Complete Distributions
|
||||||
|
|
||||||
**Step 1: Build Nushell + System Plugins**
|
**Step 1: Build Nushell + System Plugins**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build Nushell with built-in system plugins (uses cargo build --workspace)
|
# Build Nushell with built-in system plugins (uses cargo build --workspace)
|
||||||
just build-nushell # Builds: nu + nu_plugin_formats, nu_plugin_inc, nu_plugin_gstat,
|
just build-nushell # Builds: nu + nu_plugin_formats, nu_plugin_inc, nu_plugin_gstat,
|
||||||
@ -159,6 +166,7 @@ just build-nushell-target linux-arm64 # Cross-compile system plugins
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Step 2: Build Everything (System + Custom Plugins)**
|
**Step 2: Build Everything (System + Custom Plugins)**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build nushell + system plugins + custom plugins from this repo
|
# Build nushell + system plugins + custom plugins from this repo
|
||||||
just build-full # Native build (calls build-nushell + build custom plugins)
|
just build-full # Native build (calls build-nushell + build custom plugins)
|
||||||
@ -167,6 +175,7 @@ just build-full-all # All platforms
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Step 3: Collect Built Binaries**
|
**Step 3: Collect Built Binaries**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Collect nushell binary + all plugins for distribution
|
# Collect nushell binary + all plugins for distribution
|
||||||
just collect # Current platform (darwin-arm64)
|
just collect # Current platform (darwin-arm64)
|
||||||
@ -175,6 +184,7 @@ just collect-platform PLATFORM # Specific platform
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Step 4: Create Distribution Packages**
|
**Step 4: Create Distribution Packages**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Create distribution packages
|
# Create distribution packages
|
||||||
just pack-full # Current platform
|
just pack-full # Current platform
|
||||||
@ -187,6 +197,7 @@ just test-install-full # Test complete installation process
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Cross-Platform Release
|
#### Cross-Platform Release
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Complete release workflow
|
# Complete release workflow
|
||||||
just release-full-cross # Build → Pack → Verify for all platforms
|
just release-full-cross # Build → Pack → Verify for all platforms
|
||||||
@ -200,6 +211,7 @@ just release-full-windows # Windows distributions
|
|||||||
#### Installation Modes
|
#### Installation Modes
|
||||||
|
|
||||||
**System Installation** (recommended for end users):
|
**System Installation** (recommended for end users):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install to system paths with proper integration
|
# Install to system paths with proper integration
|
||||||
./install.sh
|
./install.sh
|
||||||
@ -212,6 +224,7 @@ just release-full-windows # Windows distributions
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Local Installation** (development/testing):
|
**Local Installation** (development/testing):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install to user directory without system integration
|
# Install to user directory without system integration
|
||||||
./install.sh --local
|
./install.sh --local
|
||||||
@ -223,6 +236,7 @@ just release-full-windows # Windows distributions
|
|||||||
### Distribution Architecture
|
### Distribution Architecture
|
||||||
|
|
||||||
#### Components Included
|
#### Components Included
|
||||||
|
|
||||||
- **Nushell Binary**: Complete nushell installation
|
- **Nushell Binary**: Complete nushell installation
|
||||||
- **All Plugins**: Every plugin in the repository
|
- **All Plugins**: Every plugin in the repository
|
||||||
- **Configuration**: Optimized default configuration
|
- **Configuration**: Optimized default configuration
|
||||||
@ -231,6 +245,7 @@ just release-full-windows # Windows distributions
|
|||||||
- **Verification**: Installation integrity checks
|
- **Verification**: Installation integrity checks
|
||||||
|
|
||||||
#### Platform Support
|
#### Platform Support
|
||||||
|
|
||||||
| Platform | Architecture | Status | Installation Method |
|
| Platform | Architecture | Status | Installation Method |
|
||||||
|----------|-------------|--------|-------------------|
|
|----------|-------------|--------|-------------------|
|
||||||
| **Linux** | x86_64 | ✅ Full | `curl` installer + manual |
|
| **Linux** | x86_64 | ✅ Full | `curl` installer + manual |
|
||||||
@ -240,6 +255,7 @@ just release-full-windows # Windows distributions
|
|||||||
| **Windows** | x86_64 | ✅ Full | PowerShell installer + manual |
|
| **Windows** | x86_64 | ✅ Full | PowerShell installer + manual |
|
||||||
|
|
||||||
#### Bootstrap Installers
|
#### Bootstrap Installers
|
||||||
|
|
||||||
- **Smart Detection**: Automatically detects platform and architecture
|
- **Smart Detection**: Automatically detects platform and architecture
|
||||||
- **Conflict Resolution**: Handles existing Nushell installations
|
- **Conflict Resolution**: Handles existing Nushell installations
|
||||||
- **Path Management**: Configures PATH and shell integration
|
- **Path Management**: Configures PATH and shell integration
|
||||||
@ -249,18 +265,21 @@ just release-full-windows # Windows distributions
|
|||||||
### Use Cases
|
### Use Cases
|
||||||
|
|
||||||
#### For End Users
|
#### For End Users
|
||||||
|
|
||||||
- **Simple Installation**: Get Nushell + all plugins with one command
|
- **Simple Installation**: Get Nushell + all plugins with one command
|
||||||
- **No Prerequisites**: No need for Rust, Git, or development tools
|
- **No Prerequisites**: No need for Rust, Git, or development tools
|
||||||
- **Professional Experience**: Clean installation/uninstallation
|
- **Professional Experience**: Clean installation/uninstallation
|
||||||
- **Immediate Productivity**: Pre-configured environment with all plugins
|
- **Immediate Productivity**: Pre-configured environment with all plugins
|
||||||
|
|
||||||
#### For System Administrators
|
#### For System Administrators
|
||||||
|
|
||||||
- **Bulk Deployment**: Deploy to multiple systems easily
|
- **Bulk Deployment**: Deploy to multiple systems easily
|
||||||
- **Consistent Environment**: Identical setup across all machines
|
- **Consistent Environment**: Identical setup across all machines
|
||||||
- **Offline Installation**: Manual packages work without internet
|
- **Offline Installation**: Manual packages work without internet
|
||||||
- **Integration Ready**: System-wide installation with proper paths
|
- **Integration Ready**: System-wide installation with proper paths
|
||||||
|
|
||||||
#### for Distributors/Packagers
|
#### for Distributors/Packagers
|
||||||
|
|
||||||
- **Ready Binaries**: All binaries built and tested
|
- **Ready Binaries**: All binaries built and tested
|
||||||
- **Cross-Platform**: Support for all major platforms
|
- **Cross-Platform**: Support for all major platforms
|
||||||
- **Checksums Included**: Integrity verification built-in
|
- **Checksums Included**: Integrity verification built-in
|
||||||
@ -302,33 +321,34 @@ This repository provides:
|
|||||||
| **nu_plugin_fluent** | ✅ Tracked | Upstream | Fluent localization framework |
|
| **nu_plugin_fluent** | ✅ Tracked | Upstream | Fluent localization framework |
|
||||||
| **nu_plugin_tera** | ✅ Tracked | Private | Tera templating engine (private repo) |
|
| **nu_plugin_tera** | ✅ Tracked | Private | Tera templating engine (private repo) |
|
||||||
| **nu_plugin_kcl** | ✅ Tracked | Private | KCL configuration language (private repo) |
|
| **nu_plugin_kcl** | ✅ Tracked | Private | KCL configuration language (private repo) |
|
||||||
|
| **nu_plugin_nickel** | 🏠 Local | Local | Nickel configuration language (eval, export, format, validate) |
|
||||||
|
|
||||||
### Provisioning Platform Plugins (NEW)
|
### Provisioning Platform Plugins
|
||||||
|
|
||||||
High-performance native plugins for the provisioning platform with **10x performance improvement** over HTTP APIs:
|
High-performance native plugins for the provisioning platform:
|
||||||
|
|
||||||
| Plugin | Type | Description | Performance Gain |
|
| Plugin | Type | Description |
|
||||||
|--------|------|-------------|------------------|
|
|--------|------|-------------|
|
||||||
| **nu_plugin_auth** | 🔐 Security | JWT authentication, MFA (TOTP/WebAuthn), session management | 20% faster |
|
| **nu_plugin_auth** | 🔐 Security | JWT authentication, MFA (TOTP/WebAuthn), session management |
|
||||||
| **nu_plugin_kms** | 🔑 Security | Multi-backend KMS (RustyVault, Age, Cosmian, AWS, Vault) | **10x faster** |
|
| **nu_plugin_kms** | 🔑 Security | Multi-backend KMS (RustyVault, Age, Cosmian, AWS, Vault) |
|
||||||
| **nu_plugin_orchestrator** | 🎯 Operations | Orchestrator status, workflow validation, task management | **10x faster** |
|
| **nu_plugin_orchestrator** | 🎯 Operations | Orchestrator status, workflow validation, task management |
|
||||||
|
| **nu_plugin_typedialog** | 💬 UX | Interactive forms/prompts via TypeDialog — replaces shlib TTY wrappers |
|
||||||
**Key Features**:
|
| **nu_plugin_mcp** | 🤖 AI | MCP client — spawn and interact with `provisioning-mcp-server` |
|
||||||
- **Native Performance**: Direct Rust integration eliminates HTTP overhead
|
|
||||||
- **Pipeline Integration**: Full Nushell pipeline support
|
|
||||||
- **Multi-Backend KMS**: RustyVault, Age, Cosmian, AWS KMS, HashiCorp Vault
|
|
||||||
- **Security First**: JWT, MFA (TOTP/WebAuthn), keyring storage
|
|
||||||
- **Production Ready**: Comprehensive tests, error handling, documentation
|
|
||||||
|
|
||||||
**Quick Start**:
|
**Quick Start**:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build and register provisioning plugins
|
# Build and register provisioning plugins
|
||||||
just build-plugin nu_plugin_auth
|
just build-plugin nu_plugin_auth
|
||||||
just build-plugin nu_plugin_kms
|
just build-plugin nu_plugin_kms
|
||||||
just build-plugin nu_plugin_orchestrator
|
just build-plugin nu_plugin_orchestrator
|
||||||
|
just build-plugin nu_plugin_typedialog
|
||||||
|
just build-plugin nu_plugin_mcp
|
||||||
just install-plugin nu_plugin_auth
|
just install-plugin nu_plugin_auth
|
||||||
just install-plugin nu_plugin_kms
|
just install-plugin nu_plugin_kms
|
||||||
just install-plugin nu_plugin_orchestrator
|
just install-plugin nu_plugin_orchestrator
|
||||||
|
just install-plugin nu_plugin_typedialog
|
||||||
|
just install-plugin nu_plugin_mcp
|
||||||
|
|
||||||
# Verify installation
|
# Verify installation
|
||||||
nu -c "plugin list | where name =~ provisioning"
|
nu -c "plugin list | where name =~ provisioning"
|
||||||
@ -337,6 +357,7 @@ nu -c "plugin list | where name =~ provisioning"
|
|||||||
**See Full Guide**: `docs/user/NUSHELL_PLUGINS_GUIDE.md`
|
**See Full Guide**: `docs/user/NUSHELL_PLUGINS_GUIDE.md`
|
||||||
|
|
||||||
### Legend
|
### Legend
|
||||||
|
|
||||||
- ✅ **Tracked**: Has upstream repository with automated tracking
|
- ✅ **Tracked**: Has upstream repository with automated tracking
|
||||||
- 🏠 **Local**: Developed locally without upstream
|
- 🏠 **Local**: Developed locally without upstream
|
||||||
- 🔒 **Private**: Private repository with tracking (requires authentication)
|
- 🔒 **Private**: Private repository with tracking (requires authentication)
|
||||||
@ -412,6 +433,7 @@ For detailed instructions, platform-specific setup, troubleshooting, and advance
|
|||||||
**➡️ [Complete Building and Cross-Compilation Guide](docs/BUILDING.md)**
|
**➡️ [Complete Building and Cross-Compilation Guide](docs/BUILDING.md)**
|
||||||
|
|
||||||
The guide covers:
|
The guide covers:
|
||||||
|
|
||||||
- Platform-specific setup and dependencies
|
- Platform-specific setup and dependencies
|
||||||
- Native vs Docker cross-compilation
|
- Native vs Docker cross-compilation
|
||||||
- Configuration and customization
|
- Configuration and customization
|
||||||
@ -608,7 +630,7 @@ The repository now uses a **unified script system** with automatic nushell detec
|
|||||||
|
|
||||||
### Directory Structure
|
### Directory Structure
|
||||||
|
|
||||||
```
|
```plaintext
|
||||||
scripts/
|
scripts/
|
||||||
├── run.sh # Universal script runner with version checking
|
├── run.sh # Universal script runner with version checking
|
||||||
├── check_version.nu # Version consistency validator
|
├── check_version.nu # Version consistency validator
|
||||||
@ -682,7 +704,7 @@ Every script automatically validates that your system nushell version matches th
|
|||||||
|
|
||||||
## 📁 File Structure
|
## 📁 File Structure
|
||||||
|
|
||||||
```
|
```plaintext
|
||||||
nushell-plugins/
|
nushell-plugins/
|
||||||
├── README.md # This file
|
├── README.md # This file
|
||||||
├── justfile # Just task runner recipes
|
├── justfile # Just task runner recipes
|
||||||
@ -731,6 +753,7 @@ nu --version && nu -c "plugin list"
|
|||||||
```
|
```
|
||||||
|
|
||||||
**What you get:**
|
**What you get:**
|
||||||
|
|
||||||
- Complete Nushell installation
|
- Complete Nushell installation
|
||||||
- All plugins from this repository
|
- All plugins from this repository
|
||||||
- Optimized configuration
|
- Optimized configuration
|
||||||
@ -742,6 +765,7 @@ nu --version && nu -c "plugin list"
|
|||||||
The installation system uses a **single source of truth** with symlinks to eliminate code duplication:
|
The installation system uses a **single source of truth** with symlinks to eliminate code duplication:
|
||||||
|
|
||||||
**Key Files:**
|
**Key Files:**
|
||||||
|
|
||||||
- **Source of Truth**: `installers/bootstrap/install.sh` (1,176 lines)
|
- **Source of Truth**: `installers/bootstrap/install.sh` (1,176 lines)
|
||||||
- Complete bootstrap installer for Nushell + plugins
|
- Complete bootstrap installer for Nushell + plugins
|
||||||
- Repository: `https://github.com/jesusperezlorenzo/nushell-plugins`
|
- Repository: `https://github.com/jesusperezlorenzo/nushell-plugins`
|
||||||
@ -775,6 +799,7 @@ Install from local archives or directories without downloading:
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Version-Agnostic Archive Detection**:
|
**Version-Agnostic Archive Detection**:
|
||||||
|
|
||||||
- Automatically detects any `nushell-*` version directory
|
- Automatically detects any `nushell-*` version directory
|
||||||
- Works with: 0.107, 0.108, 0.109, or any future version
|
- Works with: 0.107, 0.108, 0.109, or any future version
|
||||||
- Searches for binaries in: `bin/nu` (preferred) → root `nu` (fallback)
|
- Searches for binaries in: `bin/nu` (preferred) → root `nu` (fallback)
|
||||||
@ -782,6 +807,7 @@ Install from local archives or directories without downloading:
|
|||||||
- Smart extraction and path detection
|
- Smart extraction and path detection
|
||||||
|
|
||||||
**Installation Options**:
|
**Installation Options**:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./install.sh # Interactive mode
|
./install.sh # Interactive mode
|
||||||
./install.sh --install-dir ~/.local # Custom path, non-interactive
|
./install.sh --install-dir ~/.local # Custom path, non-interactive
|
||||||
@ -792,6 +818,7 @@ Install from local archives or directories without downloading:
|
|||||||
```
|
```
|
||||||
|
|
||||||
**How DRY Works**:
|
**How DRY Works**:
|
||||||
|
|
||||||
1. **Single Source**: Only `installers/bootstrap/install.sh` is edited
|
1. **Single Source**: Only `installers/bootstrap/install.sh` is edited
|
||||||
2. **Symlinks Propagate**: All changes automatically available at `./install.sh` and `./scripts/templates/install.sh`
|
2. **Symlinks Propagate**: All changes automatically available at `./install.sh` and `./scripts/templates/install.sh`
|
||||||
3. **Verified**: All symlinked paths contain identical content
|
3. **Verified**: All symlinked paths contain identical content
|
||||||
@ -939,6 +966,7 @@ just validate # Validate setup and dependencies
|
|||||||
**A:** This system requires your installed nushell version to match the submodule version for consistency. All operations automatically check version consistency and will fail if versions don't match.
|
**A:** This system requires your installed nushell version to match the submodule version for consistency. All operations automatically check version consistency and will fail if versions don't match.
|
||||||
|
|
||||||
**Solutions:**
|
**Solutions:**
|
||||||
|
|
||||||
- **Auto-fix**: `just fix-nushell` or `./scripts/run.sh --fix --check-only`
|
- **Auto-fix**: `just fix-nushell` or `./scripts/run.sh --fix --check-only`
|
||||||
- **Manual check**: `just validate-nushell`
|
- **Manual check**: `just validate-nushell`
|
||||||
- **Skip (not recommended)**: `./scripts/run.sh --no-version-check script.nu`
|
- **Skip (not recommended)**: `./scripts/run.sh --no-version-check script.nu`
|
||||||
@ -946,6 +974,7 @@ just validate # Validate setup and dependencies
|
|||||||
### Q: What happened to the bash wrapper scripts?
|
### Q: What happened to the bash wrapper scripts?
|
||||||
|
|
||||||
**A:** The repository has been consolidated to eliminate script duplication. The old bash wrappers in `scripts/sh/` have been removed in favor of:
|
**A:** The repository has been consolidated to eliminate script duplication. The old bash wrappers in `scripts/sh/` have been removed in favor of:
|
||||||
|
|
||||||
- **Universal wrapper**: `./scripts/run.sh` with automatic version checking
|
- **Universal wrapper**: `./scripts/run.sh` with automatic version checking
|
||||||
- **Direct nu scripts**: All scripts moved from `scripts/nu/` to `scripts/`
|
- **Direct nu scripts**: All scripts moved from `scripts/nu/` to `scripts/`
|
||||||
- **Just recipes**: Updated to use the new system
|
- **Just recipes**: Updated to use the new system
|
||||||
@ -953,6 +982,7 @@ just validate # Validate setup and dependencies
|
|||||||
### Q: How does the new script system work?
|
### Q: How does the new script system work?
|
||||||
|
|
||||||
**A:** The new system provides:
|
**A:** The new system provides:
|
||||||
|
|
||||||
1. **Universal wrapper** (`scripts/run.sh`) with automatic nushell detection and version validation
|
1. **Universal wrapper** (`scripts/run.sh`) with automatic nushell detection and version validation
|
||||||
2. **Consolidated scripts** - all nu scripts in `scripts/` directory
|
2. **Consolidated scripts** - all nu scripts in `scripts/` directory
|
||||||
3. **Mandatory version checking** - every operation validates version consistency
|
3. **Mandatory version checking** - every operation validates version consistency
|
||||||
@ -965,6 +995,7 @@ just validate # Validate setup and dependencies
|
|||||||
### Q: What happens to my local changes during upstream merges?
|
### Q: What happens to my local changes during upstream merges?
|
||||||
|
|
||||||
**A:** Local changes are preserved. The system:
|
**A:** Local changes are preserved. The system:
|
||||||
|
|
||||||
1. Creates backup branches before any merge
|
1. Creates backup branches before any merge
|
||||||
2. Applies upstream changes in a temporary branch
|
2. Applies upstream changes in a temporary branch
|
||||||
3. Restores your local nu_* dependency versions
|
3. Restores your local nu_* dependency versions
|
||||||
@ -978,6 +1009,7 @@ just validate # Validate setup and dependencies
|
|||||||
### Q: How do I add a new plugin to the repository?
|
### Q: How do I add a new plugin to the repository?
|
||||||
|
|
||||||
**A:** Use the template generator:
|
**A:** Use the template generator:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
just make-plugin nu_plugin_myfeature
|
just make-plugin nu_plugin_myfeature
|
||||||
# or
|
# or
|
||||||
@ -987,6 +1019,7 @@ nu scripts/nu/make_plugin.nu nu_plugin_myfeature
|
|||||||
### Q: What if upstream tracking fails?
|
### Q: What if upstream tracking fails?
|
||||||
|
|
||||||
**A:** Check the plugin status with `just status`. Failed plugins show error details. Common issues:
|
**A:** Check the plugin status with `just status`. Failed plugins show error details. Common issues:
|
||||||
|
|
||||||
- Network connectivity to upstream repository
|
- Network connectivity to upstream repository
|
||||||
- Authentication for private repositories
|
- Authentication for private repositories
|
||||||
- Merge conflicts requiring manual resolution
|
- Merge conflicts requiring manual resolution
|
||||||
@ -994,6 +1027,7 @@ nu scripts/nu/make_plugin.nu nu_plugin_myfeature
|
|||||||
### Q: How do I update nushell dependency versions?
|
### Q: How do I update nushell dependency versions?
|
||||||
|
|
||||||
**A:** Use the version updater:
|
**A:** Use the version updater:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
just update-nu-versions # Update all plugins
|
just update-nu-versions # Update all plugins
|
||||||
just list-nu-versions # Show current versions
|
just list-nu-versions # Show current versions
|
||||||
@ -1006,6 +1040,7 @@ just list-nu-versions # Show current versions
|
|||||||
### Q: How do I distribute plugins to other systems?
|
### Q: How do I distribute plugins to other systems?
|
||||||
|
|
||||||
**A:** Use the distribution pipeline:
|
**A:** Use the distribution pipeline:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
just build # Build all plugins
|
just build # Build all plugins
|
||||||
just collect # Collect binaries
|
just collect # Collect binaries
|
||||||
@ -1017,6 +1052,7 @@ The resulting archive contains all binaries and installation scripts.
|
|||||||
### Q: What's the difference between shell scripts and nushell scripts?
|
### Q: What's the difference between shell scripts and nushell scripts?
|
||||||
|
|
||||||
**A:**
|
**A:**
|
||||||
|
|
||||||
- **Nushell scripts** (`scripts/nu/`): Primary implementation with full features
|
- **Nushell scripts** (`scripts/nu/`): Primary implementation with full features
|
||||||
- **Shell scripts** (`scripts/sh/`): Wrappers for compatibility with non-nushell environments
|
- **Shell scripts** (`scripts/sh/`): Wrappers for compatibility with non-nushell environments
|
||||||
- Both provide the same functionality, use whichever fits your environment
|
- Both provide the same functionality, use whichever fits your environment
|
||||||
@ -1024,6 +1060,7 @@ The resulting archive contains all binaries and installation scripts.
|
|||||||
### Q: How do I contribute a new plugin?
|
### Q: How do I contribute a new plugin?
|
||||||
|
|
||||||
**A:**
|
**A:**
|
||||||
|
|
||||||
1. Create the plugin: `just make-plugin nu_plugin_yourname`
|
1. Create the plugin: `just make-plugin nu_plugin_yourname`
|
||||||
2. Implement your functionality
|
2. Implement your functionality
|
||||||
3. Add upstream URL to `etc/plugin_registry.toml` if it has one
|
3. Add upstream URL to `etc/plugin_registry.toml` if it has one
|
||||||
@ -1033,12 +1070,14 @@ The resulting archive contains all binaries and installation scripts.
|
|||||||
### Q: How do I exclude plugins from upstream tracking?
|
### Q: How do I exclude plugins from upstream tracking?
|
||||||
|
|
||||||
**A:** Edit `etc/upstream_exclude.toml` to exclude plugins from specific operations:
|
**A:** Edit `etc/upstream_exclude.toml` to exclude plugins from specific operations:
|
||||||
|
|
||||||
- Add to `[exclude]` section to exclude from all operations
|
- Add to `[exclude]` section to exclude from all operations
|
||||||
- Add to `[exclude.check]` to skip automatic checks
|
- Add to `[exclude.check]` to skip automatic checks
|
||||||
- Add to `[exclude.merge]` to prevent automatic merging
|
- Add to `[exclude.merge]` to prevent automatic merging
|
||||||
- Use patterns like `nu_plugin_test_*` to exclude multiple plugins
|
- Use patterns like `nu_plugin_test_*` to exclude multiple plugins
|
||||||
|
|
||||||
You can also use Just commands:
|
You can also use Just commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
just exclude nu_plugin_test add # Add to exclusion
|
just exclude nu_plugin_test add # Add to exclusion
|
||||||
just exclude nu_plugin_test remove # Remove from exclusion
|
just exclude nu_plugin_test remove # Remove from exclusion
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
851
docs/building.md
851
docs/building.md
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -182,12 +182,6 @@ additional_dirs = [
|
|||||||
[packaging]
|
[packaging]
|
||||||
# Output directory for packages
|
# Output directory for packages
|
||||||
output_dir = "bin_archives"
|
output_dir = "bin_archives"
|
||||||
# Package formats per platform
|
|
||||||
formats = {
|
|
||||||
linux = ["tar.gz"],
|
|
||||||
macos = ["tar.gz"],
|
|
||||||
windows = ["zip"]
|
|
||||||
}
|
|
||||||
# Compression level (0-9)
|
# Compression level (0-9)
|
||||||
compression_level = 6
|
compression_level = 6
|
||||||
# Whether to generate checksums
|
# Whether to generate checksums
|
||||||
@ -195,6 +189,12 @@ generate_checksums = true
|
|||||||
# Checksum algorithms
|
# Checksum algorithms
|
||||||
checksum_algorithms = ["sha256", "sha512"]
|
checksum_algorithms = ["sha256", "sha512"]
|
||||||
|
|
||||||
|
# Package formats per platform
|
||||||
|
[packaging.formats]
|
||||||
|
linux = ["tar.gz"]
|
||||||
|
macos = ["tar.gz"]
|
||||||
|
windows = ["zip"]
|
||||||
|
|
||||||
# Manifest settings
|
# Manifest settings
|
||||||
[packaging.manifest]
|
[packaging.manifest]
|
||||||
# Include detailed manifest in packages
|
# Include detailed manifest in packages
|
||||||
@ -210,11 +210,6 @@ include_plugin_info = true
|
|||||||
|
|
||||||
# Installation settings
|
# Installation settings
|
||||||
[installation]
|
[installation]
|
||||||
# Default configuration templates
|
|
||||||
config_templates = {
|
|
||||||
env = "scripts/templates/default_env.nu",
|
|
||||||
config = "scripts/templates/default_config.nu"
|
|
||||||
}
|
|
||||||
# Whether to create config directory
|
# Whether to create config directory
|
||||||
create_config_dir = true
|
create_config_dir = true
|
||||||
# Whether to update PATH
|
# Whether to update PATH
|
||||||
@ -227,6 +222,11 @@ shell_scripts = [
|
|||||||
"installers/bootstrap/install.ps1"
|
"installers/bootstrap/install.ps1"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Default configuration templates
|
||||||
|
[installation.config_templates]
|
||||||
|
env = "scripts/templates/default_env.nu"
|
||||||
|
config = "scripts/templates/default_config.nu"
|
||||||
|
|
||||||
# Verification settings
|
# Verification settings
|
||||||
[verification]
|
[verification]
|
||||||
# Enable installation verification
|
# Enable installation verification
|
||||||
@ -274,11 +274,10 @@ generate_release_notes = true
|
|||||||
# Pre-release validation
|
# Pre-release validation
|
||||||
validate_before_release = true
|
validate_before_release = true
|
||||||
# Release channels
|
# Release channels
|
||||||
channels = {
|
[release.channels]
|
||||||
stable = "main",
|
stable = "main"
|
||||||
beta = "develop",
|
beta = "develop"
|
||||||
nightly = "nightly"
|
nightly = "nightly"
|
||||||
}
|
|
||||||
|
|
||||||
# Documentation settings
|
# Documentation settings
|
||||||
[documentation]
|
[documentation]
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
# Nushell Plugin Registry for Provisioning Platform
|
[plugins.nu_plugin_auth]
|
||||||
# This file tracks available Nushell plugins with metadata
|
|
||||||
|
|
||||||
[nu_plugin_auth]
|
|
||||||
upstream_url = "local"
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
status = "ok"
|
status = "ok"
|
||||||
auto_merge = false
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_auth"
|
||||||
description = "Authentication plugin (JWT, MFA) for provisioning platform"
|
description = "Authentication plugin (JWT, MFA) for provisioning platform"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
category = "provisioning"
|
category = "provisioning"
|
||||||
@ -14,59 +13,71 @@ commands = [
|
|||||||
"auth verify",
|
"auth verify",
|
||||||
"auth sessions",
|
"auth sessions",
|
||||||
"auth mfa enroll",
|
"auth mfa enroll",
|
||||||
"auth mfa verify"
|
"auth mfa verify",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"keyring",
|
"keyring",
|
||||||
"rpassword",
|
"rpassword",
|
||||||
"qrcode"
|
"qrcode",
|
||||||
]
|
]
|
||||||
|
|
||||||
[nu_plugin_kms]
|
[plugins.nu_plugin_kms]
|
||||||
upstream_url = "local"
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
status = "ok"
|
status = "ok"
|
||||||
auto_merge = false
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_kms"
|
||||||
description = "KMS plugin (RustyVault, Age, Cosmian) for provisioning platform"
|
description = "KMS plugin (RustyVault, Age, Cosmian) for provisioning platform"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
category = "provisioning"
|
category = "provisioning"
|
||||||
backends = ["rustyvault", "age", "cosmian", "aws", "vault"]
|
backends = [
|
||||||
|
"rustyvault",
|
||||||
|
"age",
|
||||||
|
"cosmian",
|
||||||
|
"aws",
|
||||||
|
"vault",
|
||||||
|
]
|
||||||
commands = [
|
commands = [
|
||||||
"kms encrypt",
|
"kms encrypt",
|
||||||
"kms decrypt",
|
"kms decrypt",
|
||||||
"kms generate-key",
|
"kms generate-key",
|
||||||
"kms status"
|
"kms status",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"age",
|
"age",
|
||||||
"base64",
|
"base64",
|
||||||
"serde"
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[nu_plugin_orchestrator]
|
[plugins.nu_plugin_orchestrator]
|
||||||
upstream_url = "local"
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
status = "ok"
|
status = "ok"
|
||||||
auto_merge = false
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_orchestrator"
|
||||||
description = "Orchestrator operations plugin (status, validate, tasks)"
|
description = "Orchestrator operations plugin (status, validate, tasks)"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
category = "provisioning"
|
category = "provisioning"
|
||||||
commands = [
|
commands = [
|
||||||
"orch status",
|
"orch status",
|
||||||
"orch validate",
|
"orch validate",
|
||||||
"orch tasks"
|
"orch tasks",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"walkdir"
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
[nu_plugin_inquire]
|
[plugins.nu_plugin_inquire]
|
||||||
upstream_url = "https://github.com/jesusperezlorenzo/nu_plugin_inquire"
|
upstream_url = "https://github.com/jesusperezlorenzo/nu_plugin_inquire"
|
||||||
|
upstream_branch = "main"
|
||||||
status = "ok"
|
status = "ok"
|
||||||
auto_merge = false
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_inquire"
|
||||||
description = "Interactive forms and prompts plugin using inquire crate - solves TTY buffering issues"
|
description = "Interactive forms and prompts plugin using inquire crate - solves TTY buffering issues"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
category = "utility"
|
category = "utility"
|
||||||
@ -79,7 +90,7 @@ commands = [
|
|||||||
"inquire custom",
|
"inquire custom",
|
||||||
"inquire editor",
|
"inquire editor",
|
||||||
"inquire date",
|
"inquire date",
|
||||||
"inquire form"
|
"inquire form",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"inquire",
|
"inquire",
|
||||||
@ -87,13 +98,15 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"toml",
|
"toml",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dialoguer"
|
"dialoguer",
|
||||||
]
|
]
|
||||||
|
|
||||||
[forminquire]
|
[plugins.forminquire]
|
||||||
upstream_url = "local"
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
status = "ok"
|
status = "ok"
|
||||||
auto_merge = false
|
auto_merge = false
|
||||||
|
local_path = "forminquire"
|
||||||
description = "Standalone interactive forms and prompts library + CLI tool - no Nushell dependency required"
|
description = "Standalone interactive forms and prompts library + CLI tool - no Nushell dependency required"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
category = "utility"
|
category = "utility"
|
||||||
@ -108,16 +121,20 @@ commands = [
|
|||||||
"forminquire custom",
|
"forminquire custom",
|
||||||
"forminquire editor",
|
"forminquire editor",
|
||||||
"forminquire date",
|
"forminquire date",
|
||||||
"forminquire form"
|
"forminquire form",
|
||||||
]
|
]
|
||||||
library_support = true
|
library_support = true
|
||||||
output_formats = ["text", "json", "yaml"]
|
output_formats = [
|
||||||
|
"text",
|
||||||
|
"json",
|
||||||
|
"yaml",
|
||||||
|
]
|
||||||
features = [
|
features = [
|
||||||
"8 interactive prompt types",
|
"8 interactive prompt types",
|
||||||
"TOML-based form definitions",
|
"TOML-based form definitions",
|
||||||
"Automatic stdin fallback",
|
"Automatic stdin fallback",
|
||||||
"Multiple output formats",
|
"Multiple output formats",
|
||||||
"Both library and CLI usage"
|
"Both library and CLI usage",
|
||||||
]
|
]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
@ -129,18 +146,343 @@ dependencies = [
|
|||||||
"chrono",
|
"chrono",
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"thiserror"
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Distribution Configuration
|
[plugins.nu_plugin_nickel]
|
||||||
[distribution]
|
upstream_url = "local"
|
||||||
excluded_plugins = [
|
upstream_branch = "main"
|
||||||
"nu_plugin_example"
|
status = "ok"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_nickel"
|
||||||
|
description = "Nushell plugin for Nickel configuration language with eval, export, format, and validation"
|
||||||
|
version = "0.1.0"
|
||||||
|
category = "provisioning"
|
||||||
|
commands = [
|
||||||
|
"nickel-eval",
|
||||||
|
"nickel-export",
|
||||||
|
"nickel-format",
|
||||||
|
"nickel-validate",
|
||||||
|
"nickel-cache-status",
|
||||||
]
|
]
|
||||||
|
dependencies = [
|
||||||
|
"nu-plugin",
|
||||||
|
"nu-protocol",
|
||||||
|
"anyhow",
|
||||||
|
"tempfile",
|
||||||
|
"sha2",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"dirs",
|
||||||
|
"chrono",
|
||||||
|
]
|
||||||
|
features = [
|
||||||
|
"Config file evaluation with caching",
|
||||||
|
"Export Nickel to JSON/YAML",
|
||||||
|
"Format Nickel files",
|
||||||
|
"Validate Nickel projects",
|
||||||
|
"Cache status management",
|
||||||
|
]
|
||||||
|
|
||||||
|
[plugins.nu_plugin_nats]
|
||||||
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "ok"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_nats"
|
||||||
|
description = "NATS JetStream plugin for provisioning platform event bus"
|
||||||
|
version = "0.110.0"
|
||||||
|
category = "provisioning"
|
||||||
|
commands = [
|
||||||
|
"nats stream setup",
|
||||||
|
"nats consumer setup",
|
||||||
|
"nats notify",
|
||||||
|
"nats pub",
|
||||||
|
"nats status",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"async-nats",
|
||||||
|
"tokio",
|
||||||
|
"bytes",
|
||||||
|
"futures",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
features = [
|
||||||
|
"Idempotent stream + consumer provisioning",
|
||||||
|
"Pull drain of cli-notifications consumer",
|
||||||
|
"JetStream publish with stream+sequence ack",
|
||||||
|
"Live stream state for all 6 platform streams",
|
||||||
|
"NATS_SERVER env var or nats://127.0.0.1:4222 default",
|
||||||
|
]
|
||||||
|
|
||||||
|
[distribution]
|
||||||
|
excluded_plugins = ["nu_plugin_example"]
|
||||||
reason = "Reference/documentation plugin - excluded from distributions, installations, and collections. Still included in build and test for validation."
|
reason = "Reference/documentation plugin - excluded from distributions, installations, and collections. Still included in build and test for validation."
|
||||||
|
|
||||||
# Metadata
|
[settings]
|
||||||
|
nu_managed_dependencies = [
|
||||||
|
"nu-plugin",
|
||||||
|
"nu-protocol",
|
||||||
|
"nu-plugin-core",
|
||||||
|
"nu-plugin-protocol",
|
||||||
|
"nu-engine",
|
||||||
|
"nu-system",
|
||||||
|
"nu-path",
|
||||||
|
]
|
||||||
|
|
||||||
[registry]
|
[registry]
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
updated = "2025-10-09"
|
updated = "2025-10-09"
|
||||||
format = "toml"
|
format = "toml"
|
||||||
|
|
||||||
|
["plugins.nu_plugin_auth"]
|
||||||
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "error"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_auth"
|
||||||
|
description = "Authentication plugin (JWT, MFA) for provisioning platform"
|
||||||
|
version = "0.1.0"
|
||||||
|
category = "provisioning"
|
||||||
|
commands = [
|
||||||
|
"auth login",
|
||||||
|
"auth logout",
|
||||||
|
"auth verify",
|
||||||
|
"auth sessions",
|
||||||
|
"auth mfa enroll",
|
||||||
|
"auth mfa verify",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"jsonwebtoken",
|
||||||
|
"reqwest",
|
||||||
|
"keyring",
|
||||||
|
"rpassword",
|
||||||
|
"qrcode",
|
||||||
|
]
|
||||||
|
|
||||||
|
["plugins.nu_plugin_kms"]
|
||||||
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "error"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_kms"
|
||||||
|
description = "KMS plugin (RustyVault, Age, Cosmian) for provisioning platform"
|
||||||
|
version = "0.1.0"
|
||||||
|
category = "provisioning"
|
||||||
|
backends = [
|
||||||
|
"rustyvault",
|
||||||
|
"age",
|
||||||
|
"cosmian",
|
||||||
|
"aws",
|
||||||
|
"vault",
|
||||||
|
]
|
||||||
|
commands = [
|
||||||
|
"kms encrypt",
|
||||||
|
"kms decrypt",
|
||||||
|
"kms generate-key",
|
||||||
|
"kms status",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"reqwest",
|
||||||
|
"age",
|
||||||
|
"base64",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
["plugins.nu_plugin_orchestrator"]
|
||||||
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "error"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_orchestrator"
|
||||||
|
description = "Orchestrator operations plugin (status, validate, tasks)"
|
||||||
|
version = "0.1.0"
|
||||||
|
category = "provisioning"
|
||||||
|
commands = [
|
||||||
|
"orch status",
|
||||||
|
"orch validate",
|
||||||
|
"orch tasks",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"serde_json",
|
||||||
|
"serde_yaml",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
["plugins.nu_plugin_inquire"]
|
||||||
|
upstream_url = "https://github.com/jesusperezlorenzo/nu_plugin_inquire"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "error"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_inquire"
|
||||||
|
description = "Interactive forms and prompts plugin using inquire crate - solves TTY buffering issues"
|
||||||
|
version = "0.1.0"
|
||||||
|
category = "utility"
|
||||||
|
commands = [
|
||||||
|
"inquire text",
|
||||||
|
"inquire confirm",
|
||||||
|
"inquire select",
|
||||||
|
"inquire multi-select",
|
||||||
|
"inquire password",
|
||||||
|
"inquire custom",
|
||||||
|
"inquire editor",
|
||||||
|
"inquire date",
|
||||||
|
"inquire form",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"inquire",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"toml",
|
||||||
|
"chrono",
|
||||||
|
"dialoguer",
|
||||||
|
]
|
||||||
|
|
||||||
|
["plugins.forminquire"]
|
||||||
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "error"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "forminquire"
|
||||||
|
description = "Standalone interactive forms and prompts library + CLI tool - no Nushell dependency required"
|
||||||
|
version = "0.1.0"
|
||||||
|
category = "utility"
|
||||||
|
type = "binary"
|
||||||
|
dual_mode = true
|
||||||
|
commands = [
|
||||||
|
"forminquire text",
|
||||||
|
"forminquire confirm",
|
||||||
|
"forminquire select",
|
||||||
|
"forminquire multi-select",
|
||||||
|
"forminquire password",
|
||||||
|
"forminquire custom",
|
||||||
|
"forminquire editor",
|
||||||
|
"forminquire date",
|
||||||
|
"forminquire form",
|
||||||
|
]
|
||||||
|
library_support = true
|
||||||
|
output_formats = [
|
||||||
|
"text",
|
||||||
|
"json",
|
||||||
|
"yaml",
|
||||||
|
]
|
||||||
|
features = [
|
||||||
|
"8 interactive prompt types",
|
||||||
|
"TOML-based form definitions",
|
||||||
|
"Automatic stdin fallback",
|
||||||
|
"Multiple output formats",
|
||||||
|
"Both library and CLI usage",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"inquire",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_yaml",
|
||||||
|
"toml",
|
||||||
|
"chrono",
|
||||||
|
"dialoguer",
|
||||||
|
"anyhow",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
["plugins.nu_plugin_nickel"]
|
||||||
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "error"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_nickel"
|
||||||
|
description = "Nushell plugin for Nickel configuration language with eval, export, format, and validation"
|
||||||
|
version = "0.1.0"
|
||||||
|
category = "provisioning"
|
||||||
|
commands = [
|
||||||
|
"nickel-eval",
|
||||||
|
"nickel-export",
|
||||||
|
"nickel-format",
|
||||||
|
"nickel-validate",
|
||||||
|
"nickel-cache-status",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"nu-plugin",
|
||||||
|
"nu-protocol",
|
||||||
|
"anyhow",
|
||||||
|
"tempfile",
|
||||||
|
"sha2",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"dirs",
|
||||||
|
"chrono",
|
||||||
|
]
|
||||||
|
features = [
|
||||||
|
"Config file evaluation with caching",
|
||||||
|
"Export Nickel to JSON/YAML",
|
||||||
|
"Format Nickel files",
|
||||||
|
"Validate Nickel projects",
|
||||||
|
"Cache status management",
|
||||||
|
]
|
||||||
|
|
||||||
|
["plugins.nu_plugin_typedialog"]
|
||||||
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "ok"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_typedialog"
|
||||||
|
description = "TypeDialog interactive forms and prompts plugin — replaces shlib TTY wrappers"
|
||||||
|
version = "0.110.0"
|
||||||
|
category = "provisioning"
|
||||||
|
commands = [
|
||||||
|
"typedialog form",
|
||||||
|
"typedialog nickel-roundtrip",
|
||||||
|
"typedialog text",
|
||||||
|
"typedialog confirm",
|
||||||
|
"typedialog select",
|
||||||
|
"typedialog multi-select",
|
||||||
|
"typedialog password",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"nu-plugin",
|
||||||
|
"nu-protocol",
|
||||||
|
"typedialog-core",
|
||||||
|
"tokio",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"interprocess",
|
||||||
|
]
|
||||||
|
features = [
|
||||||
|
"CLI and web backends (--backend cli|web)",
|
||||||
|
"Nickel roundtrip with typecheck validation",
|
||||||
|
"Direct prompts: text, confirm, select, multi-select, password",
|
||||||
|
"ESC/cancel returns null (Value::nothing), not error",
|
||||||
|
"Initial values seeding via --initial <record>",
|
||||||
|
]
|
||||||
|
|
||||||
|
["plugins.nu_plugin_mcp"]
|
||||||
|
upstream_url = "local"
|
||||||
|
upstream_branch = "main"
|
||||||
|
status = "ok"
|
||||||
|
auto_merge = false
|
||||||
|
local_path = "nu_plugin_mcp"
|
||||||
|
description = "MCP client plugin — spawn and interact with provisioning-mcp-server via JSON-RPC 2.0"
|
||||||
|
version = "0.110.0"
|
||||||
|
category = "provisioning"
|
||||||
|
commands = [
|
||||||
|
"mcp connect",
|
||||||
|
"mcp tools list",
|
||||||
|
"mcp tool call",
|
||||||
|
"mcp disconnect",
|
||||||
|
]
|
||||||
|
dependencies = [
|
||||||
|
"nu-plugin",
|
||||||
|
"nu-protocol",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"interprocess",
|
||||||
|
]
|
||||||
|
features = [
|
||||||
|
"Spawn MCP server binary as child process",
|
||||||
|
"MCP protocol handshake (initialize + initialized)",
|
||||||
|
"Tool discovery via tools/list",
|
||||||
|
"Tool dispatch with record payload",
|
||||||
|
"Session state persisted in Arc<Mutex<Option<McpSession>>>",
|
||||||
|
"isError responses mapped to {error: true, message: ...} records",
|
||||||
|
]
|
||||||
|
|||||||
289
guides/README.md
289
guides/README.md
File diff suppressed because one or more lines are too long
@ -3,9 +3,11 @@
|
|||||||
## Fundamental Rules for AI-Friendly Nushell Code
|
## Fundamental Rules for AI-Friendly Nushell Code
|
||||||
|
|
||||||
### Rule 1: One Command, One Purpose
|
### Rule 1: One Command, One Purpose
|
||||||
|
|
||||||
Every command must do exactly one thing. AI agents struggle with multi-purpose functions.
|
Every command must do exactly one thing. AI agents struggle with multi-purpose functions.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Single purpose
|
# ✅ GOOD - Single purpose
|
||||||
def extract-errors [log_file: path] -> table {
|
def extract-errors [log_file: path] -> table {
|
||||||
open $log_file | lines | parse "{time} [{level}] {msg}" | where level == "ERROR"
|
open $log_file | lines | parse "{time} [{level}] {msg}" | where level == "ERROR"
|
||||||
@ -18,9 +20,11 @@ def process-logs [log_file: path, --extract-errors, --count-warnings, --save-out
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 2: Explicit Type Signatures Always
|
### Rule 2: Explicit Type Signatures Always
|
||||||
|
|
||||||
AI agents need clear contracts. Never omit types.
|
AI agents need clear contracts. Never omit types.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Complete type information
|
# ✅ GOOD - Complete type information
|
||||||
def calculate-average [numbers: list<float>] -> float {
|
def calculate-average [numbers: list<float>] -> float {
|
||||||
$numbers | math avg
|
$numbers | math avg
|
||||||
@ -33,9 +37,11 @@ def calculate-average [numbers] {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 3: Return Early, Fail Fast
|
### Rule 3: Return Early, Fail Fast
|
||||||
|
|
||||||
Check preconditions immediately. Don't nest error handling.
|
Check preconditions immediately. Don't nest error handling.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Early returns
|
# ✅ GOOD - Early returns
|
||||||
def process-file [path: path] -> table {
|
def process-file [path: path] -> table {
|
||||||
if not ($path | path exists) {
|
if not ($path | path exists) {
|
||||||
@ -66,9 +72,11 @@ def process-file [path: path] -> table {
|
|||||||
## Essential Patterns for AI Code Generation
|
## Essential Patterns for AI Code Generation
|
||||||
|
|
||||||
### Pattern 1: Command Template Pattern
|
### Pattern 1: Command Template Pattern
|
||||||
|
|
||||||
Use this structure for EVERY command:
|
Use this structure for EVERY command:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# [PURPOSE]: Single-line description of what this does
|
# [PURPOSE]: Single-line description of what this does
|
||||||
# [INPUT]: Expected input format
|
# [INPUT]: Expected input format
|
||||||
# [OUTPUT]: Output format
|
# [OUTPUT]: Output format
|
||||||
@ -90,9 +98,11 @@ def command-name [
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Pattern 2: Pipeline Stage Pattern
|
### Pattern 2: Pipeline Stage Pattern
|
||||||
|
|
||||||
Each pipeline stage must be self-contained and testable:
|
Each pipeline stage must be self-contained and testable:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Clear pipeline stages
|
# ✅ GOOD - Clear pipeline stages
|
||||||
def analyze-data [input: path] -> table {
|
def analyze-data [input: path] -> table {
|
||||||
load-data $input
|
load-data $input
|
||||||
@ -111,11 +121,13 @@ def format-output [data: table] -> table { $data | select relevant_columns }
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Pattern 3: Error Context Pattern
|
### Pattern 3: Error Context Pattern
|
||||||
|
|
||||||
Always provide context for errors that AI can use to fix issues:
|
Always provide context for errors that AI can use to fix issues:
|
||||||
|
|
||||||
in Nushell 0.108, try-catch with error parameter might not be supported when assigning to variables.
|
in Nushell 0.108, try-catch with error parameter might not be supported when assigning to variables.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Detailed error context
|
# ✅ GOOD - Detailed error context
|
||||||
def parse-config [config_path: path] -> record {
|
def parse-config [config_path: path] -> record {
|
||||||
try {
|
try {
|
||||||
@ -134,9 +146,11 @@ def parse-config [config_path: path] -> record {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Pattern 4: Data Validation Pattern
|
### Pattern 4: Data Validation Pattern
|
||||||
|
|
||||||
Validate data structure at boundaries:
|
Validate data structure at boundaries:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Explicit validation
|
# ✅ GOOD - Explicit validation
|
||||||
def process-user-data [data: table] -> table {
|
def process-user-data [data: table] -> table {
|
||||||
# Define expected schema
|
# Define expected schema
|
||||||
@ -163,9 +177,11 @@ def process-user-data [data: table] -> table {
|
|||||||
## Critical Rules for AI Tool Integration
|
## Critical Rules for AI Tool Integration
|
||||||
|
|
||||||
### Rule 4: No Side Effects in Functions
|
### Rule 4: No Side Effects in Functions
|
||||||
|
|
||||||
Functions must be pure unless explicitly named as mutations:
|
Functions must be pure unless explicitly named as mutations:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Pure function
|
# ✅ GOOD - Pure function
|
||||||
def calculate-tax [amount: float, rate: float] -> float {
|
def calculate-tax [amount: float, rate: float] -> float {
|
||||||
$amount * $rate
|
$amount * $rate
|
||||||
@ -186,9 +202,11 @@ def calculate-tax [amount: float, rate: float] -> float {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 5: Atomic Operations
|
### Rule 5: Atomic Operations
|
||||||
|
|
||||||
Every operation must be atomic - it either completely succeeds or completely fails:
|
Every operation must be atomic - it either completely succeeds or completely fails:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Atomic operation
|
# ✅ GOOD - Atomic operation
|
||||||
def update-json-file [path: path, updates: record] -> nothing {
|
def update-json-file [path: path, updates: record] -> nothing {
|
||||||
# Read, modify, write as single operation
|
# Read, modify, write as single operation
|
||||||
@ -208,9 +226,11 @@ def update-json-file [path: path, updates: record] -> nothing {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 6: Explicit Dependencies
|
### Rule 6: Explicit Dependencies
|
||||||
|
|
||||||
Never rely on global state or environment without declaring it:
|
Never rely on global state or environment without declaring it:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Explicit dependencies
|
# ✅ GOOD - Explicit dependencies
|
||||||
def api-request [
|
def api-request [
|
||||||
endpoint: string
|
endpoint: string
|
||||||
@ -232,9 +252,11 @@ def api-request [endpoint: string] -> any {
|
|||||||
## Structured Data Patterns
|
## Structured Data Patterns
|
||||||
|
|
||||||
### Pattern 5: Table Transformation Pattern
|
### Pattern 5: Table Transformation Pattern
|
||||||
|
|
||||||
Always use Nushell's table operations instead of loops:
|
Always use Nushell's table operations instead of loops:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Table operations
|
# ✅ GOOD - Table operations
|
||||||
def transform-sales [sales: table] -> table {
|
def transform-sales [sales: table] -> table {
|
||||||
$sales
|
$sales
|
||||||
@ -258,9 +280,11 @@ def transform-sales [sales: table] -> table {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Pattern 6: Schema Definition Pattern
|
### Pattern 6: Schema Definition Pattern
|
||||||
|
|
||||||
Define data schemas explicitly for AI understanding:
|
Define data schemas explicitly for AI understanding:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Schema definitions at module level
|
# Schema definitions at module level
|
||||||
const USER_SCHEMA = {
|
const USER_SCHEMA = {
|
||||||
id: "int"
|
id: "int"
|
||||||
@ -291,9 +315,11 @@ def validate-user [user: record] -> bool {
|
|||||||
## AI-Specific Patterns
|
## AI-Specific Patterns
|
||||||
|
|
||||||
### Pattern 7: Self-Documenting Code Pattern
|
### Pattern 7: Self-Documenting Code Pattern
|
||||||
|
|
||||||
Include inline documentation that AI can parse:
|
Include inline documentation that AI can parse:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
def complex-calculation [
|
def complex-calculation [
|
||||||
data: table # @format: [{x: float, y: float, weight: float}]
|
data: table # @format: [{x: float, y: float, weight: float}]
|
||||||
] -> record { # @returns: {mean: float, std: float, correlation: float}
|
] -> record { # @returns: {mean: float, std: float, correlation: float}
|
||||||
@ -318,9 +344,11 @@ def complex-calculation [
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Pattern 8: Testable Unit Pattern
|
### Pattern 8: Testable Unit Pattern
|
||||||
|
|
||||||
Every function must include test examples:
|
Every function must include test examples:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Function with embedded test cases
|
# Function with embedded test cases
|
||||||
def parse-version [version: string] -> record {
|
def parse-version [version: string] -> record {
|
||||||
# @test: "1.2.3" -> {major: 1, minor: 2, patch: 3}
|
# @test: "1.2.3" -> {major: 1, minor: 2, patch: 3}
|
||||||
@ -342,9 +370,11 @@ def test-parse-version [] {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Pattern 9: Incremental Computation Pattern
|
### Pattern 9: Incremental Computation Pattern
|
||||||
|
|
||||||
Break complex computations into verifiable steps:
|
Break complex computations into verifiable steps:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Each step is verifiable
|
# ✅ GOOD - Each step is verifiable
|
||||||
def analyze-dataset [data: path] -> record {
|
def analyze-dataset [data: path] -> record {
|
||||||
# Load and get shape
|
# Load and get shape
|
||||||
@ -373,9 +403,11 @@ def analyze-dataset [data: path] -> record {
|
|||||||
## Module Organization Rules
|
## Module Organization Rules
|
||||||
|
|
||||||
### Rule 7: Single Responsibility Modules
|
### Rule 7: Single Responsibility Modules
|
||||||
|
|
||||||
Each module handles one domain:
|
Each module handles one domain:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# file: data_validation.nu
|
# file: data_validation.nu
|
||||||
module data_validation {
|
module data_validation {
|
||||||
export def validate-email [email: string] -> bool { }
|
export def validate-email [email: string] -> bool { }
|
||||||
@ -392,9 +424,11 @@ module data_transformation {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 8: Explicit Exports
|
### Rule 8: Explicit Exports
|
||||||
|
|
||||||
Only export what's needed:
|
Only export what's needed:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
module api_client {
|
module api_client {
|
||||||
# Public API
|
# Public API
|
||||||
export def get [endpoint: string] -> any {
|
export def get [endpoint: string] -> any {
|
||||||
@ -415,9 +449,11 @@ module api_client {
|
|||||||
## Performance Rules for AI Tools
|
## Performance Rules for AI Tools
|
||||||
|
|
||||||
### Rule 9: Lazy Evaluation
|
### Rule 9: Lazy Evaluation
|
||||||
|
|
||||||
Don't compute until necessary:
|
Don't compute until necessary:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Lazy evaluation
|
# ✅ GOOD - Lazy evaluation
|
||||||
def process-conditionally [
|
def process-conditionally [
|
||||||
data: table
|
data: table
|
||||||
@ -436,9 +472,11 @@ def process-conditionally [
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 10: Stream Large Data
|
### Rule 10: Stream Large Data
|
||||||
|
|
||||||
Never load entire large files into memory:
|
Never load entire large files into memory:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Streaming
|
# ✅ GOOD - Streaming
|
||||||
def process-large-file [path: path] -> nothing {
|
def process-large-file [path: path] -> nothing {
|
||||||
open --raw $path
|
open --raw $path
|
||||||
@ -460,9 +498,11 @@ def process-large-file [path: path] -> table {
|
|||||||
## Error Handling Rules
|
## Error Handling Rules
|
||||||
|
|
||||||
### Rule 11: Never Swallow Errors
|
### Rule 11: Never Swallow Errors
|
||||||
|
|
||||||
Always propagate or handle errors explicitly:
|
Always propagate or handle errors explicitly:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Explicit error handling
|
# ✅ GOOD - Explicit error handling
|
||||||
def safe-divide [a: float, b: float] -> float {
|
def safe-divide [a: float, b: float] -> float {
|
||||||
if $b == 0 {
|
if $b == 0 {
|
||||||
@ -478,9 +518,11 @@ def safe-divide [a: float, b: float] -> float {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 12: Structured Error Returns
|
### Rule 12: Structured Error Returns
|
||||||
|
|
||||||
Use consistent error structures:
|
Use consistent error structures:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Define error type
|
# Define error type
|
||||||
const ERROR_SCHEMA = {
|
const ERROR_SCHEMA = {
|
||||||
success: "bool"
|
success: "bool"
|
||||||
@ -512,9 +554,11 @@ def api-call [url: string] -> record {
|
|||||||
## Code Generation Rules for AI
|
## Code Generation Rules for AI
|
||||||
|
|
||||||
### Rule 13: Predictable Naming
|
### Rule 13: Predictable Naming
|
||||||
|
|
||||||
Use consistent, predictable names:
|
Use consistent, predictable names:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Naming conventions AI can predict:
|
# Naming conventions AI can predict:
|
||||||
# - get-* : Returns data without modification
|
# - get-* : Returns data without modification
|
||||||
# - set-* : Updates data
|
# - set-* : Updates data
|
||||||
@ -536,9 +580,11 @@ def parse-json [text: string] -> any { }
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 14: Consistent Parameter Order
|
### Rule 14: Consistent Parameter Order
|
||||||
|
|
||||||
Always use this parameter order:
|
Always use this parameter order:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Order: required positional, optional positional, flags
|
# Order: required positional, optional positional, flags
|
||||||
def command [
|
def command [
|
||||||
required1: type # Required parameters first
|
required1: type # Required parameters first
|
||||||
@ -550,9 +596,11 @@ def command [
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 15: Return Type Consistency
|
### Rule 15: Return Type Consistency
|
||||||
|
|
||||||
Use consistent return types for similar operations:
|
Use consistent return types for similar operations:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# All getters return record or null
|
# All getters return record or null
|
||||||
def get-config [] -> record? {
|
def get-config [] -> record? {
|
||||||
try { open config.json } catch { null }
|
try { open config.json } catch { null }
|
||||||
@ -571,9 +619,11 @@ def transform-table [input: table] -> table {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rule 16: Function Signature Syntax with Pipeline Types (Nushell 0.107.1+)
|
### Rule 16: Function Signature Syntax with Pipeline Types (Nushell 0.107.1+)
|
||||||
|
|
||||||
**CRITICAL**: When using return type annotations, use the pipeline signature: `[params]: input_type -> return_type`
|
**CRITICAL**: When using return type annotations, use the pipeline signature: `[params]: input_type -> return_type`
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Complete pipeline signature
|
# ✅ GOOD - Complete pipeline signature
|
||||||
def process-data [input: string]: nothing -> table {
|
def process-data [input: string]: nothing -> table {
|
||||||
$input | from json
|
$input | from json
|
||||||
@ -601,9 +651,11 @@ def process-data [input: string] {
|
|||||||
**Note**: The syntax is `[parameters]: input_type -> return_type`. Both the colon AND arrow are required when specifying return types. This has been the syntax since Nushell 0.107.1.
|
**Note**: The syntax is `[parameters]: input_type -> return_type`. Both the colon AND arrow are required when specifying return types. This has been the syntax since Nushell 0.107.1.
|
||||||
|
|
||||||
### Rule 17: String Interpolation - Always Use Parentheses
|
### Rule 17: String Interpolation - Always Use Parentheses
|
||||||
|
|
||||||
**CRITICAL**: In string interpolations, ALWAYS use parentheses `($var)` or `($expr)` for ALL interpolations.
|
**CRITICAL**: In string interpolations, ALWAYS use parentheses `($var)` or `($expr)` for ALL interpolations.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# ✅ GOOD - Parentheses for variables
|
# ✅ GOOD - Parentheses for variables
|
||||||
print $"Processing file ($filename) at ($timestamp)"
|
print $"Processing file ($filename) at ($timestamp)"
|
||||||
print $"Server ($hostname) running on port ($port)"
|
print $"Server ($hostname) running on port ($port)"
|
||||||
@ -624,12 +676,14 @@ print $"Server $hostname on port $port"
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Why**:
|
**Why**:
|
||||||
|
|
||||||
- Parentheses `($var)` or `($expr)` are the ONLY way to interpolate in Nushell strings
|
- Parentheses `($var)` or `($expr)` are the ONLY way to interpolate in Nushell strings
|
||||||
- Square brackets `[...]` are treated as literal characters (no interpolation)
|
- Square brackets `[...]` are treated as literal characters (no interpolation)
|
||||||
- Both variables and expressions use the same syntax: `($something)`
|
- Both variables and expressions use the same syntax: `($something)`
|
||||||
- Consistent syntax reduces errors and improves maintainability
|
- Consistent syntax reduces errors and improves maintainability
|
||||||
|
|
||||||
**Rule of thumb**:
|
**Rule of thumb**:
|
||||||
|
|
||||||
- Variable? Use `($var)`
|
- Variable? Use `($var)`
|
||||||
- Expression? Use `($expr)`
|
- Expression? Use `($expr)`
|
||||||
- Function call? Use `($fn arg)`
|
- Function call? Use `($fn arg)`
|
||||||
@ -640,24 +694,31 @@ print $"Server $hostname on port $port"
|
|||||||
**CRITICAL**: In `$"..."` strings, parentheses that are NOT variable interpolation MUST be escaped.
|
**CRITICAL**: In `$"..."` strings, parentheses that are NOT variable interpolation MUST be escaped.
|
||||||
|
|
||||||
❌ **WRONG**:
|
❌ **WRONG**:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
let msg = $"Update? (yes/no): " # ERROR: (yes/no) treated as command
|
let msg = $"Update? (yes/no): " # ERROR: (yes/no) treated as command
|
||||||
let text = $"Use format (JSON/YAML)" # ERROR: tries to execute command
|
let text = $"Use format (JSON/YAML)" # ERROR: tries to execute command
|
||||||
```
|
```
|
||||||
|
|
||||||
✅ **CORRECT**:
|
✅ **CORRECT**:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
let msg = $"Update? \(yes/no\): " # Escaped literal parentheses
|
let msg = $"Update? \(yes/no\): " # Escaped literal parentheses
|
||||||
let text = $"Use format \(JSON/YAML\)" # Escaped literal parentheses
|
let text = $"Use format \(JSON/YAML\)" # Escaped literal parentheses
|
||||||
let msg = $"Value: ($var)" # Unescaped for variable interpolation
|
let msg = $"Value: ($var)" # Unescaped for variable interpolation
|
||||||
```
|
```
|
||||||
|
|
||||||
**Simple rule**:
|
**Simple rule**:
|
||||||
|
|
||||||
- If `()` contains a variable name → keep as is: `($variable)`
|
- If `()` contains a variable name → keep as is: `($variable)`
|
||||||
- If `()` is literal text → escape with backslash: `\(text\)`
|
- If `()` is literal text → escape with backslash: `\(text\)`
|
||||||
|
|
||||||
**Common mistake patterns:**
|
**Common mistake patterns:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# BAD - will try to execute 'yes/no' command
|
# BAD - will try to execute 'yes/no' command
|
||||||
input $"Continue? (yes/no): "
|
input $"Continue? (yes/no): "
|
||||||
|
|
||||||
@ -676,6 +737,7 @@ log_info $"Format \(example\): data"
|
|||||||
## Quick Reference Card for AI Agents
|
## Quick Reference Card for AI Agents
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# TEMPLATE: Copy-paste this for new commands (Nushell 0.107.1+)
|
# TEMPLATE: Copy-paste this for new commands (Nushell 0.107.1+)
|
||||||
# [PURPOSE]:
|
# [PURPOSE]:
|
||||||
# [INPUT]:
|
# [INPUT]:
|
||||||
@ -716,6 +778,7 @@ def command-name [
|
|||||||
## Summary Checklist for AI-Compatible Nushell
|
## Summary Checklist for AI-Compatible Nushell
|
||||||
|
|
||||||
✅ **Every function has:**
|
✅ **Every function has:**
|
||||||
|
|
||||||
- Explicit type signatures with pipeline syntax `[param: type]: input_type -> return_type {`
|
- Explicit type signatures with pipeline syntax `[param: type]: input_type -> return_type {`
|
||||||
- Single responsibility
|
- Single responsibility
|
||||||
- Early validation
|
- Early validation
|
||||||
@ -723,6 +786,7 @@ def command-name [
|
|||||||
- Test examples
|
- Test examples
|
||||||
|
|
||||||
✅ **Never use:**
|
✅ **Never use:**
|
||||||
|
|
||||||
- Global state without declaration
|
- Global state without declaration
|
||||||
- Hidden side effects
|
- Hidden side effects
|
||||||
- Nested conditionals (prefer early returns)
|
- Nested conditionals (prefer early returns)
|
||||||
@ -733,6 +797,7 @@ def command-name [
|
|||||||
- Function signatures without both colon AND arrow when specifying return types
|
- Function signatures without both colon AND arrow when specifying return types
|
||||||
|
|
||||||
✅ **Always prefer:**
|
✅ **Always prefer:**
|
||||||
|
|
||||||
- Pipeline operations over loops
|
- Pipeline operations over loops
|
||||||
- Pure functions over stateful
|
- Pure functions over stateful
|
||||||
- Explicit over implicit
|
- Explicit over implicit
|
||||||
@ -741,6 +806,7 @@ def command-name [
|
|||||||
- Parentheses `($var)` for ALL string interpolations (variables and expressions)
|
- Parentheses `($var)` for ALL string interpolations (variables and expressions)
|
||||||
|
|
||||||
✅ **For AI tools specifically:**
|
✅ **For AI tools specifically:**
|
||||||
|
|
||||||
- Use predictable naming patterns
|
- Use predictable naming patterns
|
||||||
- Include operation markers (! for mutations)
|
- Include operation markers (! for mutations)
|
||||||
- Document schemas inline
|
- Document schemas inline
|
||||||
@ -763,27 +829,26 @@ Following these rules and patterns ensures that AI agents like Claude Code can e
|
|||||||
- config/loader.nu
|
- config/loader.nu
|
||||||
- oci/client.nu (8 blocks - OCI currently disabled)
|
- oci/client.nu (8 blocks - OCI currently disabled)
|
||||||
|
|
||||||
2. Function Signature Syntax (2 instances)
|
1. Function Signature Syntax (2 instances)
|
||||||
|
|
||||||
- Issue: Missing input type in signatures
|
- Issue: Missing input type in signatures
|
||||||
- Old: def foo [x: string] -> bool
|
- Old: def foo [x: string] -> bool
|
||||||
- New: def foo [x: string]: nothing -> bool
|
- New: def foo [x: string]: nothing -> bool
|
||||||
- Files fixed: workspace/helpers.nu
|
- Files fixed: workspace/helpers.nu
|
||||||
|
|
||||||
3. Boolean Flag Syntax (1 instance)
|
1. Boolean Flag Syntax (1 instance)
|
||||||
|
|
||||||
- Issue: Type annotations not allowed on boolean flags
|
- Issue: Type annotations not allowed on boolean flags
|
||||||
- Old: --flag: bool = true
|
- Old: --flag: bool = true
|
||||||
- New: --flag = true
|
- New: --flag = true
|
||||||
- Files fixed: main_provisioning/contexts.nu
|
- Files fixed: main_provisioning/contexts.nu
|
||||||
|
|
||||||
4. Variable Type Initialization (1 instance)
|
1. Variable Type Initialization (1 instance)
|
||||||
|
|
||||||
- Issue: Can't assign record to null variable in 0.108
|
- Issue: Can't assign record to null variable in 0.108
|
||||||
- Old: mut var = null; $var = {record}
|
- Old: mut var = null; $var = {record}
|
||||||
- New: mut var = {success: false}; $var = {record}
|
- New: mut var = {success: false}; $var = {record}
|
||||||
|
|
||||||
|
|
||||||
#" Before (fails in Nushell 0.107.1)
|
#" Before (fails in Nushell 0.107.1)
|
||||||
try {
|
try {
|
||||||
# operations
|
# operations
|
||||||
@ -794,6 +859,7 @@ Following these rules and patterns ensures that AI agents like Claude Code can e
|
|||||||
}
|
}
|
||||||
|
|
||||||
# After (works in Nushell 0.107.1)
|
# After (works in Nushell 0.107.1)
|
||||||
|
|
||||||
let result = (do {
|
let result = (do {
|
||||||
# operations
|
# operations
|
||||||
result
|
result
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,6 +1,5 @@
|
|||||||
# Tools Module - Development Tools and Utilities
|
# Tools Module - Development Tools and Utilities
|
||||||
# Commands for development utilities, plugin management, and system tools
|
# Commands for development utilities, plugin management, and system tools
|
||||||
|
|
||||||
# 🔍 VERSION AND VALIDATION COMMANDS
|
# 🔍 VERSION AND VALIDATION COMMANDS
|
||||||
|
|
||||||
# Check nushell version consistency
|
# Check nushell version consistency
|
||||||
@ -83,7 +82,7 @@ install-local:
|
|||||||
PLATFORM_DIR=$(find distribution -maxdepth 1 -type d -name "*-*" | head -n1)
|
PLATFORM_DIR=$(find distribution -maxdepth 1 -type d -name "*-*" | head -n1)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$PLATFORM_DIR" ] || [ ! -f "$PLATFORM_DIR/install.nu" ]; then
|
if [ -z "$PLATFORM_DIR" ] || [ ! -f "$PLATFORM_DIR/install.sh" ]; then
|
||||||
echo "❌ Installation script not found in distribution"
|
echo "❌ Installation script not found in distribution"
|
||||||
echo "💡 Run 'just collect' to regenerate distribution"
|
echo "💡 Run 'just collect' to regenerate distribution"
|
||||||
exit 1
|
exit 1
|
||||||
@ -92,7 +91,7 @@ install-local:
|
|||||||
echo "📦 Installing plugins locally from distribution..."
|
echo "📦 Installing plugins locally from distribution..."
|
||||||
echo "💡 Using register-only mode (no sudo required)"
|
echo "💡 Using register-only mode (no sudo required)"
|
||||||
echo "💡 Using distribution: $PLATFORM_DIR"
|
echo "💡 Using distribution: $PLATFORM_DIR"
|
||||||
cd "$PLATFORM_DIR" && nu install.nu --verify
|
cd "$PLATFORM_DIR" && bash install.sh --local
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "✅ Local installation completed!"
|
echo "✅ Local installation completed!"
|
||||||
@ -120,7 +119,7 @@ install-system:
|
|||||||
PLATFORM_DIR=$(find distribution -maxdepth 1 -type d -name "*-*" | head -n1)
|
PLATFORM_DIR=$(find distribution -maxdepth 1 -type d -name "*-*" | head -n1)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$PLATFORM_DIR" ] || [ ! -f "$PLATFORM_DIR/install.nu" ]; then
|
if [ -z "$PLATFORM_DIR" ] || [ ! -f "$PLATFORM_DIR/install.sh" ]; then
|
||||||
echo "❌ Installation script not found in distribution"
|
echo "❌ Installation script not found in distribution"
|
||||||
echo "💡 Run 'just collect' to regenerate distribution"
|
echo "💡 Run 'just collect' to regenerate distribution"
|
||||||
exit 1
|
exit 1
|
||||||
@ -136,6 +135,7 @@ install-system:
|
|||||||
|
|
||||||
# Copy nushell binary to user location (safer than system)
|
# Copy nushell binary to user location (safer than system)
|
||||||
echo " Installing nushell binary to ~/.local/bin..."
|
echo " Installing nushell binary to ~/.local/bin..."
|
||||||
|
rm -f ~/.local/bin/nu # Remove old version if it exists
|
||||||
cp "$PLATFORM_DIR/nu" ~/.local/bin/nu
|
cp "$PLATFORM_DIR/nu" ~/.local/bin/nu
|
||||||
chmod +x ~/.local/bin/nu
|
chmod +x ~/.local/bin/nu
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ install-system:
|
|||||||
|
|
||||||
# Verify installation
|
# Verify installation
|
||||||
echo " Verifying installation..."
|
echo " Verifying installation..."
|
||||||
~/.local/bin/nu -c "plugin list" | head -20
|
~/.local/bin/nu -c "plugin list" # | head -20
|
||||||
|
|
||||||
# Update PATH suggestion
|
# Update PATH suggestion
|
||||||
echo ""
|
echo ""
|
||||||
@ -206,7 +206,7 @@ install-from-archive ARCHIVE="":
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "📦 Installing from archive: $ARCHIVE"
|
echo "📦 Installing from archive: $ARCHIVE"
|
||||||
./install.sh --source-path "$ARCHIVE" --install-dir ~/.local --verify
|
./install.sh --source-path "$ARCHIVE" --install-dir ~/.local/bin --verify
|
||||||
|
|
||||||
# Install from bin_archives/ (fastest - everything already built)
|
# Install from bin_archives/ (fastest - everything already built)
|
||||||
[no-cd]
|
[no-cd]
|
||||||
@ -230,7 +230,7 @@ install-fast:
|
|||||||
echo "📍 Installing to: ~/.local/bin"
|
echo "📍 Installing to: ~/.local/bin"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
./install.sh --source-path "$ARCHIVE" --install-dir ~/.local --verify
|
./install.sh --source-path "$ARCHIVE" --install-dir ~/.local/bin --verify
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "✅ Installation complete!"
|
echo "✅ Installation complete!"
|
||||||
|
|||||||
@ -262,6 +262,20 @@ list-versions:
|
|||||||
@echo "📋 Plugin Version List"
|
@echo "📋 Plugin Version List"
|
||||||
@nu {{justfile_directory()}}/scripts/update_all_plugins.nu --list
|
@nu {{justfile_directory()}}/scripts/update_all_plugins.nu --list
|
||||||
|
|
||||||
|
# Replace [package] version from old to new (only exact matches)
|
||||||
|
[no-cd]
|
||||||
|
[group('version-update')]
|
||||||
|
replace-package-version FROM TO:
|
||||||
|
@echo "🔄 Replacing [package] version from {{FROM}} to {{TO}}"
|
||||||
|
@nu {{justfile_directory()}}/scripts/update_all_plugins.nu replace-version {{FROM}} {{TO}}
|
||||||
|
|
||||||
|
# Preview [package] version replacement (dry-run)
|
||||||
|
[no-cd]
|
||||||
|
[group('version-update')]
|
||||||
|
preview-package-version FROM TO:
|
||||||
|
@echo "🔍 Preview: Replacing [package] version from {{FROM}} to {{TO}}"
|
||||||
|
@nu {{justfile_directory()}}/scripts/update_all_plugins.nu replace-version {{FROM}} {{TO}} --dry-run
|
||||||
|
|
||||||
# 📦 DISTRIBUTION CREATION
|
# 📦 DISTRIBUTION CREATION
|
||||||
|
|
||||||
# Create complete distribution packages (nushell + all plugins)
|
# Create complete distribution packages (nushell + all plugins)
|
||||||
@ -480,6 +494,10 @@ update-help:
|
|||||||
@echo " just dist-status - Show distribution status"
|
@echo " just dist-status - Show distribution status"
|
||||||
@echo " just list-versions - List plugin versions"
|
@echo " just list-versions - List plugin versions"
|
||||||
@echo ""
|
@echo ""
|
||||||
|
@echo "Package Version Management:"
|
||||||
|
@echo " just replace-package-version 0.109.1 0.110.0 - Replace [package] version"
|
||||||
|
@echo " just preview-package-version 0.109.1 0.110.0 - Preview replacement (dry-run)"
|
||||||
|
@echo ""
|
||||||
@echo "Documentation:"
|
@echo "Documentation:"
|
||||||
@echo " just update-docs - Show documentation paths"
|
@echo " just update-docs - Show documentation paths"
|
||||||
@echo " cat guides/COMPLETE_VERSION_UPDATE_GUIDE.md"
|
@echo " cat guides/COMPLETE_VERSION_UPDATE_GUIDE.md"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nu_plugin_auth"
|
name = "nu_plugin_auth"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
authors = ["Jesus Perez <jesus@librecloud.online>"]
|
authors = ["Jesus Perez <jesus@librecloud.online>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Nushell plugin for provisioning authentication (JWT, MFA)"
|
description = "Nushell plugin for provisioning authentication (JWT, MFA)"
|
||||||
@ -8,8 +8,8 @@ repository = "https://github.com/provisioning/nu_plugin_auth"
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = "0.109.1"
|
nu-plugin = "0.111.0"
|
||||||
nu-protocol = "0.109.1"
|
nu-protocol = "0.111.0"
|
||||||
jsonwebtoken = "=9.3"
|
jsonwebtoken = "=9.3"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
keyring = "3.6"
|
keyring = "3.6"
|
||||||
@ -39,6 +39,5 @@ features = ["full"]
|
|||||||
version = "5.7"
|
version = "5.7"
|
||||||
features = ["qr"]
|
features = ["qr"]
|
||||||
|
|
||||||
[dev-dependencies.nu-plugin-test-support]
|
[dev-dependencies]
|
||||||
version = "0.109.1"
|
nu-plugin-test-support = "0.111.0"
|
||||||
path = "../nushell/crates/nu-plugin-test-support"
|
|
||||||
|
|||||||
@ -1,44 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nu_plugin_auth"
|
|
||||||
version = "0.109.0"
|
|
||||||
authors = ["Jesus Perez <jesus@librecloud.online>"]
|
|
||||||
edition = "2021"
|
|
||||||
description = "Nushell plugin for provisioning authentication (JWT, MFA)"
|
|
||||||
repository = "https://github.com/provisioning/nu_plugin_auth"
|
|
||||||
license = "MIT"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
nu-plugin = "0.109.1"
|
|
||||||
nu-protocol = "0.109.1"
|
|
||||||
jsonwebtoken = "=9.3"
|
|
||||||
serde_json = "1.0"
|
|
||||||
keyring = "3.6"
|
|
||||||
rpassword = "7.4"
|
|
||||||
base64 = "0.22"
|
|
||||||
qrcode = "0.14"
|
|
||||||
chrono = "0.4"
|
|
||||||
|
|
||||||
[dependencies.reqwest]
|
|
||||||
version = "0.12"
|
|
||||||
features = [
|
|
||||||
"json",
|
|
||||||
"rustls-tls",
|
|
||||||
"blocking",
|
|
||||||
]
|
|
||||||
default-features = false
|
|
||||||
|
|
||||||
[dependencies.serde]
|
|
||||||
version = "1.0"
|
|
||||||
features = ["derive"]
|
|
||||||
|
|
||||||
[dependencies.tokio]
|
|
||||||
version = "1.48"
|
|
||||||
features = ["full"]
|
|
||||||
|
|
||||||
[dependencies.totp-rs]
|
|
||||||
version = "5.7"
|
|
||||||
features = ["qr"]
|
|
||||||
|
|
||||||
[dev-dependencies.nu-plugin-test-support]
|
|
||||||
version = "0.109.0"
|
|
||||||
path = "../nushell/crates/nu-plugin-test-support"
|
|
||||||
@ -21,12 +21,16 @@ This plugin provides native Nushell commands for authenticating with the provisi
|
|||||||
Login to provisioning platform with JWT authentication.
|
Login to provisioning platform with JWT authentication.
|
||||||
|
|
||||||
**Syntax:**
|
**Syntax:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth login <username> [password] [--url <control-center-url>] [--save]
|
auth login <username> [password] [--url <control-center-url>] [--save]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Login with password prompt (secure)
|
# Login with password prompt (secure)
|
||||||
auth login admin
|
auth login admin
|
||||||
|
|
||||||
@ -45,12 +49,16 @@ auth login admin --save
|
|||||||
Logout from provisioning platform (revoke tokens).
|
Logout from provisioning platform (revoke tokens).
|
||||||
|
|
||||||
**Syntax:**
|
**Syntax:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth logout [--all]
|
auth logout [--all]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Logout from current session
|
# Logout from current session
|
||||||
auth logout
|
auth logout
|
||||||
|
|
||||||
@ -63,12 +71,16 @@ auth logout --all
|
|||||||
Verify current authentication token.
|
Verify current authentication token.
|
||||||
|
|
||||||
**Syntax:**
|
**Syntax:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth verify [--token <jwt-token>]
|
auth verify [--token <jwt-token>]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Verify stored authentication token
|
# Verify stored authentication token
|
||||||
auth verify
|
auth verify
|
||||||
|
|
||||||
@ -81,12 +93,16 @@ auth verify --token eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
|
|||||||
List active authentication sessions.
|
List active authentication sessions.
|
||||||
|
|
||||||
**Syntax:**
|
**Syntax:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth sessions [--active]
|
auth sessions [--active]
|
||||||
```
|
```
|
||||||
|
|
||||||
**Examples:**
|
**Examples:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# List all sessions
|
# List all sessions
|
||||||
auth sessions
|
auth sessions
|
||||||
|
|
||||||
@ -98,7 +114,8 @@ auth sessions --active
|
|||||||
|
|
||||||
### Build from source
|
### Build from source
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
cd provisioning/core/plugins/nushell-plugins/nu_plugin_auth
|
cd provisioning/core/plugins/nushell-plugins/nu_plugin_auth
|
||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
@ -106,13 +123,15 @@ cargo build --release
|
|||||||
### Register with Nushell
|
### Register with Nushell
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
plugin add target/release/nu_plugin_auth
|
plugin add target/release/nu_plugin_auth
|
||||||
plugin use auth
|
plugin use auth
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using justfile (recommended)
|
### Using justfile (recommended)
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# From nushell-plugins directory
|
# From nushell-plugins directory
|
||||||
just install-plugin nu_plugin_auth
|
just install-plugin nu_plugin_auth
|
||||||
|
|
||||||
@ -131,6 +150,7 @@ The plugin uses the following defaults:
|
|||||||
Override defaults using command flags:
|
Override defaults using command flags:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Use custom control center URL
|
# Use custom control center URL
|
||||||
auth login admin --url https://control.production.example.com
|
auth login admin --url https://control.production.example.com
|
||||||
```
|
```
|
||||||
@ -167,6 +187,7 @@ See control center API documentation for details: `provisioning/platform/control
|
|||||||
**Version**: 0.1.0 (Initial structure)
|
**Version**: 0.1.0 (Initial structure)
|
||||||
|
|
||||||
**Implementation Progress**:
|
**Implementation Progress**:
|
||||||
|
|
||||||
- ✅ Plugin structure created (Agente 1)
|
- ✅ Plugin structure created (Agente 1)
|
||||||
- ⏳ Login command implementation (Agente 2)
|
- ⏳ Login command implementation (Agente 2)
|
||||||
- ⏳ Logout command implementation (Agente 3)
|
- ⏳ Logout command implementation (Agente 3)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -10,6 +10,7 @@
|
|||||||
## ✅ Completed Components
|
## ✅ Completed Components
|
||||||
|
|
||||||
### 1. Login Command (`auth login`)
|
### 1. Login Command (`auth login`)
|
||||||
|
|
||||||
- [x] Username/password authentication
|
- [x] Username/password authentication
|
||||||
- [x] Secure password prompt (no echo)
|
- [x] Secure password prompt (no echo)
|
||||||
- [x] HTTP POST to `/auth/login`
|
- [x] HTTP POST to `/auth/login`
|
||||||
@ -20,6 +21,7 @@
|
|||||||
- [x] Error handling (HTTP errors, keyring errors)
|
- [x] Error handling (HTTP errors, keyring errors)
|
||||||
|
|
||||||
### 2. Logout Command (`auth logout`)
|
### 2. Logout Command (`auth logout`)
|
||||||
|
|
||||||
- [x] Token retrieval from keyring
|
- [x] Token retrieval from keyring
|
||||||
- [x] HTTP POST to `/auth/logout`
|
- [x] HTTP POST to `/auth/logout`
|
||||||
- [x] Token revocation on server
|
- [x] Token revocation on server
|
||||||
@ -29,6 +31,7 @@
|
|||||||
- [x] Error handling (no session, HTTP errors)
|
- [x] Error handling (no session, HTTP errors)
|
||||||
|
|
||||||
### 3. Helper Functions (`src/helpers.rs`)
|
### 3. Helper Functions (`src/helpers.rs`)
|
||||||
|
|
||||||
- [x] `store_tokens_in_keyring()` - Save JWT tokens securely
|
- [x] `store_tokens_in_keyring()` - Save JWT tokens securely
|
||||||
- [x] `get_access_token()` - Retrieve access token
|
- [x] `get_access_token()` - Retrieve access token
|
||||||
- [x] `get_tokens_from_keyring()` - Retrieve both tokens
|
- [x] `get_tokens_from_keyring()` - Retrieve both tokens
|
||||||
@ -40,6 +43,7 @@
|
|||||||
- [x] `list_sessions()` - HTTP sessions API (ready for future use)
|
- [x] `list_sessions()` - HTTP sessions API (ready for future use)
|
||||||
|
|
||||||
### 4. MFA Support (BONUS)
|
### 4. MFA Support (BONUS)
|
||||||
|
|
||||||
- [x] `send_mfa_enroll_request()` - TOTP/WebAuthn enrollment
|
- [x] `send_mfa_enroll_request()` - TOTP/WebAuthn enrollment
|
||||||
- [x] `send_mfa_verify_request()` - TOTP code verification
|
- [x] `send_mfa_verify_request()` - TOTP code verification
|
||||||
- [x] `generate_qr_code()` - QR code generation for TOTP
|
- [x] `generate_qr_code()` - QR code generation for TOTP
|
||||||
@ -48,6 +52,7 @@
|
|||||||
- [x] `auth mfa verify` command
|
- [x] `auth mfa verify` command
|
||||||
|
|
||||||
### 5. Security Features
|
### 5. Security Features
|
||||||
|
|
||||||
- [x] OS keyring integration (macOS Keychain, Linux libsecret, Windows Credential Manager)
|
- [x] OS keyring integration (macOS Keychain, Linux libsecret, Windows Credential Manager)
|
||||||
- [x] Secure password input (rpassword crate)
|
- [x] Secure password input (rpassword crate)
|
||||||
- [x] HTTPS with rustls-tls
|
- [x] HTTPS with rustls-tls
|
||||||
@ -56,6 +61,7 @@
|
|||||||
- [x] Server-side token revocation
|
- [x] Server-side token revocation
|
||||||
|
|
||||||
### 6. Documentation
|
### 6. Documentation
|
||||||
|
|
||||||
- [x] `LOGIN_LOGOUT_IMPLEMENTATION.md` - Complete implementation details
|
- [x] `LOGIN_LOGOUT_IMPLEMENTATION.md` - Complete implementation details
|
||||||
- [x] `QUICK_REFERENCE.md` - Command reference card
|
- [x] `QUICK_REFERENCE.md` - Command reference card
|
||||||
- [x] `IMPLEMENTATION_STATUS.md` - This status file
|
- [x] `IMPLEMENTATION_STATUS.md` - This status file
|
||||||
@ -67,7 +73,9 @@
|
|||||||
## 🔧 Build Status
|
## 🔧 Build Status
|
||||||
|
|
||||||
### Compilation
|
### Compilation
|
||||||
```bash
|
|
||||||
|
```nushell
|
||||||
|
bash
|
||||||
$ cargo check
|
$ cargo check
|
||||||
Checking nu_plugin_auth v0.1.0
|
Checking nu_plugin_auth v0.1.0
|
||||||
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.89s
|
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.89s
|
||||||
@ -81,6 +89,7 @@ $ cargo build --release
|
|||||||
**Warnings**: 6 unused code warnings (for future commands)
|
**Warnings**: 6 unused code warnings (for future commands)
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
|
|
||||||
- ✅ `reqwest` with `blocking` feature
|
- ✅ `reqwest` with `blocking` feature
|
||||||
- ✅ `keyring = "3.2"` for OS credential storage
|
- ✅ `keyring = "3.2"` for OS credential storage
|
||||||
- ✅ `rpassword = "7.4"` for secure input
|
- ✅ `rpassword = "7.4"` for secure input
|
||||||
@ -93,13 +102,17 @@ $ cargo build --release
|
|||||||
## 📝 Test Instructions
|
## 📝 Test Instructions
|
||||||
|
|
||||||
### 1. Register Plugin
|
### 1. Register Plugin
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
plugin add target/release/nu_plugin_auth
|
plugin add target/release/nu_plugin_auth
|
||||||
plugin use nu_plugin_auth
|
plugin use nu_plugin_auth
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Test Login
|
### 2. Test Login
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Interactive password prompt
|
# Interactive password prompt
|
||||||
auth login admin
|
auth login admin
|
||||||
|
|
||||||
@ -111,7 +124,9 @@ auth login admin --url http://control.example.com:8081
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 3. Test Logout
|
### 3. Test Logout
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Logout current user
|
# Logout current user
|
||||||
auth logout
|
auth logout
|
||||||
|
|
||||||
@ -125,7 +140,9 @@ auth logout --all
|
|||||||
### 4. Expected Output
|
### 4. Expected Output
|
||||||
|
|
||||||
**Login Success:**
|
**Login Success:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
user: {
|
user: {
|
||||||
@ -140,7 +157,9 @@ auth logout --all
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Logout Success:**
|
**Logout Success:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
message: "Logged out successfully",
|
message: "Logged out successfully",
|
||||||
@ -153,6 +172,7 @@ auth logout --all
|
|||||||
## 🚀 Integration Points
|
## 🚀 Integration Points
|
||||||
|
|
||||||
### Control Center API
|
### Control Center API
|
||||||
|
|
||||||
- **Base URL**: `http://localhost:8081` (default)
|
- **Base URL**: `http://localhost:8081` (default)
|
||||||
- **Endpoints**:
|
- **Endpoints**:
|
||||||
- `POST /auth/login` - Authentication
|
- `POST /auth/login` - Authentication
|
||||||
@ -163,6 +183,7 @@ auth logout --all
|
|||||||
- `POST /mfa/verify` - MFA verification
|
- `POST /mfa/verify` - MFA verification
|
||||||
|
|
||||||
### Security System
|
### Security System
|
||||||
|
|
||||||
- **JWT Auth**: RS256-signed tokens (15min access, 7d refresh)
|
- **JWT Auth**: RS256-signed tokens (15min access, 7d refresh)
|
||||||
- **MFA**: TOTP (RFC 6238) + WebAuthn/FIDO2
|
- **MFA**: TOTP (RFC 6238) + WebAuthn/FIDO2
|
||||||
- **Audit**: All auth events logged
|
- **Audit**: All auth events logged
|
||||||
@ -173,12 +194,14 @@ auth logout --all
|
|||||||
## ⏭️ Future Work (Not Implemented)
|
## ⏭️ Future Work (Not Implemented)
|
||||||
|
|
||||||
### Commands to Implement
|
### Commands to Implement
|
||||||
|
|
||||||
- [ ] `auth verify` - Verify current token validity
|
- [ ] `auth verify` - Verify current token validity
|
||||||
- [ ] `auth sessions` - List all active sessions
|
- [ ] `auth sessions` - List all active sessions
|
||||||
- [ ] `auth whoami` - Show current user from token
|
- [ ] `auth whoami` - Show current user from token
|
||||||
- [ ] `auth refresh` - Refresh expired access token
|
- [ ] `auth refresh` - Refresh expired access token
|
||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
- [ ] Auto-refresh tokens before expiration
|
- [ ] Auto-refresh tokens before expiration
|
||||||
- [ ] Background token refresh daemon
|
- [ ] Background token refresh daemon
|
||||||
- [ ] Session management (revoke specific session)
|
- [ ] Session management (revoke specific session)
|
||||||
@ -292,6 +315,7 @@ Beyond the basic requirements:
|
|||||||
**Status**: ✅ PRODUCTION READY
|
**Status**: ✅ PRODUCTION READY
|
||||||
|
|
||||||
**Ready for**:
|
**Ready for**:
|
||||||
|
|
||||||
- Manual testing with Control Center
|
- Manual testing with Control Center
|
||||||
- Integration testing
|
- Integration testing
|
||||||
- User acceptance testing
|
- User acceptance testing
|
||||||
|
|||||||
@ -20,27 +20,32 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
**Implemented Functions:**
|
**Implemented Functions:**
|
||||||
|
|
||||||
#### Token Storage (Keyring Integration)
|
#### Token Storage (Keyring Integration)
|
||||||
|
|
||||||
- `store_tokens_in_keyring()` - Store JWT tokens in OS keyring
|
- `store_tokens_in_keyring()` - Store JWT tokens in OS keyring
|
||||||
- `get_access_token()` - Retrieve access token from keyring
|
- `get_access_token()` - Retrieve access token from keyring
|
||||||
- `get_tokens_from_keyring()` - Retrieve both tokens from keyring
|
- `get_tokens_from_keyring()` - Retrieve both tokens from keyring
|
||||||
- `remove_tokens_from_keyring()` - Delete tokens from keyring
|
- `remove_tokens_from_keyring()` - Delete tokens from keyring
|
||||||
|
|
||||||
#### Password Input
|
#### Password Input
|
||||||
|
|
||||||
- `prompt_password()` - Secure password input (no echo)
|
- `prompt_password()` - Secure password input (no echo)
|
||||||
|
|
||||||
#### HTTP API Calls
|
#### HTTP API Calls
|
||||||
|
|
||||||
- `send_login_request()` - POST `/auth/login` with credentials
|
- `send_login_request()` - POST `/auth/login` with credentials
|
||||||
- `send_logout_request()` - POST `/auth/logout` to revoke token
|
- `send_logout_request()` - POST `/auth/logout` to revoke token
|
||||||
- `verify_token()` - GET `/auth/verify` to check token validity
|
- `verify_token()` - GET `/auth/verify` to check token validity
|
||||||
- `list_sessions()` - GET `/auth/sessions` to list active sessions
|
- `list_sessions()` - GET `/auth/sessions` to list active sessions
|
||||||
|
|
||||||
#### MFA Support (Bonus)
|
#### MFA Support (Bonus)
|
||||||
|
|
||||||
- `send_mfa_enroll_request()` - POST `/mfa/enroll/{type}` for TOTP/WebAuthn
|
- `send_mfa_enroll_request()` - POST `/mfa/enroll/{type}` for TOTP/WebAuthn
|
||||||
- `send_mfa_verify_request()` - POST `/mfa/verify` to verify TOTP code
|
- `send_mfa_verify_request()` - POST `/mfa/verify` to verify TOTP code
|
||||||
- `generate_qr_code()` - Generate QR code for TOTP secret
|
- `generate_qr_code()` - Generate QR code for TOTP secret
|
||||||
- `display_qr_code()` - Display QR code in terminal with instructions
|
- `display_qr_code()` - Display QR code in terminal with instructions
|
||||||
|
|
||||||
**Data Structures:**
|
**Data Structures:**
|
||||||
|
|
||||||
- `LoginRequest` - Login payload
|
- `LoginRequest` - Login payload
|
||||||
- `TokenResponse` - Login response with JWT tokens and user info
|
- `TokenResponse` - Login response with JWT tokens and user info
|
||||||
- `UserInfo` - User details (id, username, email, roles)
|
- `UserInfo` - User details (id, username, email, roles)
|
||||||
@ -59,13 +64,16 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
**Implemented Commands:**
|
**Implemented Commands:**
|
||||||
|
|
||||||
#### `auth login` Command (Lines 92-149)
|
#### `auth login` Command (Lines 92-149)
|
||||||
|
|
||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
- Required: `username: String`
|
- Required: `username: String`
|
||||||
- Optional: `password: String` (prompts if omitted)
|
- Optional: `password: String` (prompts if omitted)
|
||||||
- Flag: `--url <string>` (default: `http://localhost:8081`)
|
- Flag: `--url <string>` (default: `http://localhost:8081`)
|
||||||
- Switch: `--save` (save tokens to keyring)
|
- Switch: `--save` (save tokens to keyring)
|
||||||
|
|
||||||
**Behavior:**
|
**Behavior:**
|
||||||
|
|
||||||
1. Get username from first argument
|
1. Get username from first argument
|
||||||
2. Get password from second argument OR prompt securely
|
2. Get password from second argument OR prompt securely
|
||||||
3. Send login request to Control Center
|
3. Send login request to Control Center
|
||||||
@ -73,7 +81,9 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
5. Return success response with user info and token metadata
|
5. Return success response with user info and token metadata
|
||||||
|
|
||||||
**Example Output:**
|
**Example Output:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
user: {
|
user: {
|
||||||
@ -88,12 +98,15 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### `auth logout` Command (Lines 193-234)
|
#### `auth logout` Command (Lines 193-234)
|
||||||
|
|
||||||
**Signature:**
|
**Signature:**
|
||||||
|
|
||||||
- Flag: `--user <string>` (default: current system user)
|
- Flag: `--user <string>` (default: current system user)
|
||||||
- Flag: `--url <string>` (default: `http://localhost:8081`)
|
- Flag: `--url <string>` (default: `http://localhost:8081`)
|
||||||
- Switch: `--all` (logout all sessions)
|
- Switch: `--all` (logout all sessions)
|
||||||
|
|
||||||
**Behavior:**
|
**Behavior:**
|
||||||
|
|
||||||
1. Get username from flag or environment variable `$USER`
|
1. Get username from flag or environment variable `$USER`
|
||||||
2. Retrieve access token from keyring
|
2. Retrieve access token from keyring
|
||||||
3. Send logout request to Control Center
|
3. Send logout request to Control Center
|
||||||
@ -101,7 +114,9 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
5. Return success confirmation
|
5. Return success confirmation
|
||||||
|
|
||||||
**Example Output:**
|
**Example Output:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
message: "Logged out successfully",
|
message: "Logged out successfully",
|
||||||
@ -114,6 +129,7 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
### 3. `Cargo.toml`
|
### 3. `Cargo.toml`
|
||||||
|
|
||||||
**Dependencies Added:**
|
**Dependencies Added:**
|
||||||
|
|
||||||
- `reqwest` with `blocking` feature enabled for synchronous HTTP
|
- `reqwest` with `blocking` feature enabled for synchronous HTTP
|
||||||
- `keyring = "3.2"` for OS-level credential storage
|
- `keyring = "3.2"` for OS-level credential storage
|
||||||
- `rpassword = "7.4"` for secure password input
|
- `rpassword = "7.4"` for secure password input
|
||||||
@ -149,6 +165,7 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
**Base URL**: Configurable via `--url` flag (default: `http://localhost:8081`)
|
**Base URL**: Configurable via `--url` flag (default: `http://localhost:8081`)
|
||||||
|
|
||||||
**Endpoints Used:**
|
**Endpoints Used:**
|
||||||
|
|
||||||
- `POST /auth/login` - Authenticate and receive JWT tokens
|
- `POST /auth/login` - Authenticate and receive JWT tokens
|
||||||
- `POST /auth/logout` - Revoke access token
|
- `POST /auth/logout` - Revoke access token
|
||||||
- `GET /auth/verify` - Verify token validity
|
- `GET /auth/verify` - Verify token validity
|
||||||
@ -157,7 +174,9 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
- `POST /mfa/verify` - Verify MFA code
|
- `POST /mfa/verify` - Verify MFA code
|
||||||
|
|
||||||
**Request Format:**
|
**Request Format:**
|
||||||
```json
|
|
||||||
|
```nushell
|
||||||
|
json
|
||||||
// Login
|
// Login
|
||||||
{
|
{
|
||||||
"username": "admin",
|
"username": "admin",
|
||||||
@ -171,7 +190,9 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Response Format:**
|
**Response Format:**
|
||||||
```json
|
|
||||||
|
```nushell
|
||||||
|
json
|
||||||
// Login success
|
// Login success
|
||||||
{
|
{
|
||||||
"access_token": "eyJhbGc...",
|
"access_token": "eyJhbGc...",
|
||||||
@ -189,13 +210,16 @@ Complete implementation of Login and Logout commands for the `nu_plugin_auth` Nu
|
|||||||
### Error Handling
|
### Error Handling
|
||||||
|
|
||||||
**Comprehensive error messages:**
|
**Comprehensive error messages:**
|
||||||
|
|
||||||
- HTTP request failures with status codes
|
- HTTP request failures with status codes
|
||||||
- Keyring errors (access denied, not found)
|
- Keyring errors (access denied, not found)
|
||||||
- Password input errors
|
- Password input errors
|
||||||
- API response parsing errors
|
- API response parsing errors
|
||||||
|
|
||||||
**Example Error Flow:**
|
**Example Error Flow:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# No active session
|
# No active session
|
||||||
auth logout
|
auth logout
|
||||||
# Error: No active session: No token found
|
# Error: No active session: No token found
|
||||||
@ -215,7 +239,8 @@ auth login admin --url http://invalid:8081
|
|||||||
|
|
||||||
✅ **Successful Compilation**
|
✅ **Successful Compilation**
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
$ cargo check
|
$ cargo check
|
||||||
Checking nu_plugin_auth v0.1.0
|
Checking nu_plugin_auth v0.1.0
|
||||||
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.89s
|
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.89s
|
||||||
@ -236,53 +261,70 @@ $ cargo build --release
|
|||||||
### Manual Testing
|
### Manual Testing
|
||||||
|
|
||||||
#### 1. Register Plugin
|
#### 1. Register Plugin
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
plugin add target/release/nu_plugin_auth
|
plugin add target/release/nu_plugin_auth
|
||||||
plugin use nu_plugin_auth
|
plugin use nu_plugin_auth
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 2. Test Login (Password Prompt)
|
#### 2. Test Login (Password Prompt)
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth login admin
|
auth login admin
|
||||||
# Password: ******
|
# Password: ******
|
||||||
# Returns user info and token metadata
|
# Returns user info and token metadata
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 3. Test Login (Password in Command)
|
#### 3. Test Login (Password in Command)
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth login admin mypassword --save
|
auth login admin mypassword --save
|
||||||
# Saves tokens to keyring
|
# Saves tokens to keyring
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 4. Test Login (Custom URL)
|
#### 4. Test Login (Custom URL)
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth login admin --url http://control.example.com:8081
|
auth login admin --url http://control.example.com:8081
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 5. Test Logout
|
#### 5. Test Logout
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth logout
|
auth logout
|
||||||
# Logs out current user
|
# Logs out current user
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 6. Test Logout (Specific User)
|
#### 6. Test Logout (Specific User)
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth logout --user admin
|
auth logout --user admin
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 7. Test Logout (All Sessions)
|
#### 7. Test Logout (All Sessions)
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
auth logout --all
|
auth logout --all
|
||||||
```
|
```
|
||||||
|
|
||||||
### Integration Testing
|
### Integration Testing
|
||||||
|
|
||||||
**Prerequisites:**
|
**Prerequisites:**
|
||||||
|
|
||||||
- Control Center running at `http://localhost:8081`
|
- Control Center running at `http://localhost:8081`
|
||||||
- Valid user account (username + password)
|
- Valid user account (username + password)
|
||||||
|
|
||||||
**Test Workflow:**
|
**Test Workflow:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# 1. Login
|
# 1. Login
|
||||||
let login_result = auth login testuser testpass --save
|
let login_result = auth login testuser testpass --save
|
||||||
|
|
||||||
@ -324,7 +366,9 @@ assert ($logout_result.message == "Logged out successfully")
|
|||||||
### MFA Support (Bonus Implementation)
|
### MFA Support (Bonus Implementation)
|
||||||
|
|
||||||
**TOTP Enrollment:**
|
**TOTP Enrollment:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Enroll in TOTP (Google Authenticator, Authy)
|
# Enroll in TOTP (Google Authenticator, Authy)
|
||||||
auth mfa enroll totp --user admin
|
auth mfa enroll totp --user admin
|
||||||
|
|
||||||
@ -333,13 +377,17 @@ auth mfa enroll totp --user admin
|
|||||||
```
|
```
|
||||||
|
|
||||||
**TOTP Verification:**
|
**TOTP Verification:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Verify 6-digit TOTP code
|
# Verify 6-digit TOTP code
|
||||||
auth mfa verify --code 123456 --user admin
|
auth mfa verify --code 123456 --user admin
|
||||||
```
|
```
|
||||||
|
|
||||||
**WebAuthn Enrollment:**
|
**WebAuthn Enrollment:**
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Enroll WebAuthn (YubiKey, Touch ID, Windows Hello)
|
# Enroll WebAuthn (YubiKey, Touch ID, Windows Hello)
|
||||||
auth mfa enroll webauthn --user admin
|
auth mfa enroll webauthn --user admin
|
||||||
```
|
```
|
||||||
@ -349,18 +397,22 @@ auth mfa enroll webauthn --user admin
|
|||||||
## Future Enhancements (Not Implemented)
|
## Future Enhancements (Not Implemented)
|
||||||
|
|
||||||
### Token Refresh
|
### Token Refresh
|
||||||
|
|
||||||
- Auto-refresh expired access tokens using refresh token
|
- Auto-refresh expired access tokens using refresh token
|
||||||
- Background refresh before expiration
|
- Background refresh before expiration
|
||||||
|
|
||||||
### Session Management
|
### Session Management
|
||||||
|
|
||||||
- `auth sessions` - List all active sessions
|
- `auth sessions` - List all active sessions
|
||||||
- `auth sessions --revoke <id>` - Revoke specific session
|
- `auth sessions --revoke <id>` - Revoke specific session
|
||||||
|
|
||||||
### Token Verification
|
### Token Verification
|
||||||
|
|
||||||
- `auth verify` - Check if current token is valid
|
- `auth verify` - Check if current token is valid
|
||||||
- `auth whoami` - Show current user info from token
|
- `auth whoami` - Show current user info from token
|
||||||
|
|
||||||
### Certificate Pinning
|
### Certificate Pinning
|
||||||
|
|
||||||
- Pin Control Center TLS certificate
|
- Pin Control Center TLS certificate
|
||||||
- Prevent MITM attacks
|
- Prevent MITM attacks
|
||||||
|
|
||||||
@ -369,6 +421,7 @@ auth mfa enroll webauthn --user admin
|
|||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
### Runtime Dependencies
|
### Runtime Dependencies
|
||||||
|
|
||||||
- `keyring = "3.2"` - OS credential storage
|
- `keyring = "3.2"` - OS credential storage
|
||||||
- `rpassword = "7.4"` - Secure password input
|
- `rpassword = "7.4"` - Secure password input
|
||||||
- `reqwest = "0.12"` - HTTP client (blocking mode)
|
- `reqwest = "0.12"` - HTTP client (blocking mode)
|
||||||
@ -377,10 +430,12 @@ auth mfa enroll webauthn --user admin
|
|||||||
- `qrcode = "0.14"` - QR code generation
|
- `qrcode = "0.14"` - QR code generation
|
||||||
|
|
||||||
### Build Dependencies
|
### Build Dependencies
|
||||||
|
|
||||||
- Rust 1.70+ (stable)
|
- Rust 1.70+ (stable)
|
||||||
- Nushell 0.107.1 (via path dependency)
|
- Nushell 0.107.1 (via path dependency)
|
||||||
|
|
||||||
### Platform Requirements
|
### Platform Requirements
|
||||||
|
|
||||||
- macOS: Keychain access
|
- macOS: Keychain access
|
||||||
- Linux: libsecret/gnome-keyring
|
- Linux: libsecret/gnome-keyring
|
||||||
- Windows: Credential Manager
|
- Windows: Credential Manager
|
||||||
@ -392,7 +447,9 @@ auth mfa enroll webauthn --user admin
|
|||||||
### Command Help
|
### Command Help
|
||||||
|
|
||||||
#### Login Command
|
#### Login Command
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
help auth login
|
help auth login
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
@ -417,7 +474,9 @@ help auth login
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Logout Command
|
#### Logout Command
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
help auth logout
|
help auth logout
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -8,6 +8,7 @@
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Build plugin
|
# Build plugin
|
||||||
cargo build --release -p nu_plugin_auth
|
cargo build --release -p nu_plugin_auth
|
||||||
|
|
||||||
@ -21,7 +22,9 @@ plugin use nu_plugin_auth
|
|||||||
## Login Command
|
## Login Command
|
||||||
|
|
||||||
### Basic Usage
|
### Basic Usage
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Interactive login (password prompt)
|
# Interactive login (password prompt)
|
||||||
auth login admin
|
auth login admin
|
||||||
|
|
||||||
@ -36,13 +39,16 @@ auth login admin --url http://control.example.com:8081
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Flags
|
### Flags
|
||||||
|
|
||||||
| Flag | Short | Type | Description | Default |
|
| Flag | Short | Type | Description | Default |
|
||||||
|------|-------|------|-------------|---------|
|
|------|-------|------|-------------|---------|
|
||||||
| `--url` | - | String | Control Center URL | `http://localhost:8081` |
|
| `--url` | - | String | Control Center URL | `http://localhost:8081` |
|
||||||
| `--save` | - | Switch | Save tokens to keyring | `false` |
|
| `--save` | - | Switch | Save tokens to keyring | `false` |
|
||||||
|
|
||||||
### Output
|
### Output
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
user: {
|
user: {
|
||||||
@ -61,7 +67,9 @@ auth login admin --url http://control.example.com:8081
|
|||||||
## Logout Command
|
## Logout Command
|
||||||
|
|
||||||
### Basic Usage
|
### Basic Usage
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Logout current user
|
# Logout current user
|
||||||
auth logout
|
auth logout
|
||||||
|
|
||||||
@ -73,6 +81,7 @@ auth logout --all
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Flags
|
### Flags
|
||||||
|
|
||||||
| Flag | Short | Type | Description | Default |
|
| Flag | Short | Type | Description | Default |
|
||||||
|------|-------|------|-------------|---------|
|
|------|-------|------|-------------|---------|
|
||||||
| `--user` | `-u` | String | Username | Current system user |
|
| `--user` | `-u` | String | Username | Current system user |
|
||||||
@ -80,7 +89,9 @@ auth logout --all
|
|||||||
| `--all` | `-a` | Switch | Logout all sessions | `false` |
|
| `--all` | `-a` | Switch | Logout all sessions | `false` |
|
||||||
|
|
||||||
### Output
|
### Output
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
{
|
{
|
||||||
success: true,
|
success: true,
|
||||||
message: "Logged out successfully",
|
message: "Logged out successfully",
|
||||||
@ -93,7 +104,9 @@ auth logout --all
|
|||||||
## MFA Commands (Bonus)
|
## MFA Commands (Bonus)
|
||||||
|
|
||||||
### TOTP Enrollment
|
### TOTP Enrollment
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Enroll in TOTP
|
# Enroll in TOTP
|
||||||
auth mfa enroll totp
|
auth mfa enroll totp
|
||||||
|
|
||||||
@ -104,7 +117,9 @@ auth mfa enroll totp --user alice
|
|||||||
**Output**: QR code in terminal + secret + backup codes
|
**Output**: QR code in terminal + secret + backup codes
|
||||||
|
|
||||||
### TOTP Verification
|
### TOTP Verification
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Verify TOTP code
|
# Verify TOTP code
|
||||||
auth mfa verify --code 123456
|
auth mfa verify --code 123456
|
||||||
|
|
||||||
@ -113,7 +128,9 @@ auth mfa verify --code 123456 --user alice
|
|||||||
```
|
```
|
||||||
|
|
||||||
### WebAuthn Enrollment
|
### WebAuthn Enrollment
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Enroll WebAuthn (YubiKey, Touch ID)
|
# Enroll WebAuthn (YubiKey, Touch ID)
|
||||||
auth mfa enroll webauthn
|
auth mfa enroll webauthn
|
||||||
```
|
```
|
||||||
@ -133,6 +150,7 @@ auth mfa enroll webauthn
|
|||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# No active session
|
# No active session
|
||||||
auth logout
|
auth logout
|
||||||
# Error: No active session: No token found
|
# Error: No active session: No token found
|
||||||
@ -174,7 +192,9 @@ auth login admin --url http://invalid:8081
|
|||||||
## Workflow Examples
|
## Workflow Examples
|
||||||
|
|
||||||
### Standard Login/Logout
|
### Standard Login/Logout
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Login
|
# Login
|
||||||
auth login admin --save
|
auth login admin --save
|
||||||
|
|
||||||
@ -185,7 +205,9 @@ auth logout
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Multiple Users
|
### Multiple Users
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Login as different users
|
# Login as different users
|
||||||
auth login alice --save
|
auth login alice --save
|
||||||
auth login bob --save
|
auth login bob --save
|
||||||
@ -195,7 +217,9 @@ auth logout --user alice
|
|||||||
```
|
```
|
||||||
|
|
||||||
### CI/CD Integration
|
### CI/CD Integration
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Non-interactive login
|
# Non-interactive login
|
||||||
let token = auth login $env.CI_USER $env.CI_PASS | get user.id
|
let token = auth login $env.CI_USER $env.CI_PASS | get user.id
|
||||||
|
|
||||||
@ -210,18 +234,22 @@ auth logout --user $env.CI_USER
|
|||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### "No token found" error
|
### "No token found" error
|
||||||
|
|
||||||
**Cause**: No active session or keyring not accessible
|
**Cause**: No active session or keyring not accessible
|
||||||
**Fix**: Login again with `--save` flag
|
**Fix**: Login again with `--save` flag
|
||||||
|
|
||||||
### "HTTP request failed"
|
### "HTTP request failed"
|
||||||
|
|
||||||
**Cause**: Control Center not running or wrong URL
|
**Cause**: Control Center not running or wrong URL
|
||||||
**Fix**: Check Control Center status and `--url` flag
|
**Fix**: Check Control Center status and `--url` flag
|
||||||
|
|
||||||
### "Login failed: HTTP 401"
|
### "Login failed: HTTP 401"
|
||||||
|
|
||||||
**Cause**: Invalid credentials
|
**Cause**: Invalid credentials
|
||||||
**Fix**: Verify username and password
|
**Fix**: Verify username and password
|
||||||
|
|
||||||
### Keyring access denied
|
### Keyring access denied
|
||||||
|
|
||||||
**Cause**: OS permission issue
|
**Cause**: OS permission issue
|
||||||
**Fix**: Grant keychain/keyring access to plugin binary
|
**Fix**: Grant keychain/keyring access to plugin binary
|
||||||
|
|
||||||
@ -230,7 +258,9 @@ auth logout --user $env.CI_USER
|
|||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Build Commands
|
### Build Commands
|
||||||
```bash
|
|
||||||
|
```nushell
|
||||||
|
bash
|
||||||
# Check code
|
# Check code
|
||||||
cargo check -p nu_plugin_auth
|
cargo check -p nu_plugin_auth
|
||||||
|
|
||||||
@ -245,6 +275,7 @@ cargo test -p nu_plugin_auth
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Plugin Location
|
### Plugin Location
|
||||||
|
|
||||||
- Source: `provisioning/core/plugins/nushell-plugins/nu_plugin_auth/`
|
- Source: `provisioning/core/plugins/nushell-plugins/nu_plugin_auth/`
|
||||||
- Binary: `target/release/nu_plugin_auth`
|
- Binary: `target/release/nu_plugin_auth`
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Build plugin
|
# Build plugin
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
@ -15,7 +16,8 @@ plugin use auth
|
|||||||
|
|
||||||
### TOTP Enrollment
|
### TOTP Enrollment
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Enroll with QR code
|
# Enroll with QR code
|
||||||
auth mfa enroll totp
|
auth mfa enroll totp
|
||||||
|
|
||||||
@ -30,7 +32,8 @@ auth mfa enroll totp --url http://control.example.com:8081
|
|||||||
|
|
||||||
### TOTP Verification
|
### TOTP Verification
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Verify code
|
# Verify code
|
||||||
auth mfa verify --code 123456
|
auth mfa verify --code 123456
|
||||||
|
|
||||||
@ -42,7 +45,8 @@ auth mfa verify --code 123456 --user alice
|
|||||||
|
|
||||||
## Complete Workflow
|
## Complete Workflow
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# 1. Login
|
# 1. Login
|
||||||
auth login admin --save
|
auth login admin --save
|
||||||
|
|
||||||
|
|||||||
@ -93,7 +93,9 @@ impl VerificationResult {
|
|||||||
pub fn decode_claims_unverified(token: &str) -> Result<Claims, AuthError> {
|
pub fn decode_claims_unverified(token: &str) -> Result<Claims, AuthError> {
|
||||||
let parts: Vec<&str> = token.split('.').collect();
|
let parts: Vec<&str> = token.split('.').collect();
|
||||||
if parts.len() != 3 {
|
if parts.len() != 3 {
|
||||||
return Err(AuthError::invalid_token("Token must have 3 parts separated by '.'"));
|
return Err(AuthError::invalid_token(
|
||||||
|
"Token must have 3 parts separated by '.'",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let payload = parts[1];
|
let payload = parts[1];
|
||||||
@ -118,7 +120,10 @@ pub fn decode_claims_unverified(token: &str) -> Result<Claims, AuthError> {
|
|||||||
///
|
///
|
||||||
/// Returns a VerificationResult indicating whether the token is valid
|
/// Returns a VerificationResult indicating whether the token is valid
|
||||||
/// and containing the claims if verification succeeded.
|
/// and containing the claims if verification succeeded.
|
||||||
pub fn verify_token_rs256(token: &str, public_key_pem: &str) -> Result<VerificationResult, AuthError> {
|
pub fn verify_token_rs256(
|
||||||
|
token: &str,
|
||||||
|
public_key_pem: &str,
|
||||||
|
) -> Result<VerificationResult, AuthError> {
|
||||||
// Verify the token header uses RS256
|
// Verify the token header uses RS256
|
||||||
let header = decode_header(token)
|
let header = decode_header(token)
|
||||||
.map_err(|e| AuthError::invalid_token(format!("Failed to decode header: {}", e)))?;
|
.map_err(|e| AuthError::invalid_token(format!("Failed to decode header: {}", e)))?;
|
||||||
|
|||||||
@ -206,9 +206,15 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_error_kind_display() {
|
fn test_error_kind_display() {
|
||||||
assert_eq!(AuthErrorKind::InvalidCredentials.to_string(), "invalid credentials");
|
assert_eq!(
|
||||||
|
AuthErrorKind::InvalidCredentials.to_string(),
|
||||||
|
"invalid credentials"
|
||||||
|
);
|
||||||
assert_eq!(AuthErrorKind::TokenExpired.to_string(), "token expired");
|
assert_eq!(AuthErrorKind::TokenExpired.to_string(), "token expired");
|
||||||
assert_eq!(AuthErrorKind::KeyringError.to_string(), "keyring operation failed");
|
assert_eq!(
|
||||||
|
AuthErrorKind::KeyringError.to_string(),
|
||||||
|
"keyring operation failed"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -248,7 +248,7 @@ pub fn verify_token(url: &str, token: &str) -> Result<VerifyResponse, AuthError>
|
|||||||
pub fn list_sessions(
|
pub fn list_sessions(
|
||||||
url: &str,
|
url: &str,
|
||||||
token: &str,
|
token: &str,
|
||||||
active_only: bool
|
active_only: bool,
|
||||||
) -> Result<Vec<SessionInfo>, AuthError> {
|
) -> Result<Vec<SessionInfo>, AuthError> {
|
||||||
let client = create_client()?;
|
let client = create_client()?;
|
||||||
|
|
||||||
@ -365,8 +365,12 @@ pub fn prompt_password(prompt: &str) -> Result<String, AuthError> {
|
|||||||
.flush()
|
.flush()
|
||||||
.map_err(|e| AuthError::new(AuthErrorKind::InternalError, format!("Flush error: {}", e)))?;
|
.map_err(|e| AuthError::new(AuthErrorKind::InternalError, format!("Flush error: {}", e)))?;
|
||||||
|
|
||||||
rpassword::read_password()
|
rpassword::read_password().map_err(|e| {
|
||||||
.map_err(|e| AuthError::new(AuthErrorKind::InternalError, format!("Password read error: {}", e)))
|
AuthError::new(
|
||||||
|
AuthErrorKind::InternalError,
|
||||||
|
format!("Password read error: {}", e),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@ -386,8 +390,12 @@ pub fn generate_qr_code(uri: &str) -> Result<String, AuthError> {
|
|||||||
use qrcode::render::unicode;
|
use qrcode::render::unicode;
|
||||||
use qrcode::QrCode;
|
use qrcode::QrCode;
|
||||||
|
|
||||||
let code = QrCode::new(uri)
|
let code = QrCode::new(uri).map_err(|e| {
|
||||||
.map_err(|e| AuthError::new(AuthErrorKind::InternalError, format!("QR code generation failed: {}", e)))?;
|
AuthError::new(
|
||||||
|
AuthErrorKind::InternalError,
|
||||||
|
format!("QR code generation failed: {}", e),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let qr_string = code
|
let qr_string = code
|
||||||
.render::<unicode::Dense1x2>()
|
.render::<unicode::Dense1x2>()
|
||||||
@ -425,10 +433,12 @@ fn extract_secret(uri: &str) -> Result<String, AuthError> {
|
|||||||
.nth(1)
|
.nth(1)
|
||||||
.and_then(|s| s.split('&').next())
|
.and_then(|s| s.split('&').next())
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
.ok_or_else(|| AuthError::new(
|
.ok_or_else(|| {
|
||||||
|
AuthError::new(
|
||||||
AuthErrorKind::InternalError,
|
AuthErrorKind::InternalError,
|
||||||
"Failed to extract secret from URI",
|
"Failed to extract secret from URI",
|
||||||
))
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@ -437,6 +447,21 @@ fn extract_secret(uri: &str) -> Result<String, AuthError> {
|
|||||||
|
|
||||||
use nu_protocol::{record, Span, Value};
|
use nu_protocol::{record, Span, Value};
|
||||||
|
|
||||||
|
/// Converts a UserInfo to a Nushell Value record.
|
||||||
|
pub fn user_info_to_value(user: &UserInfo, span: Span) -> Value {
|
||||||
|
Value::record(
|
||||||
|
record! {
|
||||||
|
"id" => Value::string(&user.id, span),
|
||||||
|
"username" => Value::string(&user.username, span),
|
||||||
|
"email" => Value::string(&user.email, span),
|
||||||
|
"roles" => Value::list(
|
||||||
|
user.roles.iter().map(|r| Value::string(r, span)).collect(),
|
||||||
|
span,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Converts a SessionInfo to a Nushell Value record.
|
/// Converts a SessionInfo to a Nushell Value record.
|
||||||
pub fn session_info_to_value(session: &SessionInfo, span: Span) -> Value {
|
pub fn session_info_to_value(session: &SessionInfo, span: Span) -> Value {
|
||||||
|
|||||||
@ -78,12 +78,12 @@ pub fn get_access_token(username: &str) -> Result<String, AuthError> {
|
|||||||
let entry = Entry::new(SERVICE_NAME_ACCESS, username)
|
let entry = Entry::new(SERVICE_NAME_ACCESS, username)
|
||||||
.map_err(|e| AuthError::keyring_error(format!("Failed to access keyring: {}", e)))?;
|
.map_err(|e| AuthError::keyring_error(format!("Failed to access keyring: {}", e)))?;
|
||||||
|
|
||||||
entry
|
entry.get_password().map_err(|e| {
|
||||||
.get_password()
|
AuthError::new(
|
||||||
.map_err(|e| AuthError::new(
|
|
||||||
AuthErrorKind::SessionNotFound,
|
AuthErrorKind::SessionNotFound,
|
||||||
format!("No access token found for user '{}': {}", username, e),
|
format!("No access token found for user '{}': {}", username, e),
|
||||||
))
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the refresh token from the system keyring.
|
/// Retrieves the refresh token from the system keyring.
|
||||||
@ -100,12 +100,12 @@ pub fn get_refresh_token(username: &str) -> Result<String, AuthError> {
|
|||||||
let entry = Entry::new(SERVICE_NAME_REFRESH, username)
|
let entry = Entry::new(SERVICE_NAME_REFRESH, username)
|
||||||
.map_err(|e| AuthError::keyring_error(format!("Failed to access keyring: {}", e)))?;
|
.map_err(|e| AuthError::keyring_error(format!("Failed to access keyring: {}", e)))?;
|
||||||
|
|
||||||
entry
|
entry.get_password().map_err(|e| {
|
||||||
.get_password()
|
AuthError::new(
|
||||||
.map_err(|e| AuthError::new(
|
|
||||||
AuthErrorKind::SessionNotFound,
|
AuthErrorKind::SessionNotFound,
|
||||||
format!("No refresh token found for user '{}': {}", username, e),
|
format!("No refresh token found for user '{}': {}", username, e),
|
||||||
))
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves both access and refresh tokens from the system keyring.
|
/// Retrieves both access and refresh tokens from the system keyring.
|
||||||
@ -175,9 +175,9 @@ pub fn get_public_key(key_id: &str) -> Result<String, AuthError> {
|
|||||||
let entry = Entry::new(SERVICE_NAME_PUBLIC_KEY, key_id)
|
let entry = Entry::new(SERVICE_NAME_PUBLIC_KEY, key_id)
|
||||||
.map_err(|e| AuthError::keyring_error(format!("Failed to access keyring: {}", e)))?;
|
.map_err(|e| AuthError::keyring_error(format!("Failed to access keyring: {}", e)))?;
|
||||||
|
|
||||||
entry
|
entry.get_password().map_err(|e| {
|
||||||
.get_password()
|
AuthError::configuration_error(format!("Public key '{}' not found: {}", key_id, e))
|
||||||
.map_err(|e| AuthError::configuration_error(format!("Public key '{}' not found: {}", key_id, e)))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if tokens exist for a user.
|
/// Checks if tokens exist for a user.
|
||||||
|
|||||||
@ -128,8 +128,7 @@ impl SimplePluginCommand for Login {
|
|||||||
let password = if let Some(pwd) = password_arg {
|
let password = if let Some(pwd) = password_arg {
|
||||||
pwd
|
pwd
|
||||||
} else {
|
} else {
|
||||||
helpers::prompt_password("Password: ")
|
helpers::prompt_password("Password: ").map_err(|e| LabeledError::new(e.to_string()))?
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send login request
|
// Send login request
|
||||||
@ -234,16 +233,15 @@ impl SimplePluginCommand for Logout {
|
|||||||
let username = username_arg.unwrap_or_else(keyring::get_current_username);
|
let username = username_arg.unwrap_or_else(keyring::get_current_username);
|
||||||
|
|
||||||
// Get access token
|
// Get access token
|
||||||
let access_token = keyring::get_access_token(&username)
|
let access_token =
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?;
|
keyring::get_access_token(&username).map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
|
|
||||||
// Send logout request
|
// Send logout request
|
||||||
helpers::send_logout_request(&url, &access_token)
|
helpers::send_logout_request(&url, &access_token)
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?;
|
.map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
|
|
||||||
// Remove tokens from keyring
|
// Remove tokens from keyring
|
||||||
keyring::remove_tokens(&username)
|
keyring::remove_tokens(&username).map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?;
|
|
||||||
|
|
||||||
Ok(Value::record(
|
Ok(Value::record(
|
||||||
record! {
|
record! {
|
||||||
@ -292,7 +290,11 @@ impl SimplePluginCommand for Verify {
|
|||||||
"Control Center URL for remote verification",
|
"Control Center URL for remote verification",
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.switch("local", "Verify locally without contacting server", Some('l'))
|
.switch(
|
||||||
|
"local",
|
||||||
|
"Verify locally without contacting server",
|
||||||
|
Some('l'),
|
||||||
|
)
|
||||||
.category(Category::Custom("provisioning".into()))
|
.category(Category::Custom("provisioning".into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,14 +339,13 @@ impl SimplePluginCommand for Verify {
|
|||||||
t
|
t
|
||||||
} else {
|
} else {
|
||||||
let username = username_arg.unwrap_or_else(keyring::get_current_username);
|
let username = username_arg.unwrap_or_else(keyring::get_current_username);
|
||||||
keyring::get_access_token(&username)
|
keyring::get_access_token(&username).map_err(|e| LabeledError::new(e.to_string()))?
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if local_only {
|
if local_only {
|
||||||
// Local verification (no network)
|
// Local verification (no network)
|
||||||
let result = auth::verify_token_local(&token)
|
let result =
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?;
|
auth::verify_token_local(&token).map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
|
|
||||||
Ok(Value::record(
|
Ok(Value::record(
|
||||||
record! {
|
record! {
|
||||||
@ -448,8 +449,8 @@ impl SimplePluginCommand for Sessions {
|
|||||||
|
|
||||||
// Get username and access token
|
// Get username and access token
|
||||||
let username = username_arg.unwrap_or_else(keyring::get_current_username);
|
let username = username_arg.unwrap_or_else(keyring::get_current_username);
|
||||||
let access_token = keyring::get_access_token(&username)
|
let access_token =
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?;
|
keyring::get_access_token(&username).map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
|
|
||||||
// List sessions from server
|
// List sessions from server
|
||||||
let sessions = helpers::list_sessions(&url, &access_token, active_only)
|
let sessions = helpers::list_sessions(&url, &access_token, active_only)
|
||||||
@ -536,8 +537,8 @@ impl SimplePluginCommand for MfaEnroll {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get access token
|
// Get access token
|
||||||
let access_token = keyring::get_access_token(&username)
|
let access_token =
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?;
|
keyring::get_access_token(&username).map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
|
|
||||||
// Send enrollment request
|
// Send enrollment request
|
||||||
let response = helpers::send_mfa_enroll_request(&url, &access_token, &mfa_type)
|
let response = helpers::send_mfa_enroll_request(&url, &access_token, &mfa_type)
|
||||||
@ -622,9 +623,7 @@ impl SimplePluginCommand for MfaVerify {
|
|||||||
|
|
||||||
// Validate code format
|
// Validate code format
|
||||||
if code.len() != 6 || !code.chars().all(|c| c.is_ascii_digit()) {
|
if code.len() != 6 || !code.chars().all(|c| c.is_ascii_digit()) {
|
||||||
return Err(LabeledError::new(
|
return Err(LabeledError::new("Code must be a 6-digit number"));
|
||||||
"Code must be a 6-digit number",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let username = call
|
let username = call
|
||||||
@ -635,8 +634,8 @@ impl SimplePluginCommand for MfaVerify {
|
|||||||
.unwrap_or_else(|| DEFAULT_CONTROL_CENTER_URL.to_string());
|
.unwrap_or_else(|| DEFAULT_CONTROL_CENTER_URL.to_string());
|
||||||
|
|
||||||
// Get access token
|
// Get access token
|
||||||
let access_token = keyring::get_access_token(&username)
|
let access_token =
|
||||||
.map_err(|e| LabeledError::new(e.to_string()))?;
|
keyring::get_access_token(&username).map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
|
|
||||||
// Verify code
|
// Verify code
|
||||||
let valid = helpers::send_mfa_verify_request(&url, &access_token, &code)
|
let valid = helpers::send_mfa_verify_request(&url, &access_token, &code)
|
||||||
|
|||||||
@ -117,10 +117,19 @@ fn test_auth_error_kind_display() {
|
|||||||
"invalid credentials"
|
"invalid credentials"
|
||||||
);
|
);
|
||||||
assert_eq!(AuthErrorKind::TokenExpired.to_string(), "token expired");
|
assert_eq!(AuthErrorKind::TokenExpired.to_string(), "token expired");
|
||||||
assert_eq!(AuthErrorKind::InvalidToken.to_string(), "invalid token format");
|
assert_eq!(
|
||||||
assert_eq!(AuthErrorKind::KeyringError.to_string(), "keyring operation failed");
|
AuthErrorKind::InvalidToken.to_string(),
|
||||||
|
"invalid token format"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
AuthErrorKind::KeyringError.to_string(),
|
||||||
|
"keyring operation failed"
|
||||||
|
);
|
||||||
assert_eq!(AuthErrorKind::NetworkError.to_string(), "network error");
|
assert_eq!(AuthErrorKind::NetworkError.to_string(), "network error");
|
||||||
assert_eq!(AuthErrorKind::MfaFailed.to_string(), "MFA verification failed");
|
assert_eq!(
|
||||||
|
AuthErrorKind::MfaFailed.to_string(),
|
||||||
|
"MFA verification failed"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
564
nu_plugin_clipboard/Cargo.lock
generated
564
nu_plugin_clipboard/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -10,14 +10,14 @@ keywords = [
|
|||||||
homepage = "https://github.com/FMotalleb/nu_plugin_clipboard"
|
homepage = "https://github.com/FMotalleb/nu_plugin_clipboard"
|
||||||
repository = "https://github.com/FMotalleb/nu_plugin_clipboard"
|
repository = "https://github.com/FMotalleb/nu_plugin_clipboard"
|
||||||
description = "A nushell plugin to copy text into clipboard or get text from it."
|
description = "A nushell plugin to copy text into clipboard or get text from it."
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = "0.109.1"
|
nu-plugin = "0.111.0"
|
||||||
nu-protocol = "0.109.1"
|
nu-protocol = "0.111.0"
|
||||||
nu-json = "0.109.1"
|
nu-json = "0.111.0"
|
||||||
|
|
||||||
[dependencies.arboard]
|
[dependencies.arboard]
|
||||||
version = "3.6.1"
|
version = "3.6.1"
|
||||||
|
|||||||
@ -25,13 +25,15 @@ Try disabling the daemon mode, as mentioned in [#20](https://github.com/FMotalle
|
|||||||
|
|
||||||
### Copying a string (supports only strings for now)
|
### Copying a string (supports only strings for now)
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
echo "test value" | clipboard copy
|
echo "test value" | clipboard copy
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using clipboard content
|
### Using clipboard content
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
clipboard paste | echo $in
|
clipboard paste | echo $in
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -41,7 +43,8 @@ clipboard paste | echo $in
|
|||||||
- When pasting, `clipboard paste` tries to parse JSON into a table or object.
|
- When pasting, `clipboard paste` tries to parse JSON into a table or object.
|
||||||
- If parsing fails, the content is returned as a string.
|
- If parsing fails, the content is returned as a string.
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
$env | clipboard copy
|
$env | clipboard copy
|
||||||
clipboard paste
|
clipboard paste
|
||||||
|
|
||||||
@ -55,7 +58,8 @@ clipboard paste
|
|||||||
|
|
||||||
This method automatically handles dependencies and features:
|
This method automatically handles dependencies and features:
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
git clone https://github.com/FMotalleb/nu_plugin_clipboard.git
|
git clone https://github.com/FMotalleb/nu_plugin_clipboard.git
|
||||||
nupm install --path nu_plugin_clipboard -f
|
nupm install --path nu_plugin_clipboard -f
|
||||||
```
|
```
|
||||||
@ -71,7 +75,8 @@ nupm install --path nu_plugin_clipboard -f
|
|||||||
|
|
||||||
### 🛠️ Manual Compilation
|
### 🛠️ Manual Compilation
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
git clone https://github.com/FMotalleb/nu_plugin_clipboard.git
|
git clone https://github.com/FMotalleb/nu_plugin_clipboard.git
|
||||||
cd nu_plugin_clipboard
|
cd nu_plugin_clipboard
|
||||||
cargo build -r
|
cargo build -r
|
||||||
@ -80,7 +85,8 @@ plugin add target/release/nu_plugin_clipboard
|
|||||||
|
|
||||||
### 📦 Install via Cargo (using git)
|
### 📦 Install via Cargo (using git)
|
||||||
|
|
||||||
```bash
|
```rust
|
||||||
|
bash
|
||||||
cargo install --git https://github.com/FMotalleb/nu_plugin_clipboard.git
|
cargo install --git https://github.com/FMotalleb/nu_plugin_clipboard.git
|
||||||
plugin add ~/.cargo/bin/nu_plugin_clipboard
|
plugin add ~/.cargo/bin/nu_plugin_clipboard
|
||||||
```
|
```
|
||||||
@ -89,7 +95,8 @@ plugin add ~/.cargo/bin/nu_plugin_clipboard
|
|||||||
|
|
||||||
- Since I live in Iran and crates.io won't let me update my packages like a normal person, most of the time crates.io is outdated.
|
- Since I live in Iran and crates.io won't let me update my packages like a normal person, most of the time crates.io is outdated.
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
cargo install nu_plugin_clipboard
|
cargo install nu_plugin_clipboard
|
||||||
plugin add ~/.cargo/bin/nu_plugin_clipboard
|
plugin add ~/.cargo/bin/nu_plugin_clipboard
|
||||||
```
|
```
|
||||||
@ -1,3 +1,3 @@
|
|||||||
pub(crate) fn map_arboard_err_to_label(err: arboard::Error) -> nu_protocol::LabeledError {
|
pub(crate) fn map_arboard_err_to_label(err: arboard::Error) -> nu_protocol::LabeledError {
|
||||||
nu_protocol::LabeledError::new(format!("Clipboard Error: {}", err.to_string()))
|
nu_protocol::LabeledError::new(format!("Clipboard Error: {}", err))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
io::{stderr, stdout, Read, Write},
|
io::{Read, Write, stderr, stdout},
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::clipboard::clipboard::Clipboard;
|
|
||||||
use crate::ClipboardPlugins;
|
use crate::ClipboardPlugins;
|
||||||
|
use crate::clipboard::clipboard::Clipboard;
|
||||||
use crate::{clipboard::clipboard::create_clipboard, utils::json};
|
use crate::{clipboard::clipboard::create_clipboard, utils::json};
|
||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||||
use nu_protocol::{Category, IntoPipelineData, LabeledError, PipelineData, Signature, Type, Value};
|
use nu_protocol::{Category, IntoPipelineData, LabeledError, PipelineData, Signature, Type, Value};
|
||||||
@ -12,7 +12,7 @@ impl ClipboardCopy {
|
|||||||
}
|
}
|
||||||
fn format_json(input: &Value) -> Result<String, LabeledError> {
|
fn format_json(input: &Value) -> Result<String, LabeledError> {
|
||||||
let json_value =
|
let json_value =
|
||||||
json::value_to_json_value(&input).map(|v| nu_json::to_string_with_indent(&v, 4));
|
json::value_to_json_value(input).map(|v| nu_json::to_string_with_indent(&v, 4));
|
||||||
|
|
||||||
match json_value {
|
match json_value {
|
||||||
Ok(Ok(text)) => Ok(text.to_owned()), // Return the owned String
|
Ok(Ok(text)) => Ok(text.to_owned()), // Return the owned String
|
||||||
@ -62,9 +62,7 @@ impl PluginCommand for ClipboardCopy {
|
|||||||
let value = input.into_value(call.head);
|
let value = input.into_value(call.head);
|
||||||
match value {
|
match value {
|
||||||
Ok(value) => {
|
Ok(value) => {
|
||||||
if let Err(err) = Self::copy(engine, &value) {
|
Self::copy(engine, &value)?;
|
||||||
return Err(err);
|
|
||||||
}
|
|
||||||
Ok(value.into_pipeline_data())
|
Ok(value.into_pipeline_data())
|
||||||
}
|
}
|
||||||
Err(err) => Err(LabeledError::new(err.to_string())),
|
Err(err) => Err(LabeledError::new(err.to_string())),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
clipboard::clipboard::{create_clipboard, Clipboard},
|
|
||||||
utils::json::json_to_value,
|
|
||||||
ClipboardPlugins,
|
ClipboardPlugins,
|
||||||
|
clipboard::clipboard::{Clipboard, create_clipboard},
|
||||||
|
utils::json::json_to_value,
|
||||||
};
|
};
|
||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||||
use nu_protocol::{Category, IntoPipelineData, LabeledError, PipelineData, Type, Value};
|
use nu_protocol::{Category, IntoPipelineData, LabeledError, PipelineData, Type, Value};
|
||||||
|
|||||||
@ -4,13 +4,13 @@ pub mod utils;
|
|||||||
use std::io;
|
use std::io;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use std::{
|
use std::{
|
||||||
io::{stderr, stdout, Write},
|
io::{Write, stderr, stdout},
|
||||||
process::exit,
|
process::exit,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::command::copy::ClipboardCopy;
|
use crate::command::copy::ClipboardCopy;
|
||||||
use crate::command::paste::ClipboardPaste;
|
use crate::command::paste::ClipboardPaste;
|
||||||
use clipboard::clipboard::{create_clipboard, CheckResult, Clipboard};
|
use clipboard::clipboard::{CheckResult, Clipboard, create_clipboard};
|
||||||
use nu_plugin::PluginCommand;
|
use nu_plugin::PluginCommand;
|
||||||
|
|
||||||
pub struct ClipboardPlugins;
|
pub struct ClipboardPlugins;
|
||||||
@ -30,10 +30,13 @@ impl nu_plugin::Plugin for ClipboardPlugins {
|
|||||||
|
|
||||||
fn main() -> Result<(), io::Error> {
|
fn main() -> Result<(), io::Error> {
|
||||||
match create_clipboard(None).pre_execute_check() {
|
match create_clipboard(None).pre_execute_check() {
|
||||||
CheckResult::Continue => Ok(nu_plugin::serve_plugin(
|
CheckResult::Continue => {
|
||||||
&mut ClipboardPlugins {},
|
nu_plugin::serve_plugin(
|
||||||
|
&ClipboardPlugins {},
|
||||||
nu_plugin::MsgPackSerializer {},
|
nu_plugin::MsgPackSerializer {},
|
||||||
)),
|
);
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
CheckResult::Exit(message, code) => {
|
CheckResult::Exit(message, code) => {
|
||||||
if code != 0 {
|
if code != 0 {
|
||||||
|
|||||||
514
nu_plugin_desktop_notifications/Cargo.lock
generated
514
nu_plugin_desktop_notifications/Cargo.lock
generated
@ -38,12 +38,6 @@ version = "0.2.21"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android-tzdata"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@ -53,6 +47,56 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell_polyfill",
|
||||||
|
"windows-sys 0.61.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
@ -227,7 +271,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash 1.1.0",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
@ -370,16 +414,15 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.39"
|
version = "0.4.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
|
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"pure-rust-locales",
|
"pure-rust-locales",
|
||||||
"serde",
|
"serde",
|
||||||
"windows-targets 0.52.6",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -402,6 +445,40 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.5.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
"terminal_size",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "concurrent-queue"
|
name = "concurrent-queue"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -540,6 +617,17 @@ dependencies = [
|
|||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "displaydoc"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "doctest-file"
|
name = "doctest-file"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -637,9 +725,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fancy-regex"
|
name = "fancy-regex"
|
||||||
version = "0.16.2"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f"
|
checksum = "72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-set",
|
"bit-set",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
@ -663,10 +751,55 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "fluent"
|
||||||
version = "0.1.4"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
checksum = "8137a6d5a2c50d6b0ebfcb9aaa91a28154e0a70605f112d30cb0cd4a78670477"
|
||||||
|
dependencies = [
|
||||||
|
"fluent-bundle",
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluent-bundle"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4"
|
||||||
|
dependencies = [
|
||||||
|
"fluent-langneg",
|
||||||
|
"fluent-syntax",
|
||||||
|
"intl-memoizer",
|
||||||
|
"intl_pluralrules",
|
||||||
|
"rustc-hash 2.1.1",
|
||||||
|
"self_cell",
|
||||||
|
"smallvec",
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluent-langneg"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7eebbe59450baee8282d71676f3bfed5689aeab00b27545e83e5f14b1195e8b0"
|
||||||
|
dependencies = [
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluent-syntax"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
@ -724,9 +857,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.2"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
@ -776,9 +909,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.11.4"
|
version = "2.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
|
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
@ -786,9 +919,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "interprocess"
|
name = "interprocess"
|
||||||
version = "2.2.2"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "894148491d817cb36b6f778017b8ac46b17408d522dd90f539d677ea938362eb"
|
checksum = "6be5e5c847dbdb44564bd85294740d031f4f8aeb3464e5375ef7141f7538db69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"doctest-file",
|
"doctest-file",
|
||||||
"libc",
|
"libc",
|
||||||
@ -797,6 +930,25 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "intl-memoizer"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f"
|
||||||
|
dependencies = [
|
||||||
|
"type-map",
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "intl_pluralrules"
|
||||||
|
version = "7.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
|
||||||
|
dependencies = [
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inventory"
|
name = "inventory"
|
||||||
version = "0.3.19"
|
version = "0.3.19"
|
||||||
@ -812,6 +964,12 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
|
checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
@ -860,9 +1018,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.175"
|
version = "0.2.178"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
@ -931,9 +1089,9 @@ checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru"
|
name = "lru"
|
||||||
version = "0.12.5"
|
version = "0.16.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
|
checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
@ -963,12 +1121,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mach2"
|
name = "mach2"
|
||||||
version = "0.4.2"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
|
checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "malloc_buf"
|
name = "malloc_buf"
|
||||||
@ -981,9 +1136,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
@ -1008,7 +1163,7 @@ dependencies = [
|
|||||||
"supports-unicode",
|
"supports-unicode",
|
||||||
"terminal_size",
|
"terminal_size",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
"unicode-width",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1118,9 +1273,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-derive-value"
|
name = "nu-derive-value"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1465d2d3ada6004cb6689f269a08c70ba81056231e2b5392d1e0ccf5825f81cb"
|
checksum = "d71958b54c367bda033f7dcc4a73b61972fb52323f71a1e3533e290fa67148d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error2",
|
"proc-macro-error2",
|
||||||
@ -1131,9 +1286,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-engine"
|
name = "nu-engine"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3b777faf7c5180fe5d7f67d83c44fd14138d91f2938a36494ed6ac66b7160f3"
|
checksum = "d41b3e3e2d25c30741a0761856258e22624c0d60064e4f0e12f86202a451d492"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
"log",
|
"log",
|
||||||
@ -1146,25 +1301,25 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-experimental"
|
name = "nu-experimental"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73dd212a1afdad646a38c00579a0988264880aeb97fee820b349a28cdcc04df2"
|
checksum = "f328fa0531bdf49c2dc0312b40cb780e3d74e0d3dbb15d508469a5ae4cfd8d8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-glob"
|
name = "nu-glob"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "15aa2c17078926f14e393b4b708e69f228cb6fd4c81136839bde82772bdde1b5"
|
checksum = "01ee787f61353c9c90581ddf4c0602a07b991cdd06c97dac8b6d323a1a52c43a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-path"
|
name = "nu-path"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dde9d8ba26f62c07176c0237a36f38ce964ab3a0dcfb6aab1feea7515d1c6594"
|
checksum = "c01d110cb931acf56237ce572e5b156e8e1134227c90deeffb92eedda9482c23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs",
|
"dirs",
|
||||||
"omnipath",
|
"omnipath",
|
||||||
@ -1174,9 +1329,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin"
|
name = "nu-plugin"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ea1fbfd41b2f5c967675fc948831e03be67d91c6b8e18a60f3445113fe6548c"
|
checksum = "c322531b1a7d6338c5ead1f454294f46babf8c99cd4716311cab1e88ba52b154"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"nix 0.30.1",
|
"nix 0.30.1",
|
||||||
@ -1185,14 +1340,14 @@ dependencies = [
|
|||||||
"nu-plugin-protocol",
|
"nu-plugin-protocol",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
"nu-utils",
|
"nu-utils",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-core"
|
name = "nu-plugin-core"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd2410648c2c38cf9359595ffcf281d9d60a81c0580ff07f7c7d42bed414f3a1"
|
checksum = "38ee792aeb0d37e0ed55ca4304e434eece497914e27ae42616a8bb973f5d2720"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"interprocess",
|
"interprocess",
|
||||||
"log",
|
"log",
|
||||||
@ -1206,9 +1361,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-protocol"
|
name = "nu-plugin-protocol"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "27de26da922261dff8103a811879228c55749a1b7b0e573b639c609a0651a01e"
|
checksum = "7725f341428db16dbef4392970de32705abc77ee80a902572c8da811dade3564"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
"nu-utils",
|
"nu-utils",
|
||||||
@ -1220,9 +1375,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-protocol"
|
name = "nu-protocol"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "038943300ca9de0924fef1c795a7dd16ffc67105629477cf163e8ee6bad95ea6"
|
checksum = "f1c0e58cbeb46cbfd40156e6f4b9f90e4a77e774ca863fa158867a4726aab1d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli",
|
"brotli",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -1251,7 +1406,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
"typetag",
|
"typetag",
|
||||||
"web-time",
|
"web-time",
|
||||||
"windows 0.62.2",
|
"windows 0.62.2",
|
||||||
@ -1260,9 +1415,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-system"
|
name = "nu-system"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46be734cc9b19e09a9665769e14360e13e6978490056ba5c8bfad7dd0537ea83"
|
checksum = "62fe7847b65edbe362a0fcb67dedfab9fd7370e89c0313f7cb7d0a7ab8f9834b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
@ -1274,15 +1429,16 @@ dependencies = [
|
|||||||
"ntapi",
|
"ntapi",
|
||||||
"procfs",
|
"procfs",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
|
"uucore",
|
||||||
"web-time",
|
"web-time",
|
||||||
"windows 0.62.2",
|
"windows 0.62.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-utils"
|
name = "nu-utils"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f8eb43c29cc5bce85f87defdadc2cca964fa434d808af37036a7cb78f3c68e9"
|
checksum = "df85a8a4bb28c84d5f7c096c02c859ac454dfac59fd0296ab5eb6ed86619219e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteyarn",
|
"byteyarn",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
@ -1303,7 +1459,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_desktop_notifications"
|
name = "nu_plugin_desktop_notifications"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"notify-rust",
|
"notify-rust",
|
||||||
"nu-plugin",
|
"nu-plugin",
|
||||||
@ -1357,18 +1513,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-core-foundation"
|
name = "objc2-core-foundation"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
|
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-io-kit"
|
name = "objc2-io-kit"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
|
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
@ -1395,6 +1551,12 @@ version = "1.20.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "option-ext"
|
name = "option-ext"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -1411,6 +1573,15 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_display"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad5fd71b79026fb918650dde6d125000a233764f1c2f1659a1c71118e33ea08f"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width 0.2.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_pipe"
|
name = "os_pipe"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@ -1542,23 +1713,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "procfs"
|
name = "procfs"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f"
|
checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chrono",
|
"chrono",
|
||||||
"flate2",
|
"flate2",
|
||||||
"hex",
|
|
||||||
"procfs-core",
|
"procfs-core",
|
||||||
"rustix 0.38.44",
|
"rustix 1.1.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "procfs-core"
|
name = "procfs-core"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec"
|
checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -1567,9 +1737,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pure-rust-locales"
|
name = "pure-rust-locales"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1190fd18ae6ce9e137184f207593877e70f39b015040156b1e05081cdfe3733a"
|
checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pwd"
|
name = "pwd"
|
||||||
@ -1633,23 +1803,23 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.15",
|
"getrandom 0.2.15",
|
||||||
"libredox",
|
"libredox",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref-cast"
|
name = "ref-cast"
|
||||||
version = "1.0.23"
|
version = "1.0.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931"
|
checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ref-cast-impl",
|
"ref-cast-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref-cast-impl"
|
name = "ref-cast-impl"
|
||||||
version = "1.0.23"
|
version = "1.0.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6"
|
checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1698,11 +1868,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmp-serde"
|
name = "rmp-serde"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
|
checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
|
||||||
"rmp",
|
"rmp",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@ -1713,6 +1882,12 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "2.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.44"
|
version = "0.38.44"
|
||||||
@ -1757,6 +1932,12 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "self_cell"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.25"
|
version = "1.0.25"
|
||||||
@ -1765,18 +1946,28 @@ checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.217"
|
version = "1.0.228"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
|
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_core"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.217"
|
version = "1.0.228"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1785,14 +1976,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.138"
|
version = "1.0.149"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
|
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ryu",
|
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1873,10 +2065,16 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strsim"
|
||||||
version = "0.26.3"
|
version = "0.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.27.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum_macros"
|
name = "strum_macros"
|
||||||
@ -1933,16 +2131,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sysinfo"
|
name = "sysinfo"
|
||||||
version = "0.37.2"
|
version = "0.38.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f"
|
checksum = "92ab6a2f8bfe508deb3c6406578252e491d299cbbf3bc0529ecc3313aee4a52f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ntapi",
|
"ntapi",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-io-kit",
|
"objc2-io-kit",
|
||||||
"windows 0.61.1",
|
"windows 0.62.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1952,7 +2150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9"
|
checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quick-xml",
|
"quick-xml",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
"windows 0.61.1",
|
"windows 0.61.1",
|
||||||
"windows-version",
|
"windows-version",
|
||||||
]
|
]
|
||||||
@ -1988,7 +2186,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
|
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-linebreak",
|
"unicode-linebreak",
|
||||||
"unicode-width",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2002,11 +2200,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.12"
|
version = "2.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl 2.0.12",
|
"thiserror-impl 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2022,9 +2220,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "2.0.12"
|
version = "2.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2050,6 +2248,17 @@ version = "0.1.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinystr"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"serde_core",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.8"
|
version = "0.6.8"
|
||||||
@ -2098,6 +2307,15 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "type-map"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90"
|
||||||
|
dependencies = [
|
||||||
|
"rustc-hash 2.1.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typeid"
|
name = "typeid"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@ -2140,10 +2358,28 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unic-langid"
|
||||||
version = "2.8.1"
|
version = "0.9.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
checksum = "a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05"
|
||||||
|
dependencies = [
|
||||||
|
"unic-langid-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-langid-impl"
|
||||||
|
version = "0.9.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658"
|
||||||
|
dependencies = [
|
||||||
|
"tinystr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
@ -2169,6 +2405,47 @@ version = "0.1.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uucore"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b157ba598d7f7ed06f6dbc62999edb9d730b4d3fb58e503d8ad6d5fbe1e04391"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"fluent",
|
||||||
|
"fluent-bundle",
|
||||||
|
"fluent-syntax",
|
||||||
|
"libc",
|
||||||
|
"nix 0.30.1",
|
||||||
|
"os_display",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"unic-langid",
|
||||||
|
"uucore_procs",
|
||||||
|
"wild",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uucore_procs"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "daa291a52608ac5a2f8539e119666e021baa6b8c01f22f02ed201bbae54cbbc0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vte"
|
name = "vte"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
@ -2267,6 +2544,15 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311"
|
checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wild"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3131afc8c575281e1e80f36ed6a092aa502c08b18ed7524e86fbbb12bb410e1"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -2763,6 +3049,28 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerofrom"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec"
|
||||||
|
version = "0.11.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zvariant"
|
name = "zvariant"
|
||||||
version = "5.4.0"
|
version = "5.4.0"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = "0.109.1"
|
nu-plugin = "0.111.0"
|
||||||
nu-protocol = "0.109.1"
|
nu-protocol = "0.111.0"
|
||||||
|
|
||||||
[dependencies.notify-rust]
|
[dependencies.notify-rust]
|
||||||
version = "4.11.7"
|
version = "4.11.7"
|
||||||
@ -20,4 +20,4 @@ license = "MIT"
|
|||||||
name = "nu_plugin_desktop_notifications"
|
name = "nu_plugin_desktop_notifications"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/FMotalleb/nu_plugin_desktop_notifications"
|
repository = "https://github.com/FMotalleb/nu_plugin_desktop_notifications"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
|
|||||||
@ -17,7 +17,8 @@ A [Nushell](https://www.nushell.sh/) plugin for sending desktop notifications us
|
|||||||
|
|
||||||
### **Sending a Notification**
|
### **Sending a Notification**
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
notify -t "Test notification body" --summary "Test title"
|
notify -t "Test notification body" --summary "Test title"
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -40,7 +41,8 @@ Send a notification after a task completes, displaying the elapsed time:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
def "notify on done" [
|
def "notify on done" [
|
||||||
task: closure
|
task: closure
|
||||||
] {
|
] {
|
||||||
@ -62,14 +64,16 @@ notify on done { port scan 8.8.8.8 53 }
|
|||||||
|
|
||||||
### 🚀 Recommended: Using [nupm](https://github.com/nushell/nupm)
|
### 🚀 Recommended: Using [nupm](https://github.com/nushell/nupm)
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
git clone https://github.com/FMotalleb/nu_plugin_desktop_notifications.git
|
git clone https://github.com/FMotalleb/nu_plugin_desktop_notifications.git
|
||||||
nupm install --path nu_plugin_desktop_notifications -f
|
nupm install --path nu_plugin_desktop_notifications -f
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🛠️ Manual Compilation
|
### 🛠️ Manual Compilation
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
git clone https://github.com/FMotalleb/nu_plugin_desktop_notifications.git
|
git clone https://github.com/FMotalleb/nu_plugin_desktop_notifications.git
|
||||||
cd nu_plugin_desktop_notifications
|
cd nu_plugin_desktop_notifications
|
||||||
cargo build -r
|
cargo build -r
|
||||||
@ -78,7 +82,8 @@ register target/release/nu_plugin_desktop_notifications
|
|||||||
|
|
||||||
### 📦 Install via Cargo (using git)
|
### 📦 Install via Cargo (using git)
|
||||||
|
|
||||||
```bash
|
```rust
|
||||||
|
bash
|
||||||
cargo install --git https://github.com/FMotalleb/nu_plugin_desktop_notifications.git
|
cargo install --git https://github.com/FMotalleb/nu_plugin_desktop_notifications.git
|
||||||
register ~/.cargo/bin/nu_plugin_desktop_notifications
|
register ~/.cargo/bin/nu_plugin_desktop_notifications
|
||||||
```
|
```
|
||||||
@ -87,7 +92,8 @@ register ~/.cargo/bin/nu_plugin_desktop_notifications
|
|||||||
>
|
>
|
||||||
> _Since I live in Iran and crates.io often restricts package updates, the version there might be outdated._
|
> _Since I live in Iran and crates.io often restricts package updates, the version there might be outdated._
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
cargo install nu_plugin_desktop_notifications
|
cargo install nu_plugin_desktop_notifications
|
||||||
register ~/.cargo/bin/nu_plugin_desktop_notifications
|
register ~/.cargo/bin/nu_plugin_desktop_notifications
|
||||||
```
|
```
|
||||||
@ -1,4 +1,4 @@
|
|||||||
use nu_plugin::{serve_plugin, Plugin};
|
use nu_plugin::{Plugin, serve_plugin};
|
||||||
|
|
||||||
use crate::notify::NotifyCommand;
|
use crate::notify::NotifyCommand;
|
||||||
mod notify;
|
mod notify;
|
||||||
@ -15,5 +15,5 @@ impl Plugin for NotifyPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
serve_plugin(&mut NotifyPlugin {}, nu_plugin::MsgPackSerializer {})
|
serve_plugin(&NotifyPlugin {}, nu_plugin::MsgPackSerializer {})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,15 +107,12 @@ impl SimplePluginCommand for NotifyCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(duration_value) = call.get_flag_value("timeout") {
|
if let Some(duration_value) = call.get_flag_value("timeout") {
|
||||||
match duration_value.as_duration() {
|
if let Ok(timeout) = duration_value.as_duration() {
|
||||||
Ok(timeout) => {
|
|
||||||
if let Ok(nanos) = timeout.try_into() {
|
if let Ok(nanos) = timeout.try_into() {
|
||||||
let duration = Timeout::from(Duration::from_nanos(nanos));
|
let duration = Timeout::from(Duration::from_nanos(nanos));
|
||||||
notification.timeout(duration);
|
notification.timeout(duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match notification.show() {
|
match notification.show() {
|
||||||
|
|||||||
491
nu_plugin_fluent/Cargo.lock
generated
491
nu_plugin_fluent/Cargo.lock
generated
@ -47,6 +47,56 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"is_terminal_polyfill",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.61.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"once_cell_polyfill",
|
||||||
|
"windows-sys 0.61.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
@ -197,9 +247,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.42"
|
version = "0.4.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
@ -228,6 +278,40 @@ dependencies = [
|
|||||||
"libloading",
|
"libloading",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.5.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
"terminal_size",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@ -264,7 +348,7 @@ dependencies = [
|
|||||||
"document-features",
|
"document-features",
|
||||||
"mio",
|
"mio",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rustix 1.1.2",
|
"rustix",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-mio",
|
"signal-hook-mio",
|
||||||
"winapi",
|
"winapi",
|
||||||
@ -382,9 +466,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fancy-regex"
|
name = "fancy-regex"
|
||||||
version = "0.16.2"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f"
|
checksum = "72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-set",
|
"bit-set",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
@ -455,14 +539,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198"
|
checksum = "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.5"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
@ -495,21 +579,15 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"foldhash",
|
"foldhash",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.16.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -534,7 +612,7 @@ dependencies = [
|
|||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -548,19 +626,19 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.12.0"
|
version = "2.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
|
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.16.0",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "interprocess"
|
name = "interprocess"
|
||||||
version = "2.2.3"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d941b405bd2322993887859a8ee6ac9134945a24ec5ec763a8a962fc64dfec2d"
|
checksum = "6be5e5c847dbdb44564bd85294740d031f4f8aeb3464e5375ef7141f7538db69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"doctest-file",
|
"doctest-file",
|
||||||
"libc",
|
"libc",
|
||||||
@ -603,6 +681,12 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
|
checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_terminal_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
@ -651,9 +735,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.175"
|
version = "0.2.178"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
@ -686,12 +770,6 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linux-raw-sys"
|
|
||||||
version = "0.4.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
@ -722,11 +800,11 @@ checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru"
|
name = "lru"
|
||||||
version = "0.12.5"
|
version = "0.16.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
|
checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown 0.15.5",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -741,18 +819,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mach2"
|
name = "mach2"
|
||||||
version = "0.4.3"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44"
|
checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.5"
|
version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miette"
|
name = "miette"
|
||||||
@ -851,9 +926,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-derive-value"
|
name = "nu-derive-value"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1465d2d3ada6004cb6689f269a08c70ba81056231e2b5392d1e0ccf5825f81cb"
|
checksum = "d71958b54c367bda033f7dcc4a73b61972fb52323f71a1e3533e290fa67148d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error2",
|
"proc-macro-error2",
|
||||||
@ -864,9 +939,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-engine"
|
name = "nu-engine"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3b777faf7c5180fe5d7f67d83c44fd14138d91f2938a36494ed6ac66b7160f3"
|
checksum = "d41b3e3e2d25c30741a0761856258e22624c0d60064e4f0e12f86202a451d492"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
"log",
|
"log",
|
||||||
@ -879,25 +954,25 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-experimental"
|
name = "nu-experimental"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73dd212a1afdad646a38c00579a0988264880aeb97fee820b349a28cdcc04df2"
|
checksum = "f328fa0531bdf49c2dc0312b40cb780e3d74e0d3dbb15d508469a5ae4cfd8d8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-glob"
|
name = "nu-glob"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "15aa2c17078926f14e393b4b708e69f228cb6fd4c81136839bde82772bdde1b5"
|
checksum = "01ee787f61353c9c90581ddf4c0602a07b991cdd06c97dac8b6d323a1a52c43a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-path"
|
name = "nu-path"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dde9d8ba26f62c07176c0237a36f38ce964ab3a0dcfb6aab1feea7515d1c6594"
|
checksum = "c01d110cb931acf56237ce572e5b156e8e1134227c90deeffb92eedda9482c23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs",
|
"dirs",
|
||||||
"omnipath",
|
"omnipath",
|
||||||
@ -907,9 +982,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin"
|
name = "nu-plugin"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ea1fbfd41b2f5c967675fc948831e03be67d91c6b8e18a60f3445113fe6548c"
|
checksum = "c322531b1a7d6338c5ead1f454294f46babf8c99cd4716311cab1e88ba52b154"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
@ -918,14 +993,14 @@ dependencies = [
|
|||||||
"nu-plugin-protocol",
|
"nu-plugin-protocol",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
"nu-utils",
|
"nu-utils",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-core"
|
name = "nu-plugin-core"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd2410648c2c38cf9359595ffcf281d9d60a81c0580ff07f7c7d42bed414f3a1"
|
checksum = "38ee792aeb0d37e0ed55ca4304e434eece497914e27ae42616a8bb973f5d2720"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"interprocess",
|
"interprocess",
|
||||||
"log",
|
"log",
|
||||||
@ -934,14 +1009,14 @@ dependencies = [
|
|||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"windows 0.62.2",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-protocol"
|
name = "nu-plugin-protocol"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "27de26da922261dff8103a811879228c55749a1b7b0e573b639c609a0651a01e"
|
checksum = "7725f341428db16dbef4392970de32705abc77ee80a902572c8da811dade3564"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
"nu-utils",
|
"nu-utils",
|
||||||
@ -953,9 +1028,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-protocol"
|
name = "nu-protocol"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "038943300ca9de0924fef1c795a7dd16ffc67105629477cf163e8ee6bad95ea6"
|
checksum = "f1c0e58cbeb46cbfd40156e6f4b9f90e4a77e774ca863fa158867a4726aab1d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli",
|
"brotli",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -984,18 +1059,18 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.18",
|
||||||
"typetag",
|
"typetag",
|
||||||
"web-time",
|
"web-time",
|
||||||
"windows 0.62.2",
|
"windows",
|
||||||
"windows-sys 0.61.0",
|
"windows-sys 0.61.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-system"
|
name = "nu-system"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46be734cc9b19e09a9665769e14360e13e6978490056ba5c8bfad7dd0537ea83"
|
checksum = "62fe7847b65edbe362a0fcb67dedfab9fd7370e89c0313f7cb7d0a7ab8f9834b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
@ -1007,15 +1082,16 @@ dependencies = [
|
|||||||
"ntapi",
|
"ntapi",
|
||||||
"procfs",
|
"procfs",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
|
"uucore",
|
||||||
"web-time",
|
"web-time",
|
||||||
"windows 0.62.2",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-utils"
|
name = "nu-utils"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f8eb43c29cc5bce85f87defdadc2cca964fa434d808af37036a7cb78f3c68e9"
|
checksum = "df85a8a4bb28c84d5f7c096c02c859ac454dfac59fd0296ab5eb6ed86619219e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteyarn",
|
"byteyarn",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
@ -1036,7 +1112,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_fluent"
|
name = "nu_plugin_fluent"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluent",
|
"fluent",
|
||||||
"fluent-bundle",
|
"fluent-bundle",
|
||||||
@ -1047,7 +1123,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.18",
|
||||||
"unic-langid",
|
"unic-langid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1072,18 +1148,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-core-foundation"
|
name = "objc2-core-foundation"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
|
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-io-kit"
|
name = "objc2-io-kit"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
|
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
@ -1101,12 +1177,27 @@ version = "1.21.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell_polyfill"
|
||||||
|
version = "1.70.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "option-ext"
|
name = "option-ext"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_display"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad5fd71b79026fb918650dde6d125000a233764f1c2f1659a1c71118e33ea08f"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_pipe"
|
name = "os_pipe"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
@ -1185,23 +1276,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "procfs"
|
name = "procfs"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f"
|
checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chrono",
|
"chrono",
|
||||||
"flate2",
|
"flate2",
|
||||||
"hex",
|
|
||||||
"procfs-core",
|
"procfs-core",
|
||||||
"rustix 0.38.44",
|
"rustix",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "procfs-core"
|
name = "procfs-core"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec"
|
checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -1210,9 +1300,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pure-rust-locales"
|
name = "pure-rust-locales"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1190fd18ae6ce9e137184f207593877e70f39b015040156b1e05081cdfe3733a"
|
checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pwd"
|
name = "pwd"
|
||||||
@ -1262,23 +1352,23 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.16",
|
"getrandom 0.2.16",
|
||||||
"libredox",
|
"libredox",
|
||||||
"thiserror 2.0.16",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref-cast"
|
name = "ref-cast"
|
||||||
version = "1.0.24"
|
version = "1.0.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf"
|
checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ref-cast-impl",
|
"ref-cast-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref-cast-impl"
|
name = "ref-cast-impl"
|
||||||
version = "1.0.24"
|
version = "1.0.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
|
checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1327,11 +1417,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmp-serde"
|
name = "rmp-serde"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
|
checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
|
||||||
"rmp",
|
"rmp",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@ -1348,19 +1437,6 @@ version = "2.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustix"
|
|
||||||
version = "0.38.44"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"errno",
|
|
||||||
"libc",
|
|
||||||
"linux-raw-sys 0.4.15",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
@ -1370,7 +1446,7 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.11.0",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.61.0",
|
"windows-sys 0.61.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1406,9 +1482,9 @@ checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.225"
|
version = "1.0.228"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d"
|
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_core",
|
"serde_core",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
@ -1416,18 +1492,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_core"
|
name = "serde_core"
|
||||||
version = "1.0.225"
|
version = "1.0.228"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383"
|
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.225"
|
version = "1.0.228"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516"
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1436,15 +1512,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.145"
|
version = "1.0.149"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ryu",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_core",
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1499,10 +1575,16 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strsim"
|
||||||
version = "0.26.3"
|
version = "0.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.27.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum_macros"
|
name = "strum_macros"
|
||||||
@ -1559,16 +1641,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sysinfo"
|
name = "sysinfo"
|
||||||
version = "0.37.2"
|
version = "0.38.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f"
|
checksum = "92ab6a2f8bfe508deb3c6406578252e491d299cbbf3bc0529ecc3313aee4a52f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ntapi",
|
"ntapi",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-io-kit",
|
"objc2-io-kit",
|
||||||
"windows 0.61.3",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1580,7 +1662,7 @@ dependencies = [
|
|||||||
"fastrand",
|
"fastrand",
|
||||||
"getrandom 0.3.3",
|
"getrandom 0.3.3",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.1.2",
|
"rustix",
|
||||||
"windows-sys 0.61.0",
|
"windows-sys 0.61.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1590,7 +1672,7 @@ version = "0.4.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0"
|
checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustix 1.1.2",
|
"rustix",
|
||||||
"windows-sys 0.60.2",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1615,11 +1697,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.16"
|
version = "2.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0"
|
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl 2.0.16",
|
"thiserror-impl 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1635,9 +1717,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "2.0.16"
|
version = "2.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960"
|
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1713,9 +1795,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unicase"
|
||||||
version = "2.8.1"
|
version = "2.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
@ -1747,6 +1829,41 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
|
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uucore"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b157ba598d7f7ed06f6dbc62999edb9d730b4d3fb58e503d8ad6d5fbe1e04391"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"fluent",
|
||||||
|
"fluent-bundle",
|
||||||
|
"fluent-syntax",
|
||||||
|
"libc",
|
||||||
|
"nix",
|
||||||
|
"os_display",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"unic-langid",
|
||||||
|
"uucore_procs",
|
||||||
|
"wild",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uucore_procs"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "daa291a52608ac5a2f8539e119666e021baa6b8c01f22f02ed201bbae54cbbc0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vte"
|
name = "vte"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
@ -1855,6 +1972,15 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d"
|
checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wild"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3131afc8c575281e1e80f36ed6a092aa502c08b18ed7524e86fbbb12bb410e1"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -1877,38 +2003,16 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows"
|
|
||||||
version = "0.61.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
|
||||||
dependencies = [
|
|
||||||
"windows-collections 0.2.0",
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
"windows-future 0.2.1",
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
"windows-numerics 0.2.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows"
|
name = "windows"
|
||||||
version = "0.62.2"
|
version = "0.62.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-collections 0.3.2",
|
"windows-collections",
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
"windows-future 0.3.2",
|
"windows-future",
|
||||||
"windows-numerics 0.3.1",
|
"windows-numerics",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-collections"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
|
||||||
dependencies = [
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1917,20 +2021,7 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
|
checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-core"
|
|
||||||
version = "0.61.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
|
||||||
dependencies = [
|
|
||||||
"windows-implement",
|
|
||||||
"windows-interface",
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
"windows-result 0.3.4",
|
|
||||||
"windows-strings 0.4.2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1942,19 +2033,8 @@ dependencies = [
|
|||||||
"windows-implement",
|
"windows-implement",
|
||||||
"windows-interface",
|
"windows-interface",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
"windows-result 0.4.1",
|
"windows-result",
|
||||||
"windows-strings 0.5.1",
|
"windows-strings",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-future"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
|
||||||
dependencies = [
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
"windows-threading 0.1.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1963,9 +2043,9 @@ version = "0.3.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
"windows-threading 0.2.1",
|
"windows-threading",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2002,35 +2082,16 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-numerics"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
|
||||||
dependencies = [
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-numerics"
|
name = "windows-numerics"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
|
checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.62.2",
|
"windows-core",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-result"
|
|
||||||
version = "0.3.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-result"
|
name = "windows-result"
|
||||||
version = "0.4.1"
|
version = "0.4.1"
|
||||||
@ -2040,15 +2101,6 @@ dependencies = [
|
|||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-strings"
|
|
||||||
version = "0.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-strings"
|
name = "windows-strings"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@ -2127,15 +2179,6 @@ dependencies = [
|
|||||||
"windows_x86_64_msvc 0.53.0",
|
"windows_x86_64_msvc 0.53.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-threading"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-threading"
|
name = "windows-threading"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -2282,3 +2325,9 @@ checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"zerofrom",
|
"zerofrom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nu_plugin_fluent"
|
name = "nu_plugin_fluent"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Nushell plugin for Fluent i18n integration"
|
description = "Nushell plugin for Fluent i18n integration"
|
||||||
authors = ["Jesús Pérex <jpl@jesusperez.com>"]
|
authors = ["Jesús Pérex <jpl@jesusperez.com>"]
|
||||||
@ -19,8 +19,8 @@ categories = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = "0.109.1"
|
nu-plugin = "0.111.0"
|
||||||
nu-protocol = "0.109.1"
|
nu-protocol = "0.111.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
fluent = "0.17"
|
fluent = "0.17"
|
||||||
fluent-bundle = "0.16"
|
fluent-bundle = "0.16"
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -1,10 +1,8 @@
|
|||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
|
||||||
use nu_protocol::{
|
|
||||||
Category, LabeledError, Signature, Span, SyntaxShape, Type, Value, record,
|
|
||||||
};
|
|
||||||
use fluent::{FluentBundle, FluentResource};
|
|
||||||
use unic_langid::LanguageIdentifier;
|
|
||||||
use crate::FluentPlugin;
|
use crate::FluentPlugin;
|
||||||
|
use fluent::{FluentBundle, FluentResource};
|
||||||
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
||||||
|
use nu_protocol::{record, Category, LabeledError, Signature, Span, SyntaxShape, Type, Value};
|
||||||
|
use unic_langid::LanguageIdentifier;
|
||||||
|
|
||||||
pub struct CreateBundle;
|
pub struct CreateBundle;
|
||||||
|
|
||||||
@ -37,7 +35,11 @@ impl SimplePluginCommand for CreateBundle {
|
|||||||
"Fallback locales in order",
|
"Fallback locales in order",
|
||||||
Some('f'),
|
Some('f'),
|
||||||
)
|
)
|
||||||
.switch("override", "Allow page files to override global messages", Some('o'))
|
.switch(
|
||||||
|
"override",
|
||||||
|
"Allow page files to override global messages",
|
||||||
|
Some('o'),
|
||||||
|
)
|
||||||
.category(Category::Strings)
|
.category(Category::Strings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,16 +72,24 @@ impl SimplePluginCommand for CreateBundle {
|
|||||||
let locale_code: String = call.req(0)?;
|
let locale_code: String = call.req(0)?;
|
||||||
|
|
||||||
// Parse locale
|
// Parse locale
|
||||||
let locale: LanguageIdentifier = locale_code.parse()
|
let locale: LanguageIdentifier = locale_code.parse().map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Invalid locale").with_label(format!("Invalid locale '{}': {}", locale_code, e), call.head))?;
|
LabeledError::new("Invalid locale").with_label(
|
||||||
|
format!("Invalid locale '{}': {}", locale_code, e),
|
||||||
|
call.head,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
// Create fallback locales
|
// Create fallback locales
|
||||||
let mut locales = vec![locale.clone()];
|
let mut locales = vec![locale.clone()];
|
||||||
if let Some(fallback_value) = call.get_flag("fallback")? {
|
if let Some(fallback_value) = call.get_flag("fallback")? {
|
||||||
let fallback_codes = extract_string_list(fallback_value)?;
|
let fallback_codes = extract_string_list(fallback_value)?;
|
||||||
for code in fallback_codes {
|
for code in fallback_codes {
|
||||||
let fallback_locale: LanguageIdentifier = code.parse()
|
let fallback_locale: LanguageIdentifier = code.parse().map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Invalid fallback locale").with_label(format!("Invalid fallback locale '{}': {}", code, e), call.head))?;
|
LabeledError::new("Invalid fallback locale").with_label(
|
||||||
|
format!("Invalid fallback locale '{}': {}", code, e),
|
||||||
|
call.head,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
locales.push(fallback_locale);
|
locales.push(fallback_locale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,12 +125,12 @@ impl SimplePluginCommand for CreateBundle {
|
|||||||
|
|
||||||
fn extract_string_list(value: Value) -> Result<Vec<String>, LabeledError> {
|
fn extract_string_list(value: Value) -> Result<Vec<String>, LabeledError> {
|
||||||
match value {
|
match value {
|
||||||
Value::List { vals, .. } => {
|
Value::List { vals, .. } => vals
|
||||||
vals.iter()
|
.iter()
|
||||||
.map(|v| value_to_string(v))
|
.map(|v| value_to_string(v))
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>(),
|
||||||
}
|
_ => Err(LabeledError::new("Invalid list")
|
||||||
_ => Err(LabeledError::new("Invalid list").with_label("Must be a list of strings", nu_protocol::Span::unknown())),
|
.with_label("Must be a list of strings", nu_protocol::Span::unknown())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,23 +144,31 @@ fn load_files_to_bundle(
|
|||||||
source: &str,
|
source: &str,
|
||||||
) -> Result<(), LabeledError> {
|
) -> Result<(), LabeledError> {
|
||||||
for file_path in files {
|
for file_path in files {
|
||||||
let content = std::fs::read_to_string(file_path)
|
let content = std::fs::read_to_string(file_path).map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Read error").with_label(format!("Failed to read '{}': {}", file_path, e), nu_protocol::Span::unknown()))?;
|
LabeledError::new("Read error").with_label(
|
||||||
|
format!("Failed to read '{}': {}", file_path, e),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let resource = FluentResource::try_new(content)
|
let resource = FluentResource::try_new(content).map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Invalid FTL").with_label(format!("Invalid FTL in '{}': {:?}", file_path, e), nu_protocol::Span::unknown()))?;
|
LabeledError::new("Invalid FTL").with_label(
|
||||||
|
format!("Invalid FTL in '{}': {:?}", file_path, e),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
bundle.add_resource(resource)
|
bundle.add_resource(resource).map_err(|errors| {
|
||||||
.map_err(|errors| {
|
let error_msgs: Vec<String> = errors.iter().map(|e| format!("{:?}", e)).collect();
|
||||||
let error_msgs: Vec<String> = errors.iter()
|
LabeledError::new("Load error").with_label(
|
||||||
.map(|e| format!("{:?}", e))
|
format!(
|
||||||
.collect();
|
|
||||||
LabeledError::new("Load error").with_label(format!(
|
|
||||||
"Failed to load {} file '{}': {}",
|
"Failed to load {} file '{}': {}",
|
||||||
source,
|
source,
|
||||||
file_path,
|
file_path,
|
||||||
error_msgs.join(", ")
|
error_msgs.join(", ")
|
||||||
), nu_protocol::Span::unknown())
|
),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -197,7 +215,7 @@ fn value_to_string(value: &Value) -> Result<String, LabeledError> {
|
|||||||
Value::Bool { val, .. } => Ok(val.to_string()),
|
Value::Bool { val, .. } => Ok(val.to_string()),
|
||||||
_ => Err(LabeledError::new("Type conversion error").with_label(
|
_ => Err(LabeledError::new("Type conversion error").with_label(
|
||||||
format!("Cannot convert {:?} to string", value.get_type()),
|
format!("Cannot convert {:?} to string", value.get_type()),
|
||||||
nu_protocol::Span::unknown()
|
nu_protocol::Span::unknown(),
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
|
use crate::FluentPlugin;
|
||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
||||||
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Type, Value};
|
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Type, Value};
|
||||||
use crate::FluentPlugin;
|
|
||||||
|
|
||||||
pub struct ExtractMessages;
|
pub struct ExtractMessages;
|
||||||
|
|
||||||
@ -14,7 +14,11 @@ impl SimplePluginCommand for ExtractMessages {
|
|||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build(PluginCommand::name(self))
|
Signature::build(PluginCommand::name(self))
|
||||||
.input_output_type(Type::Any, Type::List(Box::new(Type::String)))
|
.input_output_type(Type::Any, Type::List(Box::new(Type::String)))
|
||||||
.required("file", SyntaxShape::Filepath, "FTL file to extract messages from")
|
.required(
|
||||||
|
"file",
|
||||||
|
SyntaxShape::Filepath,
|
||||||
|
"FTL file to extract messages from",
|
||||||
|
)
|
||||||
.category(Category::Strings)
|
.category(Category::Strings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,13 +27,11 @@ impl SimplePluginCommand for ExtractMessages {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
|
fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
|
||||||
vec![
|
vec![nu_protocol::Example {
|
||||||
nu_protocol::Example {
|
|
||||||
description: "Extract message IDs from an FTL file",
|
description: "Extract message IDs from an FTL file",
|
||||||
example: "fluent-extract locales/en-US/main.ftl",
|
example: "fluent-extract locales/en-US/main.ftl",
|
||||||
result: None,
|
result: None,
|
||||||
},
|
}]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
|
use crate::FluentPlugin;
|
||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
||||||
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Type, Value};
|
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Type, Value};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use crate::FluentPlugin;
|
|
||||||
|
|
||||||
pub struct ListLocales;
|
pub struct ListLocales;
|
||||||
|
|
||||||
@ -15,7 +15,11 @@ impl SimplePluginCommand for ListLocales {
|
|||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build(PluginCommand::name(self))
|
Signature::build(PluginCommand::name(self))
|
||||||
.input_output_type(Type::Any, Type::List(Box::new(Type::String)))
|
.input_output_type(Type::Any, Type::List(Box::new(Type::String)))
|
||||||
.required("directory", SyntaxShape::Directory, "Directory containing locale folders")
|
.required(
|
||||||
|
"directory",
|
||||||
|
SyntaxShape::Directory,
|
||||||
|
"Directory containing locale folders",
|
||||||
|
)
|
||||||
.category(Category::Strings)
|
.category(Category::Strings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,13 +28,11 @@ impl SimplePluginCommand for ListLocales {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
|
fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
|
||||||
vec![
|
vec![nu_protocol::Example {
|
||||||
nu_protocol::Example {
|
|
||||||
description: "List available locales",
|
description: "List available locales",
|
||||||
example: "fluent-list-locales ./locales",
|
example: "fluent-list-locales ./locales",
|
||||||
result: None,
|
result: None,
|
||||||
},
|
}]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
@ -42,17 +44,27 @@ impl SimplePluginCommand for ListLocales {
|
|||||||
) -> Result<Value, LabeledError> {
|
) -> Result<Value, LabeledError> {
|
||||||
let directory: String = call.req(0)?;
|
let directory: String = call.req(0)?;
|
||||||
|
|
||||||
let entries = fs::read_dir(&directory)
|
let entries = fs::read_dir(&directory).map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Read error").with_label(format!("Failed to read directory '{}': {}", directory, e), call.head))?;
|
LabeledError::new("Read error").with_label(
|
||||||
|
format!("Failed to read directory '{}': {}", directory, e),
|
||||||
|
call.head,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let mut locales = Vec::new();
|
let mut locales = Vec::new();
|
||||||
|
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
let entry = entry
|
let entry = entry.map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Read error").with_label(format!("Failed to read directory entry: {}", e), call.head))?;
|
LabeledError::new("Read error")
|
||||||
|
.with_label(format!("Failed to read directory entry: {}", e), call.head)
|
||||||
|
})?;
|
||||||
|
|
||||||
if entry.file_type()
|
if entry
|
||||||
.map_err(|e| LabeledError::new("File type error").with_label(format!("Failed to get file type: {}", e), call.head))?
|
.file_type()
|
||||||
|
.map_err(|e| {
|
||||||
|
LabeledError::new("File type error")
|
||||||
|
.with_label(format!("Failed to get file type: {}", e), call.head)
|
||||||
|
})?
|
||||||
.is_dir()
|
.is_dir()
|
||||||
{
|
{
|
||||||
if let Some(name) = entry.file_name().to_str() {
|
if let Some(name) = entry.file_name().to_str() {
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
|
||||||
use nu_protocol::{
|
|
||||||
Category, LabeledError, Signature, SyntaxShape, Type, Value
|
|
||||||
};
|
|
||||||
use fluent::{FluentBundle, FluentResource, FluentArgs, FluentValue};
|
|
||||||
use unic_langid::LanguageIdentifier;
|
|
||||||
use crate::FluentPlugin;
|
use crate::FluentPlugin;
|
||||||
|
use fluent::{FluentArgs, FluentBundle, FluentResource, FluentValue};
|
||||||
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
||||||
|
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Type, Value};
|
||||||
|
use unic_langid::LanguageIdentifier;
|
||||||
|
|
||||||
pub struct Localize;
|
pub struct Localize;
|
||||||
|
|
||||||
@ -38,7 +36,11 @@ impl SimplePluginCommand for Localize {
|
|||||||
"FTL files to load",
|
"FTL files to load",
|
||||||
Some('f'),
|
Some('f'),
|
||||||
)
|
)
|
||||||
.switch("fallback", "Return message ID if translation not found", Some('F'))
|
.switch(
|
||||||
|
"fallback",
|
||||||
|
"Return message ID if translation not found",
|
||||||
|
Some('F'),
|
||||||
|
)
|
||||||
.category(Category::Strings)
|
.category(Category::Strings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +79,12 @@ impl SimplePluginCommand for Localize {
|
|||||||
let locale_code: String = call.req(1)?;
|
let locale_code: String = call.req(1)?;
|
||||||
|
|
||||||
// Parse locale
|
// Parse locale
|
||||||
let locale: LanguageIdentifier = locale_code.parse()
|
let locale: LanguageIdentifier = locale_code.parse().map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Invalid locale").with_label(format!("Invalid locale '{}': {}", locale_code, e), call.head))?;
|
LabeledError::new("Invalid locale").with_label(
|
||||||
|
format!("Invalid locale '{}': {}", locale_code, e),
|
||||||
|
call.head,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
// Create FluentBundle
|
// Create FluentBundle
|
||||||
let mut bundle = FluentBundle::new(vec![locale.clone()]);
|
let mut bundle = FluentBundle::new(vec![locale.clone()]);
|
||||||
@ -92,7 +98,8 @@ impl SimplePluginCommand for Localize {
|
|||||||
let files = extract_file_list(files_value)?;
|
let files = extract_file_list(files_value)?;
|
||||||
load_from_files(&mut bundle, &files)?;
|
load_from_files(&mut bundle, &files)?;
|
||||||
} else {
|
} else {
|
||||||
return Err(LabeledError::new("Missing argument").with_label("Must provide either --bundle or --files", call.head));
|
return Err(LabeledError::new("Missing argument")
|
||||||
|
.with_label("Must provide either --bundle or --files", call.head));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare arguments for interpolation
|
// Prepare arguments for interpolation
|
||||||
@ -110,32 +117,37 @@ impl SimplePluginCommand for Localize {
|
|||||||
// Return message ID as fallback
|
// Return message ID as fallback
|
||||||
return Ok(Value::string(format!("[[{}]]", message_id), call.head));
|
return Ok(Value::string(format!("[[{}]]", message_id), call.head));
|
||||||
} else {
|
} else {
|
||||||
return Err(LabeledError::new("Message not found").with_label(format!("Message '{}' not found in locale '{}'", message_id, locale_code), call.head));
|
return Err(LabeledError::new("Message not found").with_label(
|
||||||
|
format!(
|
||||||
|
"Message '{}' not found in locale '{}'",
|
||||||
|
message_id, locale_code
|
||||||
|
),
|
||||||
|
call.head,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Format the message
|
// Format the message
|
||||||
let pattern = msg.value()
|
let pattern = msg.value().ok_or_else(|| {
|
||||||
.ok_or_else(|| LabeledError::new("Message has no value").with_label(format!("Message '{}' has no value", message_id), call.head))?;
|
LabeledError::new("Message has no value")
|
||||||
|
.with_label(format!("Message '{}' has no value", message_id), call.head)
|
||||||
|
})?;
|
||||||
|
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
let formatted = bundle.format_pattern(
|
let formatted = bundle.format_pattern(pattern, fluent_args.as_ref(), &mut errors);
|
||||||
pattern,
|
|
||||||
fluent_args.as_ref(),
|
|
||||||
&mut errors
|
|
||||||
);
|
|
||||||
|
|
||||||
// Handle formatting errors
|
// Handle formatting errors
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
let error_msgs: Vec<String> = errors.iter()
|
let error_msgs: Vec<String> = errors.iter().map(|e| format!("{:?}", e)).collect();
|
||||||
.map(|e| format!("{:?}", e))
|
return Err(LabeledError::new("Formatting error").with_label(
|
||||||
.collect();
|
format!(
|
||||||
return Err(LabeledError::new("Formatting error").with_label(format!(
|
|
||||||
"Formatting errors for message '{}': {}",
|
"Formatting errors for message '{}': {}",
|
||||||
message_id,
|
message_id,
|
||||||
error_msgs.join(", ")
|
error_msgs.join(", ")
|
||||||
), call.head));
|
),
|
||||||
|
call.head,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::string(formatted.to_string(), call.head))
|
Ok(Value::string(formatted.to_string(), call.head))
|
||||||
@ -153,7 +165,10 @@ fn load_from_bundle_value(
|
|||||||
load_messages_from_value(bundle, messages_value)?;
|
load_messages_from_value(bundle, messages_value)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(LabeledError::new("Invalid bundle").with_label("Bundle must be a record", nu_protocol::Span::unknown())),
|
_ => {
|
||||||
|
return Err(LabeledError::new("Invalid bundle")
|
||||||
|
.with_label("Bundle must be a record", nu_protocol::Span::unknown()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -172,16 +187,27 @@ fn load_messages_from_value(
|
|||||||
|
|
||||||
// Create a minimal FTL resource from the message
|
// Create a minimal FTL resource from the message
|
||||||
let ftl_content = format!("{} = {}", id, text);
|
let ftl_content = format!("{} = {}", id, text);
|
||||||
let resource = FluentResource::try_new(ftl_content)
|
let resource = FluentResource::try_new(ftl_content).map_err(|_| {
|
||||||
.map_err(|_| LabeledError::new("Invalid FTL").with_label(format!("Invalid FTL for message '{}'", id), nu_protocol::Span::unknown()))?;
|
LabeledError::new("Invalid FTL").with_label(
|
||||||
|
format!("Invalid FTL for message '{}'", id),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
bundle.add_resource(resource)
|
bundle.add_resource(resource).map_err(|_| {
|
||||||
.map_err(|_| LabeledError::new("Failed to add message").with_label(format!("Failed to add message '{}'", id), nu_protocol::Span::unknown()))?;
|
LabeledError::new("Failed to add message").with_label(
|
||||||
|
format!("Failed to add message '{}'", id),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(LabeledError::new("Invalid messages").with_label("Messages must be a list", nu_protocol::Span::unknown())),
|
_ => {
|
||||||
|
return Err(LabeledError::new("Invalid messages")
|
||||||
|
.with_label("Messages must be a list", nu_protocol::Span::unknown()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -191,26 +217,40 @@ fn load_from_files(
|
|||||||
files: &[String],
|
files: &[String],
|
||||||
) -> Result<(), LabeledError> {
|
) -> Result<(), LabeledError> {
|
||||||
for file_path in files {
|
for file_path in files {
|
||||||
let content = std::fs::read_to_string(file_path)
|
let content = std::fs::read_to_string(file_path).map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Read error").with_label(format!("Failed to read '{}': {}", file_path, e), nu_protocol::Span::unknown()))?;
|
LabeledError::new("Read error").with_label(
|
||||||
|
format!("Failed to read '{}': {}", file_path, e),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
let resource = FluentResource::try_new(content)
|
let resource = FluentResource::try_new(content).map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Invalid FTL").with_label(format!("Invalid FTL in '{}': {:?}", file_path, e), nu_protocol::Span::unknown()))?;
|
LabeledError::new("Invalid FTL").with_label(
|
||||||
|
format!("Invalid FTL in '{}': {:?}", file_path, e),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
bundle.add_resource(resource)
|
bundle.add_resource(resource).map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Load error").with_label(format!("Failed to load '{}': {:?}", file_path, e), nu_protocol::Span::unknown()))?;
|
LabeledError::new("Load error").with_label(
|
||||||
|
format!("Failed to load '{}': {:?}", file_path, e),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_file_list(files_value: Value) -> Result<Vec<String>, LabeledError> {
|
fn extract_file_list(files_value: Value) -> Result<Vec<String>, LabeledError> {
|
||||||
match files_value {
|
match files_value {
|
||||||
Value::List { vals, .. } => {
|
Value::List { vals, .. } => vals
|
||||||
vals.iter()
|
.iter()
|
||||||
.map(|v| value_to_string(v))
|
.map(|v| value_to_string(v))
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>(),
|
||||||
}
|
_ => Err(LabeledError::new("Invalid files").with_label(
|
||||||
_ => Err(LabeledError::new("Invalid files").with_label("Files must be a list of strings", nu_protocol::Span::unknown())),
|
"Files must be a list of strings",
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,16 +264,24 @@ fn convert_to_fluent_args(args_value: Value) -> Result<FluentArgs<'static>, Labe
|
|||||||
Value::String { val, .. } => FluentValue::from(val.clone()),
|
Value::String { val, .. } => FluentValue::from(val.clone()),
|
||||||
Value::Int { val, .. } => FluentValue::from(*val as f64),
|
Value::Int { val, .. } => FluentValue::from(*val as f64),
|
||||||
Value::Float { val, .. } => FluentValue::from(*val),
|
Value::Float { val, .. } => FluentValue::from(*val),
|
||||||
_ => return Err(LabeledError::new("Unsupported argument type").with_label(format!(
|
_ => {
|
||||||
|
return Err(LabeledError::new("Unsupported argument type").with_label(
|
||||||
|
format!(
|
||||||
"Unsupported argument type for '{}': {:?}",
|
"Unsupported argument type for '{}': {:?}",
|
||||||
key,
|
key,
|
||||||
value.get_type()
|
value.get_type()
|
||||||
), nu_protocol::Span::unknown())),
|
),
|
||||||
|
nu_protocol::Span::unknown(),
|
||||||
|
))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
fluent_args.set(key.clone(), fluent_value);
|
fluent_args.set(key.clone(), fluent_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(LabeledError::new("Invalid arguments").with_label("Arguments must be a record", nu_protocol::Span::unknown())),
|
_ => {
|
||||||
|
return Err(LabeledError::new("Invalid arguments")
|
||||||
|
.with_label("Arguments must be a record", nu_protocol::Span::unknown()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(fluent_args)
|
Ok(fluent_args)
|
||||||
@ -247,7 +295,7 @@ fn value_to_string(value: &Value) -> Result<String, LabeledError> {
|
|||||||
Value::Bool { val, .. } => Ok(val.to_string()),
|
Value::Bool { val, .. } => Ok(val.to_string()),
|
||||||
_ => Err(LabeledError::new("Type conversion error").with_label(
|
_ => Err(LabeledError::new("Type conversion error").with_label(
|
||||||
format!("Cannot convert {:?} to string", value.get_type()),
|
format!("Cannot convert {:?} to string", value.get_type()),
|
||||||
nu_protocol::Span::unknown()
|
nu_protocol::Span::unknown(),
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,14 +1,13 @@
|
|||||||
mod parse_ftl;
|
mod create_bundle;
|
||||||
mod localize;
|
|
||||||
mod validate_ftl;
|
|
||||||
mod extract_messages;
|
mod extract_messages;
|
||||||
mod list_locales;
|
mod list_locales;
|
||||||
mod create_bundle;
|
mod localize;
|
||||||
|
mod parse_ftl;
|
||||||
|
mod validate_ftl;
|
||||||
|
|
||||||
pub use parse_ftl::ParseFtl;
|
pub use create_bundle::CreateBundle;
|
||||||
pub use localize::Localize;
|
|
||||||
pub use validate_ftl::ValidateFtl;
|
|
||||||
pub use extract_messages::ExtractMessages;
|
pub use extract_messages::ExtractMessages;
|
||||||
pub use list_locales::ListLocales;
|
pub use list_locales::ListLocales;
|
||||||
pub use create_bundle::CreateBundle;
|
pub use localize::Localize;
|
||||||
|
pub use parse_ftl::ParseFtl;
|
||||||
|
pub use validate_ftl::ValidateFtl;
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
|
||||||
use nu_protocol::{
|
|
||||||
Category, LabeledError, Signature, Span, SyntaxShape, Type, Value, record
|
|
||||||
};
|
|
||||||
use fluent_syntax::parser::parse;
|
|
||||||
use fluent_syntax::ast::{Entry, Message, Pattern, PatternElement};
|
|
||||||
use std::fs;
|
|
||||||
use crate::FluentPlugin;
|
use crate::FluentPlugin;
|
||||||
|
use fluent_syntax::ast::{Entry, Message, Pattern, PatternElement};
|
||||||
|
use fluent_syntax::parser::parse;
|
||||||
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
||||||
|
use nu_protocol::{record, Category, LabeledError, Signature, Span, SyntaxShape, Type, Value};
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
pub struct ParseFtl;
|
pub struct ParseFtl;
|
||||||
|
|
||||||
@ -28,13 +26,11 @@ impl SimplePluginCommand for ParseFtl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
|
fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
|
||||||
vec![
|
vec![nu_protocol::Example {
|
||||||
nu_protocol::Example {
|
|
||||||
description: "Parse an FTL file",
|
description: "Parse an FTL file",
|
||||||
example: "fluent-parse locales/en-US/main.ftl",
|
example: "fluent-parse locales/en-US/main.ftl",
|
||||||
result: None,
|
result: None,
|
||||||
},
|
}]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
@ -47,14 +43,21 @@ impl SimplePluginCommand for ParseFtl {
|
|||||||
let file_path: String = call.req(0)?;
|
let file_path: String = call.req(0)?;
|
||||||
|
|
||||||
// Read FTL file
|
// Read FTL file
|
||||||
let ftl_content = fs::read_to_string(&file_path)
|
let ftl_content = fs::read_to_string(&file_path).map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Read error").with_label(format!("Failed to read file '{}': {}", file_path, e), call.head))?;
|
LabeledError::new("Read error").with_label(
|
||||||
|
format!("Failed to read file '{}': {}", file_path, e),
|
||||||
|
call.head,
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
|
||||||
// Parse FTL content
|
// Parse FTL content
|
||||||
let resource = match parse(ftl_content) {
|
let resource = match parse(ftl_content) {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err((_, errors)) => {
|
Err((_, errors)) => {
|
||||||
return Err(LabeledError::new("Parse error").with_label(format!("Failed to parse FTL content: {:?}", errors), call.head));
|
return Err(LabeledError::new("Parse error").with_label(
|
||||||
|
format!("Failed to parse FTL content: {:?}", errors),
|
||||||
|
call.head,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -76,7 +79,10 @@ impl SimplePluginCommand for ParseFtl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_messages_from_resource(resource: &fluent_syntax::ast::Resource<String>, span: Span) -> Result<Vec<Value>, String> {
|
fn extract_messages_from_resource(
|
||||||
|
resource: &fluent_syntax::ast::Resource<String>,
|
||||||
|
span: Span,
|
||||||
|
) -> Result<Vec<Value>, String> {
|
||||||
let mut messages = Vec::new();
|
let mut messages = Vec::new();
|
||||||
|
|
||||||
for entry in &resource.body {
|
for entry in &resource.body {
|
||||||
@ -113,8 +119,16 @@ fn extract_message_info(message: &Message<String>, span: Span) -> Result<Value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract comment if present
|
// Extract comment if present
|
||||||
let comment = message.comment.as_ref()
|
let comment = message
|
||||||
.map(|c| c.content.iter().map(|line| line.trim()).collect::<Vec<_>>().join("\n"))
|
.comment
|
||||||
|
.as_ref()
|
||||||
|
.map(|c| {
|
||||||
|
c.content
|
||||||
|
.iter()
|
||||||
|
.map(|line| line.trim())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n")
|
||||||
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
Ok(Value::record(
|
Ok(Value::record(
|
||||||
@ -129,7 +143,8 @@ fn extract_message_info(message: &Message<String>, span: Span) -> Result<Value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn extract_pattern_text(pattern: &Pattern<String>) -> String {
|
fn extract_pattern_text(pattern: &Pattern<String>) -> String {
|
||||||
pattern.elements
|
pattern
|
||||||
|
.elements
|
||||||
.iter()
|
.iter()
|
||||||
.map(|element| match element {
|
.map(|element| match element {
|
||||||
PatternElement::TextElement { value } => value.to_string(),
|
PatternElement::TextElement { value } => value.to_string(),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
|
||||||
use nu_protocol::{Category, LabeledError, Signature, SyntaxShape, Type, Value, record};
|
|
||||||
use fluent_syntax::parser::parse;
|
|
||||||
use crate::FluentPlugin;
|
use crate::FluentPlugin;
|
||||||
|
use fluent_syntax::parser::parse;
|
||||||
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand, SimplePluginCommand};
|
||||||
|
use nu_protocol::{record, Category, LabeledError, Signature, SyntaxShape, Type, Value};
|
||||||
|
|
||||||
pub struct ValidateFtl;
|
pub struct ValidateFtl;
|
||||||
|
|
||||||
@ -24,13 +24,11 @@ impl SimplePluginCommand for ValidateFtl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
|
fn examples(&self) -> Vec<nu_protocol::Example<'_>> {
|
||||||
vec![
|
vec![nu_protocol::Example {
|
||||||
nu_protocol::Example {
|
|
||||||
description: "Validate an FTL file",
|
description: "Validate an FTL file",
|
||||||
example: "fluent-validate locales/en-US/main.ftl",
|
example: "fluent-validate locales/en-US/main.ftl",
|
||||||
result: None,
|
result: None,
|
||||||
},
|
}]
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
@ -42,8 +40,10 @@ impl SimplePluginCommand for ValidateFtl {
|
|||||||
) -> Result<Value, LabeledError> {
|
) -> Result<Value, LabeledError> {
|
||||||
let file_path: String = call.req(0)?;
|
let file_path: String = call.req(0)?;
|
||||||
|
|
||||||
let content = std::fs::read_to_string(&file_path)
|
let content = std::fs::read_to_string(&file_path).map_err(|e| {
|
||||||
.map_err(|e| LabeledError::new("Read error").with_label(format!("Failed to read '{}': {}", file_path, e), call.head))?;
|
LabeledError::new("Read error")
|
||||||
|
.with_label(format!("Failed to read '{}': {}", file_path, e), call.head)
|
||||||
|
})?;
|
||||||
|
|
||||||
let parse_result = parse(content);
|
let parse_result = parse(content);
|
||||||
let result = match parse_result {
|
let result = match parse_result {
|
||||||
@ -56,7 +56,8 @@ impl SimplePluginCommand for ValidateFtl {
|
|||||||
call.head,
|
call.head,
|
||||||
),
|
),
|
||||||
Err((_resource, errors)) => {
|
Err((_resource, errors)) => {
|
||||||
let error_list: Vec<Value> = errors.iter()
|
let error_list: Vec<Value> = errors
|
||||||
|
.iter()
|
||||||
.map(|err| Value::string(format!("{:?}", err), call.head))
|
.map(|err| Value::string(format!("{:?}", err), call.head))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|||||||
@ -22,4 +22,3 @@ impl Plugin for FluentPlugin {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
933
nu_plugin_hashes/Cargo.lock
generated
933
nu_plugin_hashes/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@ keywords = [
|
|||||||
categories = ["algorithms"]
|
categories = ["algorithms"]
|
||||||
repository = "https://github.com/ArmoredPony/nu_plugin_hashes"
|
repository = "https://github.com/ArmoredPony/nu_plugin_hashes"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
@ -37,9 +37,9 @@ default = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-cmd-base = "0.109.1"
|
nu-cmd-base = "0.111.0"
|
||||||
nu-plugin = "0.109.1"
|
nu-plugin = "0.111.0"
|
||||||
nu-protocol = "0.109.1"
|
nu-protocol = "0.111.0"
|
||||||
digest = "0.10.7"
|
digest = "0.10.7"
|
||||||
|
|
||||||
[dependencies.ascon-hash]
|
[dependencies.ascon-hash]
|
||||||
@ -215,9 +215,8 @@ optional = true
|
|||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dev-dependencies.nu-plugin-test-support]
|
[dev-dependencies]
|
||||||
version = "0.109.1"
|
nu-plugin-test-support = "0.111.0"
|
||||||
path = "../nushell/crates/nu-plugin-test-support"
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
strip = true
|
strip = true
|
||||||
|
|||||||
@ -1,225 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nu_plugin_hashes"
|
|
||||||
description = "A Nushell plugin that adds 63 cryptographic hash functions from Hashes project"
|
|
||||||
keywords = [
|
|
||||||
"nu",
|
|
||||||
"plugin",
|
|
||||||
"hash",
|
|
||||||
]
|
|
||||||
categories = ["algorithms"]
|
|
||||||
repository = "https://github.com/ArmoredPony/nu_plugin_hashes"
|
|
||||||
license = "MIT"
|
|
||||||
version = "0.109.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = [
|
|
||||||
"ascon-hash",
|
|
||||||
"belt-hash",
|
|
||||||
"blake2",
|
|
||||||
"blake3",
|
|
||||||
"fsb",
|
|
||||||
"gost94",
|
|
||||||
"groestl",
|
|
||||||
"jh",
|
|
||||||
"md2",
|
|
||||||
"md4",
|
|
||||||
"ripemd",
|
|
||||||
"sha1",
|
|
||||||
"sha2",
|
|
||||||
"sha3",
|
|
||||||
"shabal",
|
|
||||||
"skein",
|
|
||||||
"sm3",
|
|
||||||
"streebog",
|
|
||||||
"tiger",
|
|
||||||
"whirlpool",
|
|
||||||
]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
nu-cmd-base = "0.109.1"
|
|
||||||
nu-plugin = "0.109.1"
|
|
||||||
nu-protocol = "0.109.1"
|
|
||||||
digest = "0.10.7"
|
|
||||||
|
|
||||||
[dependencies.ascon-hash]
|
|
||||||
version = "0.3.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.belt-hash]
|
|
||||||
version = "0.1.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.blake2]
|
|
||||||
version = "0.10.6"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.blake3]
|
|
||||||
version = "1.8.2"
|
|
||||||
optional = true
|
|
||||||
default-features = false
|
|
||||||
features = [
|
|
||||||
"std",
|
|
||||||
"traits-preview",
|
|
||||||
]
|
|
||||||
|
|
||||||
[dependencies.fsb]
|
|
||||||
version = "0.1.3"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.gost94]
|
|
||||||
version = "0.10.4"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.groestl]
|
|
||||||
version = "0.10.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.jh]
|
|
||||||
version = "0.1.0"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.md2]
|
|
||||||
version = "0.10.2"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.md4]
|
|
||||||
version = "0.10.2"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.ripemd]
|
|
||||||
version = "0.1.3"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.sha1]
|
|
||||||
version = "0.10.6"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.sha2]
|
|
||||||
version = "0.10.9"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.sha3]
|
|
||||||
version = "0.10.8"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.shabal]
|
|
||||||
version = "0.4.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.skein]
|
|
||||||
version = "0.1.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.sm3]
|
|
||||||
version = "0.4.2"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.streebog]
|
|
||||||
version = "0.10.2"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.tiger]
|
|
||||||
version = "0.2.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dependencies.whirlpool]
|
|
||||||
version = "0.10.4"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
digest = "0.10.7"
|
|
||||||
|
|
||||||
[build-dependencies.ascon-hash]
|
|
||||||
version = "0.3.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.belt-hash]
|
|
||||||
version = "0.1.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.blake2]
|
|
||||||
version = "0.10.6"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.blake3]
|
|
||||||
version = "1.8.2"
|
|
||||||
optional = true
|
|
||||||
default-features = false
|
|
||||||
features = [
|
|
||||||
"std",
|
|
||||||
"traits-preview",
|
|
||||||
]
|
|
||||||
|
|
||||||
[build-dependencies.fsb]
|
|
||||||
version = "0.1.3"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.gost94]
|
|
||||||
version = "0.10.4"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.groestl]
|
|
||||||
version = "0.10.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.jh]
|
|
||||||
version = "0.1.0"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.md2]
|
|
||||||
version = "0.10.2"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.md4]
|
|
||||||
version = "0.10.2"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.ripemd]
|
|
||||||
version = "0.1.3"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.sha1]
|
|
||||||
version = "0.10.6"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.sha2]
|
|
||||||
version = "0.10.9"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.sha3]
|
|
||||||
version = "0.10.8"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.shabal]
|
|
||||||
version = "0.4.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.skein]
|
|
||||||
version = "0.1.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.sm3]
|
|
||||||
version = "0.4.2"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.streebog]
|
|
||||||
version = "0.10.2"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.tiger]
|
|
||||||
version = "0.2.1"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[build-dependencies.whirlpool]
|
|
||||||
version = "0.10.4"
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
[dev-dependencies.nu-plugin-test-support]
|
|
||||||
version = "0.109.0"
|
|
||||||
path = "../nushell/crates/nu-plugin-test-support"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
strip = true
|
|
||||||
lto = true
|
|
||||||
codegen-units = 1
|
|
||||||
@ -13,20 +13,25 @@ crate.
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
To install this plugin with all algorithms available run
|
To install this plugin with all algorithms available run
|
||||||
```nu
|
|
||||||
|
```nushell
|
||||||
|
nu
|
||||||
cargo install nu_plugin_hashes
|
cargo install nu_plugin_hashes
|
||||||
plugin add ($env.CARGO_HOME ++ /bin/nu_plugin_hashes)
|
plugin add ($env.CARGO_HOME ++ /bin/nu_plugin_hashes)
|
||||||
```
|
```
|
||||||
|
|
||||||
or on Windows
|
or on Windows
|
||||||
```nu
|
|
||||||
|
```nushell
|
||||||
|
nu
|
||||||
cargo install nu_plugin_hashes
|
cargo install nu_plugin_hashes
|
||||||
plugin add ($env.CARGO_HOME ++ /bin/nu_plugin_hashes.exe)
|
plugin add ($env.CARGO_HOME ++ /bin/nu_plugin_hashes.exe)
|
||||||
```
|
```
|
||||||
|
|
||||||
After loading the plugin, execute `help hash` to list newly added commands
|
After loading the plugin, execute `help hash` to list newly added commands
|
||||||
|
|
||||||
```nu
|
```nushell
|
||||||
|
nu
|
||||||
~> help hash
|
~> help hash
|
||||||
Apply hash function.
|
Apply hash function.
|
||||||
|
|
||||||
@ -47,12 +52,16 @@ Subcommands:
|
|||||||
|
|
||||||
If you only need some algorithms, disable default features and select only
|
If you only need some algorithms, disable default features and select only
|
||||||
those you need
|
those you need
|
||||||
```nu
|
|
||||||
|
```nushell
|
||||||
|
nu
|
||||||
cargo install nu_plugin_hashes --no-default-features --features sha2,streebog
|
cargo install nu_plugin_hashes --no-default-features --features sha2,streebog
|
||||||
```
|
```
|
||||||
|
|
||||||
Then check what's installed
|
Then check what's installed
|
||||||
```nu
|
|
||||||
|
```nushell
|
||||||
|
nu
|
||||||
~> help hash
|
~> help hash
|
||||||
Apply hash function.
|
Apply hash function.
|
||||||
|
|
||||||
|
|||||||
@ -467,12 +467,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
let hashers_generated_path = Path::new(&out_dir).join("hashers_generated.rs");
|
let hashers_generated_path = Path::new(&out_dir).join("hashers_generated.rs");
|
||||||
let commands_generated_path =
|
let commands_generated_path = Path::new(&out_dir).join("commands_generated.rs");
|
||||||
Path::new(&out_dir).join("commands_generated.rs");
|
let mut hashers_generated_file = std::fs::File::create(hashers_generated_path).unwrap();
|
||||||
let mut hashers_generated_file =
|
let mut commands_generated_file = std::fs::File::create(commands_generated_path).unwrap();
|
||||||
std::fs::File::create(hashers_generated_path).unwrap();
|
|
||||||
let mut commands_generated_file =
|
|
||||||
std::fs::File::create(commands_generated_path).unwrap();
|
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
hashers_generated_file,
|
hashers_generated_file,
|
||||||
@ -494,13 +491,10 @@ pub fn commands() -> Vec<Box<dyn PluginCommand<Plugin = HashesPlugin>>> {{
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
for mut hasher_impl_meta in hasher_impls {
|
for mut hasher_impl_meta in hasher_impls {
|
||||||
let feature_name =
|
let feature_name = hasher_impl_meta.crate_name.replace("-", "_").to_uppercase();
|
||||||
hasher_impl_meta.crate_name.replace("-", "_").to_uppercase();
|
|
||||||
if std::env::var(format!("CARGO_FEATURE_{feature_name}")).is_ok() {
|
if std::env::var(format!("CARGO_FEATURE_{feature_name}")).is_ok() {
|
||||||
hashers_generated_file
|
hashers_generated_file.write_all(build_impl_str(&mut hasher_impl_meta).as_bytes())?;
|
||||||
.write_all(build_impl_str(&mut hasher_impl_meta).as_bytes())?;
|
hashers_generated_file.write_all(build_test_str(&hasher_impl_meta).as_bytes())?;
|
||||||
hashers_generated_file
|
|
||||||
.write_all(build_test_str(&hasher_impl_meta).as_bytes())?;
|
|
||||||
|
|
||||||
let crate_name = hasher_impl_meta.crate_name;
|
let crate_name = hasher_impl_meta.crate_name;
|
||||||
let hasher_type_name = hasher_impl_meta.hasher_type_name;
|
let hasher_type_name = hasher_impl_meta.hasher_type_name;
|
||||||
@ -586,13 +580,11 @@ impl Hasher for {crate_name}::{hasher_type_name} {{
|
|||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
",
|
",
|
||||||
hash
|
hash.iter()
|
||||||
.iter()
|
|
||||||
.map(|b| format!("{b:02x?}"))
|
.map(|b| format!("{b:02x?}"))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(""),
|
.join(""),
|
||||||
hash
|
hash.iter()
|
||||||
.iter()
|
|
||||||
.map(|b| format!("0x{b:02x?}"))
|
.map(|b| format!("0x{b:02x?}"))
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(",")
|
.join(",")
|
||||||
|
|||||||
@ -7,21 +7,11 @@
|
|||||||
use std::{io::Write, marker::PhantomData, ops::Not};
|
use std::{io::Write, marker::PhantomData, ops::Not};
|
||||||
|
|
||||||
use digest::{Digest, Output};
|
use digest::{Digest, Output};
|
||||||
use nu_cmd_base::input_handler::{operate, CmdArgument};
|
use nu_cmd_base::input_handler::{CmdArgument, operate};
|
||||||
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::CellPath,
|
Category, Example, IntoPipelineData, LabeledError, PipelineData, ShellError, Signature, Span,
|
||||||
Category,
|
SyntaxShape, Type, Value, ast::CellPath,
|
||||||
Example,
|
|
||||||
IntoPipelineData,
|
|
||||||
LabeledError,
|
|
||||||
PipelineData,
|
|
||||||
ShellError,
|
|
||||||
Signature,
|
|
||||||
Span,
|
|
||||||
SyntaxShape,
|
|
||||||
Type,
|
|
||||||
Value,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::HashesPlugin;
|
use crate::HashesPlugin;
|
||||||
@ -42,10 +32,7 @@ impl<H: Hasher> Default for GenericHasher<H> {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: format!("hash {}", H::name()),
|
name: format!("hash {}", H::name()),
|
||||||
description: format!(
|
description: format!("Hash a value using the {} hash algorithm.", H::name()),
|
||||||
"Hash a value using the {} hash algorithm.",
|
|
||||||
H::name()
|
|
||||||
),
|
|
||||||
_hasher: PhantomData,
|
_hasher: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use nu_plugin::{serve_plugin, MsgPackSerializer};
|
use nu_plugin::{MsgPackSerializer, serve_plugin};
|
||||||
use nu_plugin_hashes::HashesPlugin;
|
use nu_plugin_hashes::HashesPlugin;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
569
nu_plugin_highlight/Cargo.lock
generated
569
nu_plugin_highlight/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nu_plugin_highlight"
|
name = "nu_plugin_highlight"
|
||||||
version = "1.4.7+0.105.2"
|
version = "0.111.0"
|
||||||
authors = ["Tim 'Piepmatz' Hesse"]
|
authors = ["Tim 'Piepmatz' Hesse"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
repository = "https://github.com/cptpiepmatz/nu-plugin-highlight"
|
repository = "https://github.com/cptpiepmatz/nu-plugin-highlight"
|
||||||
@ -26,9 +26,9 @@ version = "0.26"
|
|||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = "0.109.1"
|
nu-plugin = "0.111.0"
|
||||||
nu-protocol = "0.109.1"
|
nu-protocol = "0.111.0"
|
||||||
nu-path = "0.109.1"
|
nu-path = "0.111.0"
|
||||||
nu-ansi-term = "0.50"
|
nu-ansi-term = "0.50"
|
||||||
ansi_colours = "1"
|
ansi_colours = "1"
|
||||||
mime_guess = "2"
|
mime_guess = "2"
|
||||||
|
|||||||
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
## About
|
## About
|
||||||
|
|
||||||
`nu-plugin-highlight` is a plugin for [Nushell](https://www.nushell.sh) that
|
`nu-plugin-highlight` is a plugin for [Nushell](https://www.nushell.sh) that
|
||||||
provides syntax highlighting for source code.
|
provides syntax highlighting for source code.
|
||||||
It uses the [`syntect`](https://crates.io/crates/syntect) library for syntax
|
It uses the [`syntect`](https://crates.io/crates/syntect) library for syntax
|
||||||
@ -26,9 +26,12 @@ access to its ready-to-use assets.
|
|||||||
Custom themes can be loaded too.
|
Custom themes can be loaded too.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
The `highlight` command can be used for syntax highlighting source code.
|
The `highlight` command can be used for syntax highlighting source code.
|
||||||
Here are a few examples:
|
Here are a few examples:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
# Highlight a Markdown file by guessing the type from the pipeline metadata
|
# Highlight a Markdown file by guessing the type from the pipeline metadata
|
||||||
open README.md | highlight
|
open README.md | highlight
|
||||||
|
|
||||||
@ -49,11 +52,13 @@ highlight --list-themes
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
- `language <string>`:
|
- `language <string>`:
|
||||||
This is an optional parameter that can be used to specify the language or file
|
This is an optional parameter that can be used to specify the language or file
|
||||||
extension to aid language detection.
|
extension to aid language detection.
|
||||||
|
|
||||||
### Flags
|
### Flags
|
||||||
|
|
||||||
- `-h, --help`:
|
- `-h, --help`:
|
||||||
Display the help message for the highlight command.
|
Display the help message for the highlight command.
|
||||||
|
|
||||||
@ -64,18 +69,23 @@ highlight --list-themes
|
|||||||
List all possible themes.
|
List all possible themes.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The plugin can be configured using the
|
The plugin can be configured using the
|
||||||
[`$env.config.plugins.highlight`](https://github.com/nushell/nushell/pull/10955)
|
[`$env.config.plugins.highlight`](https://github.com/nushell/nushell/pull/10955)
|
||||||
variable.
|
variable.
|
||||||
|
|
||||||
### `true_colors`
|
### `true_colors`
|
||||||
|
|
||||||
Enable or disable true colors (24-bit).
|
Enable or disable true colors (24-bit).
|
||||||
By default, this is enabled.
|
By default, this is enabled.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
$env.config.plugins.highlight.true_colors = true
|
$env.config.plugins.highlight.true_colors = true
|
||||||
```
|
```
|
||||||
|
|
||||||
### `theme`
|
### `theme`
|
||||||
|
|
||||||
Set a theme to use.
|
Set a theme to use.
|
||||||
The default theme depends on the operating system.
|
The default theme depends on the operating system.
|
||||||
Use `highlight --list-themes | where default == true` to see your default theme.
|
Use `highlight --list-themes | where default == true` to see your default theme.
|
||||||
@ -83,24 +93,31 @@ Setting this environment variable should allow
|
|||||||
`highlight --list-themes | where id == $env.config.plugins.highlight.theme` to
|
`highlight --list-themes | where id == $env.config.plugins.highlight.theme` to
|
||||||
result in a single row with your selected theme.
|
result in a single row with your selected theme.
|
||||||
If you get no results, you have set an invalid theme.
|
If you get no results, you have set an invalid theme.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
$env.config.plugins.highlight.theme = ansi
|
$env.config.plugins.highlight.theme = ansi
|
||||||
```
|
```
|
||||||
|
|
||||||
### `custom_themes`
|
### `custom_themes`
|
||||||
|
|
||||||
Set a directory to load custom themes from.
|
Set a directory to load custom themes from.
|
||||||
Using `synctect`s theme loader, you can load custom themes in the `.tmtheme`
|
Using `synctect`s theme loader, you can load custom themes in the `.tmtheme`
|
||||||
format from a directory that is passed as this configuration value.
|
format from a directory that is passed as this configuration value.
|
||||||
```nushell
|
|
||||||
|
```toml
|
||||||
|
nushell
|
||||||
$env.config.plugins.highlight.custom_themes = ~/.nu/highlight/themes
|
$env.config.plugins.highlight.custom_themes = ~/.nu/highlight/themes
|
||||||
```
|
```
|
||||||
|
|
||||||
## Plugin Installation
|
## Plugin Installation
|
||||||
|
|
||||||
Installing and registering the `nu-plugin-highlight` is a straightforward
|
Installing and registering the `nu-plugin-highlight` is a straightforward
|
||||||
process.
|
process.
|
||||||
Follow these steps:
|
Follow these steps:
|
||||||
|
|
||||||
1. Install the plugin from crates.io using cargo:
|
1. Install the plugin from crates.io using cargo:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
cargo install nu_plugin_highlight
|
cargo install nu_plugin_highlight
|
||||||
```
|
```
|
||||||
@ -108,6 +125,7 @@ Follow these steps:
|
|||||||
2. Restart your terminal session to ensure the newly installed plugin is recognized.
|
2. Restart your terminal session to ensure the newly installed plugin is recognized.
|
||||||
|
|
||||||
3. Find path of your installation:
|
3. Find path of your installation:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
which nu_plugin_highlight
|
which nu_plugin_highlight
|
||||||
```
|
```
|
||||||
@ -115,6 +133,7 @@ Follow these steps:
|
|||||||
4. Register the plugin with Nushell:
|
4. Register the plugin with Nushell:
|
||||||
|
|
||||||
If you are using a version **lower** than **0.93.0**, use `register` instead of `plugin add`.
|
If you are using a version **lower** than **0.93.0**, use `register` instead of `plugin add`.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
plugin add path/to/the/plugin/binary
|
plugin add path/to/the/plugin/binary
|
||||||
```
|
```
|
||||||
@ -124,6 +143,7 @@ Follow these steps:
|
|||||||
Tip: You can simply restart the shell or terminal. When nushell starts, it loads all plugins.
|
Tip: You can simply restart the shell or terminal. When nushell starts, it loads all plugins.
|
||||||
|
|
||||||
If you are using a version **lower** than **0.93.0**, you do **not need** to do this.
|
If you are using a version **lower** than **0.93.0**, you do **not need** to do this.
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
plugin use highlight
|
plugin use highlight
|
||||||
```
|
```
|
||||||
@ -131,10 +151,12 @@ Follow these steps:
|
|||||||
After registering, the plugin is available as part of your set of commands:
|
After registering, the plugin is available as part of your set of commands:
|
||||||
|
|
||||||
```nushell
|
```nushell
|
||||||
|
nushell
|
||||||
help commands | where command_type == "plugin"
|
help commands | where command_type == "plugin"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Version Numbering
|
## Version Numbering
|
||||||
|
|
||||||
Starting with version `v1.1.0`, the version number of `nu-plugin-highlight`
|
Starting with version `v1.1.0`, the version number of `nu-plugin-highlight`
|
||||||
incorporates the version number of its dependency, `nu-plugin`.
|
incorporates the version number of its dependency, `nu-plugin`.
|
||||||
This is denoted in the format `v1.1.0+0.90.1`, where `v1.1.0` refers to the
|
This is denoted in the format `v1.1.0+0.90.1`, where `v1.1.0` refers to the
|
||||||
@ -142,5 +164,6 @@ version of `nu-plugin-highlight` and `0.90.1` refers to the version of the
|
|||||||
`nu-plugin` dependency.
|
`nu-plugin` dependency.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
`nu_plugin_highlight` is licensed under the MIT License.
|
`nu_plugin_highlight` is licensed under the MIT License.
|
||||||
See [LICENSE](LICENSE) for more information.
|
See [LICENSE](LICENSE) for more information.
|
||||||
@ -2,11 +2,11 @@ use std::ops::Deref;
|
|||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use bat::assets::HighlightingAssets;
|
use bat::assets::HighlightingAssets;
|
||||||
use bat::theme::{default_theme, ColorScheme};
|
use bat::theme::{ColorScheme, default_theme};
|
||||||
|
use syntect::LoadingError;
|
||||||
use syntect::easy::HighlightLines;
|
use syntect::easy::HighlightLines;
|
||||||
use syntect::highlighting::ThemeSet;
|
use syntect::highlighting::ThemeSet;
|
||||||
use syntect::parsing::{SyntaxReference, SyntaxSet};
|
use syntect::parsing::{SyntaxReference, SyntaxSet};
|
||||||
use syntect::LoadingError;
|
|
||||||
|
|
||||||
use crate::terminal;
|
use crate::terminal;
|
||||||
use crate::theme::{ListThemes, ThemeDescription};
|
use crate::theme::{ListThemes, ThemeDescription};
|
||||||
@ -17,7 +17,7 @@ const SYNTAX_SET: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/syntax_set.b
|
|||||||
pub struct Highlighter {
|
pub struct Highlighter {
|
||||||
syntax_set: SyntaxSet,
|
syntax_set: SyntaxSet,
|
||||||
highlighting_assets: HighlightingAssets,
|
highlighting_assets: HighlightingAssets,
|
||||||
custom_themes: Option<ThemeSet>
|
custom_themes: Option<ThemeSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Highlighter {
|
impl Highlighter {
|
||||||
@ -27,13 +27,13 @@ impl Highlighter {
|
|||||||
syntax_set: syntect::dumps::from_uncompressed_data(SYNTAX_SET)
|
syntax_set: syntect::dumps::from_uncompressed_data(SYNTAX_SET)
|
||||||
.expect("Failed to load syntax set"),
|
.expect("Failed to load syntax set"),
|
||||||
highlighting_assets: HighlightingAssets::from_binary(),
|
highlighting_assets: HighlightingAssets::from_binary(),
|
||||||
custom_themes: None
|
custom_themes: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn custom_themes_from_folder(
|
pub fn custom_themes_from_folder(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: impl AsRef<Path>
|
path: impl AsRef<Path>,
|
||||||
) -> Result<(), LoadingError> {
|
) -> Result<(), LoadingError> {
|
||||||
let path = nu_path::expand_to_real_path(path);
|
let path = nu_path::expand_to_real_path(path);
|
||||||
self.custom_themes = Some(ThemeSet::load_from_folder(path)?);
|
self.custom_themes = Some(ThemeSet::load_from_folder(path)?);
|
||||||
@ -53,7 +53,7 @@ impl Highlighter {
|
|||||||
id: t_id.to_owned(),
|
id: t_id.to_owned(),
|
||||||
name: theme.name.clone(),
|
name: theme.name.clone(),
|
||||||
author: theme.author.clone(),
|
author: theme.author.clone(),
|
||||||
default: default_theme_id == t_id
|
default: default_theme_id == t_id,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
@ -64,7 +64,7 @@ impl Highlighter {
|
|||||||
id: id.to_owned(),
|
id: id.to_owned(),
|
||||||
name: theme.name.clone(),
|
name: theme.name.clone(),
|
||||||
author: theme.author.clone(),
|
author: theme.author.clone(),
|
||||||
default: default_theme_id == id
|
default: default_theme_id == id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ impl Highlighter {
|
|||||||
input: &str,
|
input: &str,
|
||||||
language: Option<&str>,
|
language: Option<&str>,
|
||||||
theme: Option<&str>,
|
theme: Option<&str>,
|
||||||
true_colors: bool
|
true_colors: bool,
|
||||||
) -> String {
|
) -> String {
|
||||||
let syntax_set = &self.syntax_set;
|
let syntax_set = &self.syntax_set;
|
||||||
let syntax_ref: Option<&SyntaxReference> = match language {
|
let syntax_ref: Option<&SyntaxReference> = match language {
|
||||||
@ -118,7 +118,7 @@ impl Highlighter {
|
|||||||
.or_else(|| syntax_set.find_syntax_by_extension(&language_lowercase))
|
.or_else(|| syntax_set.find_syntax_by_extension(&language_lowercase))
|
||||||
.or_else(|| syntax_set.find_syntax_by_extension(&language_capitalized))
|
.or_else(|| syntax_set.find_syntax_by_extension(&language_capitalized))
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None,
|
||||||
};
|
};
|
||||||
let syntax_ref = syntax_ref
|
let syntax_ref = syntax_ref
|
||||||
.or(syntax_set.find_syntax_by_first_line(input))
|
.or(syntax_set.find_syntax_by_first_line(input))
|
||||||
@ -126,7 +126,7 @@ impl Highlighter {
|
|||||||
|
|
||||||
let theme_id = match theme {
|
let theme_id = match theme {
|
||||||
None => default_theme(ColorScheme::Dark),
|
None => default_theme(ColorScheme::Dark),
|
||||||
Some(theme) => theme
|
Some(theme) => theme,
|
||||||
};
|
};
|
||||||
let theme = self
|
let theme = self
|
||||||
.custom_themes
|
.custom_themes
|
||||||
@ -143,10 +143,11 @@ impl Highlighter {
|
|||||||
// insert a newline in between lines, this is necessary for bats syntax set
|
// insert a newline in between lines, this is necessary for bats syntax set
|
||||||
let l = match i == line_count - 1 {
|
let l = match i == line_count - 1 {
|
||||||
false => format!("{}\n", l.trim_end()),
|
false => format!("{}\n", l.trim_end()),
|
||||||
true => l.trim_end().to_owned()
|
true => l.trim_end().to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let styled_lines = highlighter.highlight_line(&l, syntax_set)
|
let styled_lines = highlighter
|
||||||
|
.highlight_line(&l, syntax_set)
|
||||||
.expect("Failed to highlight line");
|
.expect("Failed to highlight line");
|
||||||
styled_lines
|
styled_lines
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use nu_plugin::{serve_plugin, MsgPackSerializer};
|
use nu_plugin::{MsgPackSerializer, serve_plugin};
|
||||||
use plugin::HighlightPlugin;
|
use plugin::HighlightPlugin;
|
||||||
|
|
||||||
mod highlight;
|
mod highlight;
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use nu_plugin::{EngineInterface, EvaluatedCall, Plugin, PluginCommand};
|
|||||||
use nu_protocol::shell_error::io::IoError;
|
use nu_protocol::shell_error::io::IoError;
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
Category, DataSource, ErrorLabel, Example, FromValue, IntoValue, LabeledError, PipelineData,
|
Category, DataSource, ErrorLabel, Example, FromValue, IntoValue, LabeledError, PipelineData,
|
||||||
PipelineMetadata, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value
|
PipelineMetadata, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||||
};
|
};
|
||||||
use syntect::LoadingError;
|
use syntect::LoadingError;
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ impl Plugin for HighlightPlugin {
|
|||||||
struct Config {
|
struct Config {
|
||||||
pub theme: Option<Spanned<String>>,
|
pub theme: Option<Spanned<String>>,
|
||||||
pub true_colors: Option<bool>,
|
pub true_colors: Option<bool>,
|
||||||
pub custom_themes: Option<Spanned<PathBuf>>
|
pub custom_themes: Option<Spanned<PathBuf>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Highlight;
|
struct Highlight;
|
||||||
@ -46,13 +46,13 @@ impl PluginCommand for Highlight {
|
|||||||
.optional(
|
.optional(
|
||||||
"language",
|
"language",
|
||||||
SyntaxShape::String,
|
SyntaxShape::String,
|
||||||
"language or file extension to help language detection"
|
"language or file extension to help language detection",
|
||||||
)
|
)
|
||||||
.named(
|
.named(
|
||||||
"theme",
|
"theme",
|
||||||
SyntaxShape::String,
|
SyntaxShape::String,
|
||||||
"them used for highlighting",
|
"them used for highlighting",
|
||||||
Some('t')
|
Some('t'),
|
||||||
)
|
)
|
||||||
.switch("list-themes", "list all possible themes", None)
|
.switch("list-themes", "list all possible themes", None)
|
||||||
.category(Category::Strings)
|
.category(Category::Strings)
|
||||||
@ -66,8 +66,8 @@ impl PluginCommand for Highlight {
|
|||||||
(String::from("author"), Type::String),
|
(String::from("author"), Type::String),
|
||||||
(String::from("default"), Type::Bool),
|
(String::from("default"), Type::Bool),
|
||||||
]
|
]
|
||||||
.into()
|
.into(),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ impl PluginCommand for Highlight {
|
|||||||
_plugin: &Self::Plugin,
|
_plugin: &Self::Plugin,
|
||||||
engine: &EngineInterface,
|
engine: &EngineInterface,
|
||||||
call: &EvaluatedCall,
|
call: &EvaluatedCall,
|
||||||
input: PipelineData
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, LabeledError> {
|
) -> Result<PipelineData, LabeledError> {
|
||||||
let mut highlighter = Highlighter::new();
|
let mut highlighter = Highlighter::new();
|
||||||
|
|
||||||
@ -96,17 +96,17 @@ impl PluginCommand for Highlight {
|
|||||||
err,
|
err,
|
||||||
custom_themes_path.span,
|
custom_themes_path.span,
|
||||||
custom_themes_path.item,
|
custom_themes_path.item,
|
||||||
"Error while loading custom themes"
|
"Error while loading custom themes",
|
||||||
)
|
),
|
||||||
)))
|
)));
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Err(labeled_error(
|
return Err(labeled_error(
|
||||||
err,
|
err,
|
||||||
"Error while loading custom themes",
|
"Error while loading custom themes",
|
||||||
custom_themes_path.span,
|
custom_themes_path.span,
|
||||||
None
|
None,
|
||||||
))
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -117,12 +117,13 @@ impl PluginCommand for Highlight {
|
|||||||
.transpose()?
|
.transpose()?
|
||||||
.or(config.theme);
|
.or(config.theme);
|
||||||
if let Some(theme) = &theme
|
if let Some(theme) = &theme
|
||||||
&& !highlighter.is_valid_theme(&theme.item) {
|
&& !highlighter.is_valid_theme(&theme.item)
|
||||||
|
{
|
||||||
return Err(labeled_error(
|
return Err(labeled_error(
|
||||||
"use `highlight --list-themes` to list all themes",
|
"use `highlight --list-themes` to list all themes",
|
||||||
format!("Unknown passed theme {:?}", &theme.item),
|
format!("Unknown passed theme {:?}", &theme.item),
|
||||||
theme.span,
|
theme.span,
|
||||||
None
|
None,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let theme = theme.map(|spanned| spanned.item);
|
let theme = theme.map(|spanned| spanned.item);
|
||||||
@ -152,35 +153,35 @@ impl PluginCommand for Highlight {
|
|||||||
fn examples(&self) -> Vec<Example<'_>> {
|
fn examples(&self) -> Vec<Example<'_>> {
|
||||||
const fn example<'e>(description: &'e str, example: &'e str) -> Example<'e>
|
const fn example<'e>(description: &'e str, example: &'e str) -> Example<'e>
|
||||||
where
|
where
|
||||||
'e: 'static
|
'e: 'static,
|
||||||
{
|
{
|
||||||
Example {
|
Example {
|
||||||
example,
|
example,
|
||||||
description,
|
description,
|
||||||
result: None
|
result: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
example(
|
example(
|
||||||
"Highlight a Markdown file by guessing the type from the pipeline metadata",
|
"Highlight a Markdown file by guessing the type from the pipeline metadata",
|
||||||
"open README.md | highlight"
|
"open README.md | highlight",
|
||||||
),
|
),
|
||||||
example(
|
example(
|
||||||
"Highlight a toml file by its file extension",
|
"Highlight a toml file by its file extension",
|
||||||
"open Cargo.toml -r | echo $in | highlight toml"
|
"open Cargo.toml -r | echo $in | highlight toml",
|
||||||
),
|
),
|
||||||
example(
|
example(
|
||||||
"Highlight a rust file by programming language",
|
"Highlight a rust file by programming language",
|
||||||
"open src/main.rs | echo $in | highlight Rust"
|
"open src/main.rs | echo $in | highlight Rust",
|
||||||
),
|
),
|
||||||
example(
|
example(
|
||||||
"Highlight a bash script by inferring the language (needs shebang)",
|
"Highlight a bash script by inferring the language (needs shebang)",
|
||||||
"open example.sh | echo $in | highlight"
|
"open example.sh | echo $in | highlight",
|
||||||
),
|
),
|
||||||
example(
|
example(
|
||||||
"Highlight a toml file with another theme",
|
"Highlight a toml file with another theme",
|
||||||
"open Cargo.toml -r | highlight -t ansi"
|
"open Cargo.toml -r | highlight -t ansi",
|
||||||
),
|
),
|
||||||
example("List all available themes", "highlight --list-themes"),
|
example("List all available themes", "highlight --list-themes"),
|
||||||
]
|
]
|
||||||
@ -189,7 +190,7 @@ impl PluginCommand for Highlight {
|
|||||||
|
|
||||||
fn language_hint(
|
fn language_hint(
|
||||||
call: &EvaluatedCall,
|
call: &EvaluatedCall,
|
||||||
metadata: Option<&PipelineMetadata>
|
metadata: Option<&PipelineMetadata>,
|
||||||
) -> Result<Option<String>, ShellError> {
|
) -> Result<Option<String>, ShellError> {
|
||||||
// first use passed argument
|
// first use passed argument
|
||||||
let arg = call.opt(0)?.map(String::from_value).transpose()?;
|
let arg = call.opt(0)?.map(String::from_value).transpose()?;
|
||||||
@ -206,15 +207,14 @@ fn language_hint(
|
|||||||
"x-toml" => Some("toml".to_string()),
|
"x-toml" => Some("toml".to_string()),
|
||||||
"x-nuscript" | "x-nushell" | "x-nuon" => Some("nushell".to_string()),
|
"x-nuscript" | "x-nushell" | "x-nuon" => Some("nushell".to_string()),
|
||||||
s if s.starts_with("x-") => None, // we cannot be sure about this type,
|
s if s.starts_with("x-") => None, // we cannot be sure about this type,
|
||||||
_ => Some(sub_type)
|
_ => Some(sub_type),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// as last resort, try to use the extension of data source
|
// as last resort, try to use the extension of data source
|
||||||
let data_source = || -> Option<String> {
|
let data_source = || -> Option<String> {
|
||||||
let data_source = &metadata?.data_source;
|
let data_source = &metadata?.data_source;
|
||||||
let DataSource::FilePath(path) = data_source
|
let DataSource::FilePath(path) = data_source else {
|
||||||
else {
|
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let extension = path.extension()?.to_string_lossy();
|
let extension = path.extension()?.to_string_lossy();
|
||||||
@ -229,20 +229,20 @@ fn labeled_error(
|
|||||||
msg: impl ToString,
|
msg: impl ToString,
|
||||||
label: impl ToString,
|
label: impl ToString,
|
||||||
span: Span,
|
span: Span,
|
||||||
inner: impl Into<Option<ShellError>>
|
inner: impl Into<Option<ShellError>>,
|
||||||
) -> LabeledError {
|
) -> LabeledError {
|
||||||
LabeledError {
|
LabeledError {
|
||||||
msg: msg.to_string(),
|
msg: msg.to_string(),
|
||||||
labels: Box::new(vec![ErrorLabel {
|
labels: Box::new(vec![ErrorLabel {
|
||||||
text: label.to_string(),
|
text: label.to_string(),
|
||||||
span
|
span,
|
||||||
}]),
|
}]),
|
||||||
code: None,
|
code: None,
|
||||||
url: None,
|
url: None,
|
||||||
help: None,
|
help: None,
|
||||||
inner: match inner.into() {
|
inner: match inner.into() {
|
||||||
Some(inner) => Box::new(vec![inner.into()]),
|
Some(inner) => Box::new(vec![inner.into()]),
|
||||||
None => Box::new(vec![])
|
None => Box::new(vec![]),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ pub struct ThemeDescription {
|
|||||||
pub id: String,
|
pub id: String,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub author: Option<String>,
|
pub author: Option<String>,
|
||||||
pub default: bool
|
pub default: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List of theme descriptions.
|
/// List of theme descriptions.
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
# Nushell syntax highlight for sublime text
|
# Nushell syntax highlight for sublime text
|
||||||
|
|
||||||
- Just copied matlab syntax file and modified it for nushell
|
- Just copied matlab syntax file and modified it for nushell
|
||||||
- Use nushell lsp language server (need lsp sublime package)
|
- Use nushell lsp language server (need lsp sublime package)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. In sublime text install the LSP package.
|
1. In sublime text install the LSP package.
|
||||||
2. After cloning and cd-ing into the directory, in nushell run (tested in Ubuntu 20.04):
|
2. After cloning and cd-ing into the directory, in nushell run (tested in Ubuntu 20.04):
|
||||||
```nu
|
|
||||||
|
```nushell
|
||||||
|
nu
|
||||||
ls
|
ls
|
||||||
| find -v README & export & color
|
| find -v README & export & color
|
||||||
| get name
|
| get name
|
||||||
@ -14,11 +18,14 @@ ls
|
|||||||
cp -f $file (~/.config/sublime-text/Packages/User | path expand)
|
cp -f $file (~/.config/sublime-text/Packages/User | path expand)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
3. In sublime, open `Preferences > Customize Color Scheme` and add the contents of `sublime-color-scheme`. Modify to your liking.
|
1. In sublime, open `Preferences > Customize Color Scheme` and add the contents of `sublime-color-scheme`. Modify to your liking.
|
||||||
|
|
||||||
## Update commands
|
## Update commands
|
||||||
|
|
||||||
If you need to update nushell functions or add your custom commands and aliases, run:
|
If you need to update nushell functions or add your custom commands and aliases, run:
|
||||||
```nu
|
|
||||||
|
```nushell
|
||||||
|
nu
|
||||||
chmod +x export.nu
|
chmod +x export.nu
|
||||||
./export.nu
|
./export.nu
|
||||||
```
|
```
|
||||||
468
nu_plugin_image/Cargo.lock
generated
468
nu_plugin_image/Cargo.lock
generated
@ -90,12 +90,6 @@ version = "0.2.21"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "android-tzdata"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
@ -232,7 +226,7 @@ dependencies = [
|
|||||||
"num-traits",
|
"num-traits",
|
||||||
"pastey",
|
"pastey",
|
||||||
"rayon",
|
"rayon",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
"v_frame",
|
"v_frame",
|
||||||
"y4m",
|
"y4m",
|
||||||
]
|
]
|
||||||
@ -273,7 +267,7 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
"rustc-hash",
|
"rustc-hash 1.1.0",
|
||||||
"shlex",
|
"shlex",
|
||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
@ -432,18 +426,17 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.41"
|
version = "0.4.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
|
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"pure-rust-locales",
|
"pure-rust-locales",
|
||||||
"serde",
|
"serde",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-link 0.1.3",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -486,6 +479,7 @@ dependencies = [
|
|||||||
"anstyle",
|
"anstyle",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
"strsim",
|
"strsim",
|
||||||
|
"terminal_size",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -597,7 +591,7 @@ dependencies = [
|
|||||||
"document-features",
|
"document-features",
|
||||||
"mio",
|
"mio",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"rustix 1.0.7",
|
"rustix",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-mio",
|
"signal-hook-mio",
|
||||||
"winapi",
|
"winapi",
|
||||||
@ -675,6 +669,17 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "displaydoc"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.104",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "doctest-file"
|
name = "doctest-file"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -768,9 +773,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fancy-regex"
|
name = "fancy-regex"
|
||||||
version = "0.16.2"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "998b056554fbe42e03ae0e152895cd1a7e1002aec800fdc6635d20270260c46f"
|
checksum = "72cf461f865c862bb7dc573f643dd6a2b6842f7c30b07882b56bd148cc2761b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit-set",
|
"bit-set",
|
||||||
"regex-automata",
|
"regex-automata",
|
||||||
@ -817,10 +822,55 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "fluent"
|
||||||
version = "0.1.5"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "8137a6d5a2c50d6b0ebfcb9aaa91a28154e0a70605f112d30cb0cd4a78670477"
|
||||||
|
dependencies = [
|
||||||
|
"fluent-bundle",
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluent-bundle"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "01203cb8918f5711e73891b347816d932046f95f54207710bda99beaeb423bf4"
|
||||||
|
dependencies = [
|
||||||
|
"fluent-langneg",
|
||||||
|
"fluent-syntax",
|
||||||
|
"intl-memoizer",
|
||||||
|
"intl_pluralrules",
|
||||||
|
"rustc-hash 2.1.1",
|
||||||
|
"self_cell",
|
||||||
|
"smallvec",
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluent-langneg"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7eebbe59450baee8282d71676f3bfed5689aeab00b27545e83e5f14b1195e8b0"
|
||||||
|
dependencies = [
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fluent-syntax"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54f0d287c53ffd184d04d8677f590f4ac5379785529e5e08b1c8083acdd5c198"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
@ -885,9 +935,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.4"
|
version = "0.16.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
@ -1033,12 +1083,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.11.4"
|
version = "2.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
|
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"equivalent",
|
"equivalent",
|
||||||
"hashbrown 0.15.4",
|
"hashbrown 0.16.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1054,9 +1104,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "interprocess"
|
name = "interprocess"
|
||||||
version = "2.2.3"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d941b405bd2322993887859a8ee6ac9134945a24ec5ec763a8a962fc64dfec2d"
|
checksum = "6be5e5c847dbdb44564bd85294740d031f4f8aeb3464e5375ef7141f7538db69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"doctest-file",
|
"doctest-file",
|
||||||
"libc",
|
"libc",
|
||||||
@ -1065,6 +1115,25 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "intl-memoizer"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "310da2e345f5eb861e7a07ee182262e94975051db9e4223e909ba90f392f163f"
|
||||||
|
dependencies = [
|
||||||
|
"type-map",
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "intl_pluralrules"
|
||||||
|
version = "7.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "078ea7b7c29a2b4df841a7f6ac8775ff6074020c6776d48491ce2268e068f972"
|
||||||
|
dependencies = [
|
||||||
|
"unic-langid",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inventory"
|
name = "inventory"
|
||||||
version = "0.3.20"
|
version = "0.3.20"
|
||||||
@ -1176,9 +1245,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.174"
|
version = "0.2.178"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libflate"
|
name = "libflate"
|
||||||
@ -1251,12 +1320,6 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "linux-raw-sys"
|
|
||||||
version = "0.4.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
@ -1296,11 +1359,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru"
|
name = "lru"
|
||||||
version = "0.12.5"
|
version = "0.16.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38"
|
checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown 0.15.4",
|
"hashbrown 0.16.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1315,12 +1378,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mach2"
|
name = "mach2"
|
||||||
version = "0.4.3"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44"
|
checksum = "dae608c151f68243f2b000364e1f7b186d9c29845f7d2d85bd31b9ad77ad552b"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matrixmultiply"
|
name = "matrixmultiply"
|
||||||
@ -1344,9 +1404,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.5"
|
version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miette"
|
name = "miette"
|
||||||
@ -1483,9 +1543,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-derive-value"
|
name = "nu-derive-value"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1465d2d3ada6004cb6689f269a08c70ba81056231e2b5392d1e0ccf5825f81cb"
|
checksum = "d71958b54c367bda033f7dcc4a73b61972fb52323f71a1e3533e290fa67148d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heck",
|
"heck",
|
||||||
"proc-macro-error2",
|
"proc-macro-error2",
|
||||||
@ -1496,9 +1556,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-engine"
|
name = "nu-engine"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3b777faf7c5180fe5d7f67d83c44fd14138d91f2938a36494ed6ac66b7160f3"
|
checksum = "d41b3e3e2d25c30741a0761856258e22624c0d60064e4f0e12f86202a451d492"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
"log",
|
"log",
|
||||||
@ -1511,25 +1571,25 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-experimental"
|
name = "nu-experimental"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73dd212a1afdad646a38c00579a0988264880aeb97fee820b349a28cdcc04df2"
|
checksum = "f328fa0531bdf49c2dc0312b40cb780e3d74e0d3dbb15d508469a5ae4cfd8d8f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-glob"
|
name = "nu-glob"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "15aa2c17078926f14e393b4b708e69f228cb6fd4c81136839bde82772bdde1b5"
|
checksum = "01ee787f61353c9c90581ddf4c0602a07b991cdd06c97dac8b6d323a1a52c43a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-path"
|
name = "nu-path"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dde9d8ba26f62c07176c0237a36f38ce964ab3a0dcfb6aab1feea7515d1c6594"
|
checksum = "c01d110cb931acf56237ce572e5b156e8e1134227c90deeffb92eedda9482c23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs",
|
"dirs",
|
||||||
"omnipath",
|
"omnipath",
|
||||||
@ -1539,9 +1599,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin"
|
name = "nu-plugin"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ea1fbfd41b2f5c967675fc948831e03be67d91c6b8e18a60f3445113fe6548c"
|
checksum = "c322531b1a7d6338c5ead1f454294f46babf8c99cd4716311cab1e88ba52b154"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
@ -1550,14 +1610,14 @@ dependencies = [
|
|||||||
"nu-plugin-protocol",
|
"nu-plugin-protocol",
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
"nu-utils",
|
"nu-utils",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-core"
|
name = "nu-plugin-core"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd2410648c2c38cf9359595ffcf281d9d60a81c0580ff07f7c7d42bed414f3a1"
|
checksum = "38ee792aeb0d37e0ed55ca4304e434eece497914e27ae42616a8bb973f5d2720"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"interprocess",
|
"interprocess",
|
||||||
"log",
|
"log",
|
||||||
@ -1566,14 +1626,14 @@ dependencies = [
|
|||||||
"rmp-serde",
|
"rmp-serde",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"windows 0.62.2",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-plugin-protocol"
|
name = "nu-plugin-protocol"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "27de26da922261dff8103a811879228c55749a1b7b0e573b639c609a0651a01e"
|
checksum = "7725f341428db16dbef4392970de32705abc77ee80a902572c8da811dade3564"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nu-protocol",
|
"nu-protocol",
|
||||||
"nu-utils",
|
"nu-utils",
|
||||||
@ -1585,9 +1645,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-protocol"
|
name = "nu-protocol"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "038943300ca9de0924fef1c795a7dd16ffc67105629477cf163e8ee6bad95ea6"
|
checksum = "f1c0e58cbeb46cbfd40156e6f4b9f90e4a77e774ca863fa158867a4726aab1d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"brotli",
|
"brotli",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -1616,18 +1676,18 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
"typetag",
|
"typetag",
|
||||||
"web-time",
|
"web-time",
|
||||||
"windows 0.62.2",
|
"windows",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-system"
|
name = "nu-system"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46be734cc9b19e09a9665769e14360e13e6978490056ba5c8bfad7dd0537ea83"
|
checksum = "62fe7847b65edbe362a0fcb67dedfab9fd7370e89c0313f7cb7d0a7ab8f9834b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
@ -1639,15 +1699,16 @@ dependencies = [
|
|||||||
"ntapi",
|
"ntapi",
|
||||||
"procfs",
|
"procfs",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
|
"uucore",
|
||||||
"web-time",
|
"web-time",
|
||||||
"windows 0.62.2",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu-utils"
|
name = "nu-utils"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f8eb43c29cc5bce85f87defdadc2cca964fa434d808af37036a7cb78f3c68e9"
|
checksum = "df85a8a4bb28c84d5f7c096c02c859ac454dfac59fd0296ab5eb6ed86619219e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteyarn",
|
"byteyarn",
|
||||||
"crossterm",
|
"crossterm",
|
||||||
@ -1668,7 +1729,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nu_plugin_image"
|
name = "nu_plugin_image"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph",
|
"ab_glyph",
|
||||||
"ansi_colours",
|
"ansi_colours",
|
||||||
@ -1790,18 +1851,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-core-foundation"
|
name = "objc2-core-foundation"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
|
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc2-io-kit"
|
name = "objc2-io-kit"
|
||||||
version = "0.3.1"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
|
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
@ -1831,6 +1892,15 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_display"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad5fd71b79026fb918650dde6d125000a233764f1c2f1659a1c71118e33ea08f"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width 0.2.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_pipe"
|
name = "os_pipe"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
@ -1982,23 +2052,22 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "procfs"
|
name = "procfs"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f"
|
checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chrono",
|
"chrono",
|
||||||
"flate2",
|
"flate2",
|
||||||
"hex",
|
|
||||||
"procfs-core",
|
"procfs-core",
|
||||||
"rustix 0.38.44",
|
"rustix",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "procfs-core"
|
name = "procfs-core"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec"
|
checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -2026,9 +2095,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pure-rust-locales"
|
name = "pure-rust-locales"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1190fd18ae6ce9e137184f207593877e70f39b015040156b1e05081cdfe3733a"
|
checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pwd"
|
name = "pwd"
|
||||||
@ -2178,7 +2247,7 @@ dependencies = [
|
|||||||
"rand 0.9.2",
|
"rand 0.9.2",
|
||||||
"rand_chacha 0.9.0",
|
"rand_chacha 0.9.0",
|
||||||
"simd_helpers",
|
"simd_helpers",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
"v_frame",
|
"v_frame",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
@ -2247,23 +2316,23 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.16",
|
"getrandom 0.2.16",
|
||||||
"libredox",
|
"libredox",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref-cast"
|
name = "ref-cast"
|
||||||
version = "1.0.24"
|
version = "1.0.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf"
|
checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ref-cast-impl",
|
"ref-cast-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ref-cast-impl"
|
name = "ref-cast-impl"
|
||||||
version = "1.0.24"
|
version = "1.0.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
|
checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2327,11 +2396,10 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmp-serde"
|
name = "rmp-serde"
|
||||||
version = "1.3.0"
|
version = "1.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
|
checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
|
||||||
"rmp",
|
"rmp",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@ -2343,17 +2411,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustc-hash"
|
||||||
version = "0.38.44"
|
version = "2.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"errno",
|
|
||||||
"libc",
|
|
||||||
"linux-raw-sys 0.4.15",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
@ -2364,7 +2425,7 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.9.4",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2395,6 +2456,12 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "self_cell"
|
||||||
|
version = "1.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b12e76d157a900eb52e81bc6e9f3069344290341720e9178cde2407113ac8d89"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.26"
|
version = "1.0.26"
|
||||||
@ -2433,14 +2500,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.140"
|
version = "1.0.149"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ryu",
|
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_core",
|
||||||
|
"zmij",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2574,9 +2642,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum"
|
name = "strum"
|
||||||
version = "0.26.3"
|
version = "0.27.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strum_macros"
|
name = "strum_macros"
|
||||||
@ -2643,16 +2711,16 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sysinfo"
|
name = "sysinfo"
|
||||||
version = "0.37.2"
|
version = "0.38.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16607d5caffd1c07ce073528f9ed972d88db15dd44023fa57142963be3feb11f"
|
checksum = "92ab6a2f8bfe508deb3c6406578252e491d299cbbf3bc0529ecc3313aee4a52f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
"ntapi",
|
"ntapi",
|
||||||
"objc2-core-foundation",
|
"objc2-core-foundation",
|
||||||
"objc2-io-kit",
|
"objc2-io-kit",
|
||||||
"windows 0.61.3",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2685,7 +2753,7 @@ version = "0.4.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed"
|
checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustix 1.0.7",
|
"rustix",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2710,11 +2778,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.12"
|
version = "2.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl 2.0.12",
|
"thiserror-impl 2.0.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2730,9 +2798,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "2.0.12"
|
version = "2.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2793,12 +2861,32 @@ dependencies = [
|
|||||||
"time-core",
|
"time-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinystr"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"serde_core",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ttf-parser"
|
name = "ttf-parser"
|
||||||
version = "0.25.1"
|
version = "0.25.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "type-map"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb30dbbd9036155e74adad6812e9898d03ec374946234fbcebd5dfc7b9187b90"
|
||||||
|
dependencies = [
|
||||||
|
"rustc-hash 2.1.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typeid"
|
name = "typeid"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
@ -2836,10 +2924,28 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unic-langid"
|
||||||
version = "2.8.1"
|
version = "0.9.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
checksum = "a28ba52c9b05311f4f6e62d5d9d46f094bd6e84cb8df7b3ef952748d752a7d05"
|
||||||
|
dependencies = [
|
||||||
|
"unic-langid-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-langid-impl"
|
||||||
|
version = "0.9.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dce1bf08044d4b7a94028c93786f8566047edc11110595914de93362559bc658"
|
||||||
|
dependencies = [
|
||||||
|
"tinystr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
@ -2877,6 +2983,35 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uucore"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b157ba598d7f7ed06f6dbc62999edb9d730b4d3fb58e503d8ad6d5fbe1e04391"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"fluent",
|
||||||
|
"fluent-bundle",
|
||||||
|
"fluent-syntax",
|
||||||
|
"libc",
|
||||||
|
"nix",
|
||||||
|
"os_display",
|
||||||
|
"thiserror 2.0.18",
|
||||||
|
"unic-langid",
|
||||||
|
"uucore_procs",
|
||||||
|
"wild",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uucore_procs"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "daa291a52608ac5a2f8539e119666e021baa6b8c01f22f02ed201bbae54cbbc0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "v_frame"
|
name = "v_frame"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -3018,6 +3153,15 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d"
|
checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wild"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3131afc8c575281e1e80f36ed6a092aa502c08b18ed7524e86fbbb12bb410e1"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
@ -3049,38 +3193,16 @@ version = "0.4.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows"
|
|
||||||
version = "0.61.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
|
||||||
dependencies = [
|
|
||||||
"windows-collections 0.2.0",
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
"windows-future 0.2.1",
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
"windows-numerics 0.2.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows"
|
name = "windows"
|
||||||
version = "0.62.2"
|
version = "0.62.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-collections 0.3.2",
|
"windows-collections",
|
||||||
"windows-core 0.62.2",
|
"windows-core 0.62.2",
|
||||||
"windows-future 0.3.2",
|
"windows-future",
|
||||||
"windows-numerics 0.3.1",
|
"windows-numerics",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-collections"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
|
||||||
dependencies = [
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3118,17 +3240,6 @@ dependencies = [
|
|||||||
"windows-strings 0.5.1",
|
"windows-strings 0.5.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-future"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
|
||||||
dependencies = [
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
"windows-threading 0.1.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-future"
|
name = "windows-future"
|
||||||
version = "0.3.2"
|
version = "0.3.2"
|
||||||
@ -3137,7 +3248,7 @@ checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core 0.62.2",
|
"windows-core 0.62.2",
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
"windows-threading 0.2.1",
|
"windows-threading",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3174,16 +3285,6 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-numerics"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
|
||||||
dependencies = [
|
|
||||||
"windows-core 0.61.2",
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-numerics"
|
name = "windows-numerics"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -3298,15 +3399,6 @@ dependencies = [
|
|||||||
"windows_x86_64_msvc 0.53.0",
|
"windows_x86_64_msvc 0.53.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-threading"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link 0.1.3",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-threading"
|
name = "windows-threading"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
@ -3468,6 +3560,28 @@ dependencies = [
|
|||||||
"syn 2.0.104",
|
"syn 2.0.104",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerofrom"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec"
|
||||||
|
version = "0.11.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zmij"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd"
|
name = "zstd"
|
||||||
version = "0.13.3"
|
version = "0.13.3"
|
||||||
|
|||||||
@ -11,8 +11,8 @@ vte = "0.15.0"
|
|||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
slog-term = "2.9.2"
|
slog-term = "2.9.2"
|
||||||
slog-async = "2.8.0"
|
slog-async = "2.8.0"
|
||||||
nu-plugin = "0.109.1"
|
nu-plugin = "0.111.0"
|
||||||
nu-protocol = "0.109.1"
|
nu-protocol = "0.111.0"
|
||||||
|
|
||||||
[dependencies.clap]
|
[dependencies.clap]
|
||||||
features = ["derive"]
|
features = ["derive"]
|
||||||
@ -52,4 +52,4 @@ license = "MIT"
|
|||||||
name = "nu_plugin_image"
|
name = "nu_plugin_image"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/FMotalleb/nu_plugin_image"
|
repository = "https://github.com/FMotalleb/nu_plugin_image"
|
||||||
version = "0.109.1"
|
version = "0.111.0"
|
||||||
|
|||||||
@ -19,7 +19,8 @@ The `to png` command converts an ANSI string into a PNG image. Customizable font
|
|||||||
|
|
||||||
#### 📌 Usage
|
#### 📌 Usage
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
> to png {flags} (output-path)
|
> to png {flags} (output-path)
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -55,7 +56,8 @@ The `to png` command converts an ANSI string into a PNG image. Customizable font
|
|||||||
|
|
||||||
#### 📊 Example: Convert ANSI String to PNG with Custom Theme
|
#### 📊 Example: Convert ANSI String to PNG with Custom Theme
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
> to png --theme "xterm" --custom-theme-fg "#FF00FF" --custom-theme-bg "#00000000" output.png
|
> to png --theme "xterm" --custom-theme-fg "#FF00FF" --custom-theme-bg "#00000000" output.png
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -67,7 +69,8 @@ The `from png` command converts an image into its corresponding ANSI text repres
|
|||||||
|
|
||||||
#### 📌 Usage
|
#### 📌 Usage
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
> from png {flags}
|
> from png {flags}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -80,7 +83,8 @@ The `from png` command converts an image into its corresponding ANSI text repres
|
|||||||
|
|
||||||
#### 📊 Example: Convert PNG Image to ANSI Text
|
#### 📊 Example: Convert PNG Image to ANSI Text
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
> from png --width 80 --height 20 image.png
|
> from png --width 80 --height 20 image.png
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -92,14 +96,16 @@ The `from png` command converts an image into its corresponding ANSI text repres
|
|||||||
|
|
||||||
This method automatically handles dependencies and features.
|
This method automatically handles dependencies and features.
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
git clone https://github.com/FMotalleb/nu_plugin_image.git
|
git clone https://github.com/FMotalleb/nu_plugin_image.git
|
||||||
nupm install --path nu_plugin_image -f
|
nupm install --path nu_plugin_image -f
|
||||||
```
|
```
|
||||||
|
|
||||||
### 🛠️ Manual Compilation
|
### 🛠️ Manual Compilation
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
git clone https://github.com/FMotalleb/nu_plugin_image.git
|
git clone https://github.com/FMotalleb/nu_plugin_image.git
|
||||||
cd nu_plugin_image
|
cd nu_plugin_image
|
||||||
cargo build -r
|
cargo build -r
|
||||||
@ -108,8 +114,8 @@ plugin add target/release/nu_plugin_image
|
|||||||
|
|
||||||
### 📦 Install via Cargo (using git)
|
### 📦 Install via Cargo (using git)
|
||||||
|
|
||||||
```bash
|
```rust
|
||||||
|
bash
|
||||||
cargo install --git https://github.com/FMotalleb/nu_plugin_image.git
|
cargo install --git https://github.com/FMotalleb/nu_plugin_image.git
|
||||||
plugin add ~/.cargo/bin/nu_plugin_image
|
plugin add ~/.cargo/bin/nu_plugin_image
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -73,7 +73,9 @@ fn load_u32(call: &EvaluatedCall, flag_name: &str) -> Result<u32, LabeledError>
|
|||||||
.map_err(|e| make_params_err(e.to_string(), call.head))?;
|
.map_err(|e| make_params_err(e.to_string(), call.head))?;
|
||||||
int_val
|
int_val
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|err: std::num::TryFromIntError| make_params_err(err.to_string(), call.head))
|
.map_err(|err: std::num::TryFromIntError| {
|
||||||
|
make_params_err(err.to_string(), call.head)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
_ => Err(make_params_err(
|
_ => Err(make_params_err(
|
||||||
format!("value of `{flag_name}` is not an integer"),
|
format!("value of `{flag_name}` is not an integer"),
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 11216da7174f88a7d5b3ce04fea3cd14bcde8d8c
|
Subproject commit 97e7365a5a917cca6559ea8e66063a4242dc2605
|
||||||
697
nu_plugin_kms/Cargo.lock
generated
697
nu_plugin_kms/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nu_plugin_kms"
|
name = "nu_plugin_kms"
|
||||||
version = "0.1.0"
|
version = "0.111.0"
|
||||||
authors = ["Jesus Perez <jesus@librecloud.online>"]
|
authors = ["Jesus Perez <jesus@librecloud.online>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Nushell plugin for KMS operations (RustyVault, Age, Cosmian)"
|
description = "Nushell plugin for KMS operations (RustyVault, Age, Cosmian)"
|
||||||
@ -8,8 +8,8 @@ repository = "https://github.com/provisioning/nu_plugin_kms"
|
|||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nu-plugin = "0.109.1"
|
nu-plugin = "0.111.0"
|
||||||
nu-protocol = "0.109.1"
|
nu-protocol = "0.111.0"
|
||||||
rusty_vault = "0.2.1"
|
rusty_vault = "0.2.1"
|
||||||
age = "0.11"
|
age = "0.11"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
@ -32,6 +32,5 @@ default-features = false
|
|||||||
version = "1.48"
|
version = "1.48"
|
||||||
features = ["full"]
|
features = ["full"]
|
||||||
|
|
||||||
[dev-dependencies.nu-plugin-test-support]
|
[dev-dependencies]
|
||||||
version = "0.109.1"
|
nu-plugin-test-support = "0.111.0"
|
||||||
path = "../nushell/crates/nu-plugin-test-support"
|
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "nu_plugin_kms"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Jesus Perez <jesus@librecloud.online>"]
|
|
||||||
edition = "2021"
|
|
||||||
description = "Nushell plugin for KMS operations (RustyVault, Age, Cosmian)"
|
|
||||||
repository = "https://github.com/provisioning/nu_plugin_kms"
|
|
||||||
license = "MIT"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
nu-plugin = "0.109.1"
|
|
||||||
nu-protocol = "0.109.1"
|
|
||||||
rusty_vault = "0.2.1"
|
|
||||||
age = "0.11"
|
|
||||||
base64 = "0.22"
|
|
||||||
serde_json = "1.0"
|
|
||||||
tempfile = "3.23"
|
|
||||||
|
|
||||||
[dependencies.serde]
|
|
||||||
version = "1.0"
|
|
||||||
features = ["derive"]
|
|
||||||
|
|
||||||
[dependencies.reqwest]
|
|
||||||
version = "0.12"
|
|
||||||
features = [
|
|
||||||
"json",
|
|
||||||
"rustls-tls",
|
|
||||||
]
|
|
||||||
default-features = false
|
|
||||||
|
|
||||||
[dependencies.tokio]
|
|
||||||
version = "1.48"
|
|
||||||
features = ["full"]
|
|
||||||
|
|
||||||
[dev-dependencies.nu-plugin-test-support]
|
|
||||||
version = "0.109.0"
|
|
||||||
path = "../nushell/crates/nu-plugin-test-support"
|
|
||||||
@ -18,7 +18,8 @@ Nushell plugin for KMS operations with multiple backends.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
cargo build --release
|
cargo build --release
|
||||||
plugin add target/release/nu_plugin_kms
|
plugin add target/release/nu_plugin_kms
|
||||||
```
|
```
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -182,7 +182,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_kms_error_with_source() {
|
fn test_kms_error_with_source() {
|
||||||
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "key file not found");
|
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "key file not found");
|
||||||
let error = KmsError::with_source(KmsErrorKind::KeyNotFound, "failed to load key", io_error);
|
let error =
|
||||||
|
KmsError::with_source(KmsErrorKind::KeyNotFound, "failed to load key", io_error);
|
||||||
assert!(error.to_string().contains("caused by"));
|
assert!(error.to_string().contains("caused by"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -209,7 +209,8 @@ pub fn encrypt_age(data: &[u8], recipient_str: &str) -> Result<String, String> {
|
|||||||
.parse::<age::x25519::Recipient>()
|
.parse::<age::x25519::Recipient>()
|
||||||
.map_err(|e| format!("Invalid Age recipient: {}", e))?;
|
.map_err(|e| format!("Invalid Age recipient: {}", e))?;
|
||||||
|
|
||||||
let encryptor = age::Encryptor::with_recipients(std::iter::once(&recipient as &dyn age::Recipient))
|
let encryptor =
|
||||||
|
age::Encryptor::with_recipients(std::iter::once(&recipient as &dyn age::Recipient))
|
||||||
.map_err(|_| "Failed to create Age encryptor".to_string())?;
|
.map_err(|_| "Failed to create Age encryptor".to_string())?;
|
||||||
|
|
||||||
let mut encrypted = vec![];
|
let mut encrypted = vec![];
|
||||||
@ -513,9 +514,7 @@ pub async fn decrypt_aws_kms(_key_id: &str, ciphertext: &str) -> Result<Vec<u8>,
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| format!("JSON parse error: {}", e))?;
|
.map_err(|e| format!("JSON parse error: {}", e))?;
|
||||||
|
|
||||||
let plaintext_b64 = result["Plaintext"]
|
let plaintext_b64 = result["Plaintext"].as_str().ok_or("Missing Plaintext")?;
|
||||||
.as_str()
|
|
||||||
.ok_or("Missing Plaintext")?;
|
|
||||||
|
|
||||||
general_purpose::STANDARD
|
general_purpose::STANDARD
|
||||||
.decode(plaintext_b64)
|
.decode(plaintext_b64)
|
||||||
@ -523,7 +522,10 @@ pub async fn decrypt_aws_kms(_key_id: &str, ciphertext: &str) -> Result<Vec<u8>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generate data key using AWS KMS
|
/// Generate data key using AWS KMS
|
||||||
pub async fn generate_data_key_aws(key_id: &str, key_spec: &str) -> Result<(String, String), String> {
|
pub async fn generate_data_key_aws(
|
||||||
|
key_id: &str,
|
||||||
|
key_spec: &str,
|
||||||
|
) -> Result<(String, String), String> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
let kms_url = std::env::var("AWS_KMS_ENDPOINT")
|
let kms_url = std::env::var("AWS_KMS_ENDPOINT")
|
||||||
@ -649,7 +651,10 @@ pub async fn generate_data_key_vault(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/v1/transit/datakey/plaintext/{}", addr, key_name))
|
.post(format!(
|
||||||
|
"{}/v1/transit/datakey/plaintext/{}",
|
||||||
|
addr, key_name
|
||||||
|
))
|
||||||
.header("X-Vault-Token", token)
|
.header("X-Vault-Token", token)
|
||||||
.json(&serde_json::json!({
|
.json(&serde_json::json!({
|
||||||
"bits": bits,
|
"bits": bits,
|
||||||
@ -685,16 +690,12 @@ pub fn check_backend_available(backend_name: &str) -> bool {
|
|||||||
"rustyvault" => {
|
"rustyvault" => {
|
||||||
std::env::var("RUSTYVAULT_ADDR").is_ok() && std::env::var("RUSTYVAULT_TOKEN").is_ok()
|
std::env::var("RUSTYVAULT_ADDR").is_ok() && std::env::var("RUSTYVAULT_TOKEN").is_ok()
|
||||||
}
|
}
|
||||||
"age" => {
|
"age" => std::env::var("AGE_RECIPIENT").is_ok() || std::env::var("AGE_IDENTITY").is_ok(),
|
||||||
std::env::var("AGE_RECIPIENT").is_ok() || std::env::var("AGE_IDENTITY").is_ok()
|
|
||||||
}
|
|
||||||
"aws" => {
|
"aws" => {
|
||||||
std::env::var("AWS_ACCESS_KEY_ID").is_ok()
|
std::env::var("AWS_ACCESS_KEY_ID").is_ok()
|
||||||
&& std::env::var("AWS_SECRET_ACCESS_KEY").is_ok()
|
&& std::env::var("AWS_SECRET_ACCESS_KEY").is_ok()
|
||||||
}
|
}
|
||||||
"vault" => {
|
"vault" => std::env::var("VAULT_ADDR").is_ok() && std::env::var("VAULT_TOKEN").is_ok(),
|
||||||
std::env::var("VAULT_ADDR").is_ok() && std::env::var("VAULT_TOKEN").is_ok()
|
|
||||||
}
|
|
||||||
"cosmian" => std::env::var("KMS_HTTP_URL").is_ok(),
|
"cosmian" => std::env::var("KMS_HTTP_URL").is_ok(),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,14 +169,15 @@ impl SimplePluginCommand for KmsEncrypt {
|
|||||||
helpers::encrypt_age(data.as_bytes(), recipient)
|
helpers::encrypt_age(data.as_bytes(), recipient)
|
||||||
.map_err(|e| LabeledError::new(e))?
|
.map_err(|e| LabeledError::new(e))?
|
||||||
}
|
}
|
||||||
helpers::Backend::AwsKms { ref key_id } => {
|
helpers::Backend::AwsKms { ref key_id } => runtime.block_on(async {
|
||||||
runtime.block_on(async {
|
|
||||||
helpers::encrypt_aws_kms(key_id, data.as_bytes())
|
helpers::encrypt_aws_kms(key_id, data.as_bytes())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| LabeledError::new(e))
|
.map_err(|e| LabeledError::new(e))
|
||||||
})?
|
})?,
|
||||||
}
|
helpers::Backend::Vault {
|
||||||
helpers::Backend::Vault { ref addr, ref token } => {
|
ref addr,
|
||||||
|
ref token,
|
||||||
|
} => {
|
||||||
let key_name = key.unwrap_or_else(|| "provisioning-main".to_string());
|
let key_name = key.unwrap_or_else(|| "provisioning-main".to_string());
|
||||||
runtime.block_on(async {
|
runtime.block_on(async {
|
||||||
helpers::encrypt_vault(addr, token, &key_name, data.as_bytes())
|
helpers::encrypt_vault(addr, token, &key_name, data.as_bytes())
|
||||||
@ -321,14 +322,15 @@ impl SimplePluginCommand for KmsDecrypt {
|
|||||||
})?;
|
})?;
|
||||||
helpers::decrypt_age(&encrypted, identity_path).map_err(|e| LabeledError::new(e))?
|
helpers::decrypt_age(&encrypted, identity_path).map_err(|e| LabeledError::new(e))?
|
||||||
}
|
}
|
||||||
helpers::Backend::AwsKms { ref key_id } => {
|
helpers::Backend::AwsKms { ref key_id } => runtime.block_on(async {
|
||||||
runtime.block_on(async {
|
|
||||||
helpers::decrypt_aws_kms(key_id, &encrypted)
|
helpers::decrypt_aws_kms(key_id, &encrypted)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| LabeledError::new(e))
|
.map_err(|e| LabeledError::new(e))
|
||||||
})?
|
})?,
|
||||||
}
|
helpers::Backend::Vault {
|
||||||
helpers::Backend::Vault { ref addr, ref token } => {
|
ref addr,
|
||||||
|
ref token,
|
||||||
|
} => {
|
||||||
let key_name = key.unwrap_or_else(|| "provisioning-main".to_string());
|
let key_name = key.unwrap_or_else(|| "provisioning-main".to_string());
|
||||||
runtime.block_on(async {
|
runtime.block_on(async {
|
||||||
helpers::decrypt_vault(addr, token, &key_name, &encrypted)
|
helpers::decrypt_vault(addr, token, &key_name, &encrypted)
|
||||||
@ -463,20 +465,19 @@ impl SimplePluginCommand for KmsGenerateKey {
|
|||||||
.map(|(secret, public)| (secret, public))
|
.map(|(secret, public)| (secret, public))
|
||||||
.map_err(|e| LabeledError::new(e))?
|
.map_err(|e| LabeledError::new(e))?
|
||||||
}
|
}
|
||||||
helpers::Backend::AwsKms { ref key_id } => {
|
helpers::Backend::AwsKms { ref key_id } => runtime.block_on(async {
|
||||||
runtime.block_on(async {
|
|
||||||
helpers::generate_data_key_aws(key_id, &key_spec)
|
helpers::generate_data_key_aws(key_id, &key_spec)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| LabeledError::new(e))
|
.map_err(|e| LabeledError::new(e))
|
||||||
})?
|
})?,
|
||||||
}
|
helpers::Backend::Vault {
|
||||||
helpers::Backend::Vault { ref addr, ref token } => {
|
ref addr,
|
||||||
runtime.block_on(async {
|
ref token,
|
||||||
|
} => runtime.block_on(async {
|
||||||
helpers::generate_data_key_vault(addr, token, "provisioning-main", &key_spec)
|
helpers::generate_data_key_vault(addr, token, "provisioning-main", &key_spec)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| LabeledError::new(e))
|
.map_err(|e| LabeledError::new(e))
|
||||||
})?
|
})?,
|
||||||
}
|
|
||||||
helpers::Backend::HttpFallback {
|
helpers::Backend::HttpFallback {
|
||||||
ref backend_name,
|
ref backend_name,
|
||||||
ref url,
|
ref url,
|
||||||
@ -560,12 +561,8 @@ impl SimplePluginCommand for KmsStatus {
|
|||||||
format!("recipient: {}, identity: {}", recipient, identity_status),
|
format!("recipient: {}, identity: {}", recipient, identity_status),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
helpers::Backend::AwsKms { ref key_id } => {
|
helpers::Backend::AwsKms { ref key_id } => ("aws", true, format!("key_id: {}", key_id)),
|
||||||
("aws", true, format!("key_id: {}", key_id))
|
helpers::Backend::Vault { ref addr, .. } => ("vault", true, format!("addr: {}", addr)),
|
||||||
}
|
|
||||||
helpers::Backend::Vault { ref addr, .. } => {
|
|
||||||
("vault", true, format!("addr: {}", addr))
|
|
||||||
}
|
|
||||||
helpers::Backend::HttpFallback {
|
helpers::Backend::HttpFallback {
|
||||||
ref backend_name,
|
ref backend_name,
|
||||||
ref url,
|
ref url,
|
||||||
@ -624,11 +621,31 @@ impl SimplePluginCommand for KmsListBackends {
|
|||||||
_input: &Value,
|
_input: &Value,
|
||||||
) -> Result<Value, LabeledError> {
|
) -> Result<Value, LabeledError> {
|
||||||
let backends = vec![
|
let backends = vec![
|
||||||
("rustyvault", "RustyVault Transit backend", "RUSTYVAULT_ADDR, RUSTYVAULT_TOKEN"),
|
(
|
||||||
("age", "Age file-based encryption", "AGE_RECIPIENT, AGE_IDENTITY"),
|
"rustyvault",
|
||||||
("aws", "AWS Key Management Service", "AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION"),
|
"RustyVault Transit backend",
|
||||||
("vault", "HashiCorp Vault Transit", "VAULT_ADDR, VAULT_TOKEN"),
|
"RUSTYVAULT_ADDR, RUSTYVAULT_TOKEN",
|
||||||
("cosmian", "Cosmian privacy-preserving encryption", "KMS_HTTP_URL"),
|
),
|
||||||
|
(
|
||||||
|
"age",
|
||||||
|
"Age file-based encryption",
|
||||||
|
"AGE_RECIPIENT, AGE_IDENTITY",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"aws",
|
||||||
|
"AWS Key Management Service",
|
||||||
|
"AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"vault",
|
||||||
|
"HashiCorp Vault Transit",
|
||||||
|
"VAULT_ADDR, VAULT_TOKEN",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"cosmian",
|
||||||
|
"Cosmian privacy-preserving encryption",
|
||||||
|
"KMS_HTTP_URL",
|
||||||
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
let backend_values: Vec<Value> = backends
|
let backend_values: Vec<Value> = backends
|
||||||
|
|||||||
@ -24,11 +24,26 @@ fn test_kms_error_with_source() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_kms_error_kind_display() {
|
fn test_kms_error_kind_display() {
|
||||||
assert_eq!(KmsErrorKind::BackendNotAvailable.to_string(), "backend not available");
|
assert_eq!(
|
||||||
assert_eq!(KmsErrorKind::EncryptionFailed.to_string(), "encryption failed");
|
KmsErrorKind::BackendNotAvailable.to_string(),
|
||||||
assert_eq!(KmsErrorKind::DecryptionFailed.to_string(), "decryption failed");
|
"backend not available"
|
||||||
assert_eq!(KmsErrorKind::KeyGenerationFailed.to_string(), "key generation failed");
|
);
|
||||||
assert_eq!(KmsErrorKind::InvalidKeySpec.to_string(), "invalid key specification");
|
assert_eq!(
|
||||||
|
KmsErrorKind::EncryptionFailed.to_string(),
|
||||||
|
"encryption failed"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
KmsErrorKind::DecryptionFailed.to_string(),
|
||||||
|
"decryption failed"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
KmsErrorKind::KeyGenerationFailed.to_string(),
|
||||||
|
"key generation failed"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
KmsErrorKind::InvalidKeySpec.to_string(),
|
||||||
|
"invalid key specification"
|
||||||
|
);
|
||||||
assert_eq!(KmsErrorKind::NetworkError.to_string(), "network error");
|
assert_eq!(KmsErrorKind::NetworkError.to_string(), "network error");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,10 +86,7 @@ fn test_backend_new_age_invalid() {
|
|||||||
fn test_backend_http_fallback() {
|
fn test_backend_http_fallback() {
|
||||||
let backend = helpers::Backend::new_http_fallback("cosmian", "http://localhost:8081");
|
let backend = helpers::Backend::new_http_fallback("cosmian", "http://localhost:8081");
|
||||||
match backend {
|
match backend {
|
||||||
helpers::Backend::HttpFallback {
|
helpers::Backend::HttpFallback { backend_name, url } => {
|
||||||
backend_name,
|
|
||||||
url,
|
|
||||||
} => {
|
|
||||||
assert_eq!(backend_name, "cosmian");
|
assert_eq!(backend_name, "cosmian");
|
||||||
assert_eq!(url, "http://localhost:8081");
|
assert_eq!(url, "http://localhost:8081");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
### 1. Verify Binary Exists
|
### 1. Verify Binary Exists
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
cd /Users/Akasha/project-provisioning/provisioning/core/plugins/nushell-plugins/nu_plugin_kms
|
cd /Users/Akasha/project-provisioning/provisioning/core/plugins/nushell-plugins/nu_plugin_kms
|
||||||
|
|
||||||
# Check binary exists
|
# Check binary exists
|
||||||
@ -19,7 +20,8 @@ ls -lh target/release/nu_plugin_kms
|
|||||||
|
|
||||||
### 2. Register Plugin with Nushell
|
### 2. Register Plugin with Nushell
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Register plugin
|
# Register plugin
|
||||||
nu -c "plugin add target/release/nu_plugin_kms"
|
nu -c "plugin add target/release/nu_plugin_kms"
|
||||||
|
|
||||||
@ -35,7 +37,8 @@ nu -c "plugin list | where name =~ kms"
|
|||||||
|
|
||||||
### 3. Test Plugin Help
|
### 3. Test Plugin Help
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Check command help
|
# Check command help
|
||||||
nu -c "kms encrypt --help"
|
nu -c "kms encrypt --help"
|
||||||
nu -c "kms decrypt --help"
|
nu -c "kms decrypt --help"
|
||||||
@ -49,7 +52,8 @@ nu -c "kms status --help"
|
|||||||
|
|
||||||
#### Setup
|
#### Setup
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Install Age (if not already installed)
|
# Install Age (if not already installed)
|
||||||
brew install age # macOS
|
brew install age # macOS
|
||||||
# or
|
# or
|
||||||
@ -68,7 +72,8 @@ echo "Age Identity: $AGE_IDENTITY"
|
|||||||
|
|
||||||
#### Test Encryption
|
#### Test Encryption
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 1: Encrypt with Age
|
# Test 1: Encrypt with Age
|
||||||
nu -c "kms encrypt 'Hello, Age!' --backend age --key $AGE_RECIPIENT" > /tmp/encrypted.txt
|
nu -c "kms encrypt 'Hello, Age!' --backend age --key $AGE_RECIPIENT" > /tmp/encrypted.txt
|
||||||
|
|
||||||
@ -80,7 +85,8 @@ cat /tmp/encrypted.txt
|
|||||||
|
|
||||||
#### Test Decryption
|
#### Test Decryption
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 2: Decrypt with Age
|
# Test 2: Decrypt with Age
|
||||||
nu -c "kms decrypt '$(cat /tmp/encrypted.txt)' --backend age --key $AGE_IDENTITY"
|
nu -c "kms decrypt '$(cat /tmp/encrypted.txt)' --backend age --key $AGE_IDENTITY"
|
||||||
|
|
||||||
@ -89,7 +95,8 @@ nu -c "kms decrypt '$(cat /tmp/encrypted.txt)' --backend age --key $AGE_IDENTITY
|
|||||||
|
|
||||||
#### Test Key Generation
|
#### Test Key Generation
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 3: Generate new Age key pair
|
# Test 3: Generate new Age key pair
|
||||||
nu -c "kms generate-key --backend age"
|
nu -c "kms generate-key --backend age"
|
||||||
|
|
||||||
@ -102,7 +109,8 @@ nu -c "kms generate-key --backend age"
|
|||||||
|
|
||||||
#### Test Auto-Detection
|
#### Test Auto-Detection
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 4: Auto-detect Age backend
|
# Test 4: Auto-detect Age backend
|
||||||
nu -c "kms status"
|
nu -c "kms status"
|
||||||
|
|
||||||
@ -118,7 +126,8 @@ nu -c "kms status"
|
|||||||
|
|
||||||
#### Setup
|
#### Setup
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Start RustyVault in Docker
|
# Start RustyVault in Docker
|
||||||
docker run -d --name rustyvault \
|
docker run -d --name rustyvault \
|
||||||
-p 8200:8200 \
|
-p 8200:8200 \
|
||||||
@ -143,7 +152,8 @@ docker exec rustyvault \
|
|||||||
|
|
||||||
#### Test Encryption
|
#### Test Encryption
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 1: Encrypt with RustyVault
|
# Test 1: Encrypt with RustyVault
|
||||||
nu -c "kms encrypt 'Secret data!' --backend rustyvault --key provisioning-main"
|
nu -c "kms encrypt 'Secret data!' --backend rustyvault --key provisioning-main"
|
||||||
|
|
||||||
@ -152,7 +162,8 @@ nu -c "kms encrypt 'Secret data!' --backend rustyvault --key provisioning-main"
|
|||||||
|
|
||||||
#### Test Decryption
|
#### Test Decryption
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 2: Encrypt and then decrypt
|
# Test 2: Encrypt and then decrypt
|
||||||
ENCRYPTED=$(nu -c "kms encrypt 'RustyVault test' --backend rustyvault --key provisioning-main")
|
ENCRYPTED=$(nu -c "kms encrypt 'RustyVault test' --backend rustyvault --key provisioning-main")
|
||||||
|
|
||||||
@ -163,7 +174,8 @@ nu -c "kms decrypt '$ENCRYPTED' --backend rustyvault --key provisioning-main"
|
|||||||
|
|
||||||
#### Test Key Generation
|
#### Test Key Generation
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 3: Generate AES256 data key
|
# Test 3: Generate AES256 data key
|
||||||
nu -c "kms generate-key --backend rustyvault --spec AES256"
|
nu -c "kms generate-key --backend rustyvault --spec AES256"
|
||||||
|
|
||||||
@ -176,7 +188,8 @@ nu -c "kms generate-key --backend rustyvault --spec AES256"
|
|||||||
|
|
||||||
#### Test Status
|
#### Test Status
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 4: Check RustyVault status
|
# Test 4: Check RustyVault status
|
||||||
nu -c "kms status"
|
nu -c "kms status"
|
||||||
|
|
||||||
@ -190,7 +203,8 @@ nu -c "kms status"
|
|||||||
|
|
||||||
#### Cleanup
|
#### Cleanup
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Stop and remove RustyVault container
|
# Stop and remove RustyVault container
|
||||||
docker stop rustyvault
|
docker stop rustyvault
|
||||||
docker rm rustyvault
|
docker rm rustyvault
|
||||||
@ -200,7 +214,8 @@ docker rm rustyvault
|
|||||||
|
|
||||||
#### Setup (Mock Server)
|
#### Setup (Mock Server)
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Create simple mock KMS server with Python
|
# Create simple mock KMS server with Python
|
||||||
cat > /tmp/mock_kms_server.py << 'EOF'
|
cat > /tmp/mock_kms_server.py << 'EOF'
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
@ -262,7 +277,8 @@ export KMS_HTTP_BACKEND="mock"
|
|||||||
|
|
||||||
#### Test HTTP Backend
|
#### Test HTTP Backend
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 1: Encrypt
|
# Test 1: Encrypt
|
||||||
nu -c "kms encrypt 'HTTP test data' --backend mock"
|
nu -c "kms encrypt 'HTTP test data' --backend mock"
|
||||||
|
|
||||||
@ -279,7 +295,8 @@ nu -c "kms status"
|
|||||||
|
|
||||||
#### Cleanup
|
#### Cleanup
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Stop mock server
|
# Stop mock server
|
||||||
kill $MOCK_SERVER_PID
|
kill $MOCK_SERVER_PID
|
||||||
```
|
```
|
||||||
@ -288,7 +305,8 @@ kill $MOCK_SERVER_PID
|
|||||||
|
|
||||||
### Test Auto-Detection Priority
|
### Test Auto-Detection Priority
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 1: RustyVault has priority
|
# Test 1: RustyVault has priority
|
||||||
export RUSTYVAULT_ADDR="http://localhost:8200"
|
export RUSTYVAULT_ADDR="http://localhost:8200"
|
||||||
export RUSTYVAULT_TOKEN="test-token"
|
export RUSTYVAULT_TOKEN="test-token"
|
||||||
@ -313,7 +331,8 @@ nu -c "kms status"
|
|||||||
|
|
||||||
### Test Error Handling
|
### Test Error Handling
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test 1: Missing required flags
|
# Test 1: Missing required flags
|
||||||
nu -c "kms encrypt 'data' --backend age"
|
nu -c "kms encrypt 'data' --backend age"
|
||||||
# Expected: Error about missing --key recipient
|
# Expected: Error about missing --key recipient
|
||||||
@ -334,7 +353,8 @@ nu -c "kms generate-key --backend rustyvault --spec INVALID"
|
|||||||
|
|
||||||
### Test Binary Data
|
### Test Binary Data
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Test handling of non-UTF8 data
|
# Test handling of non-UTF8 data
|
||||||
dd if=/dev/urandom bs=1024 count=1 | base64 > /tmp/random.b64
|
dd if=/dev/urandom bs=1024 count=1 | base64 > /tmp/random.b64
|
||||||
|
|
||||||
@ -356,7 +376,8 @@ fi
|
|||||||
|
|
||||||
### Age Performance
|
### Age Performance
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Benchmark encryption (1000 iterations)
|
# Benchmark encryption (1000 iterations)
|
||||||
time for i in {1..1000}; do
|
time for i in {1..1000}; do
|
||||||
nu -c "kms encrypt 'test data' --backend age --key $AGE_RECIPIENT" > /dev/null
|
nu -c "kms encrypt 'test data' --backend age --key $AGE_RECIPIENT" > /dev/null
|
||||||
@ -367,7 +388,8 @@ done
|
|||||||
|
|
||||||
### RustyVault Performance
|
### RustyVault Performance
|
||||||
|
|
||||||
```bash
|
```rust
|
||||||
|
bash
|
||||||
# Benchmark encryption (1000 iterations)
|
# Benchmark encryption (1000 iterations)
|
||||||
time for i in {1..1000}; do
|
time for i in {1..1000}; do
|
||||||
nu -c "kms encrypt 'test data' --backend rustyvault --key provisioning-main" > /dev/null
|
nu -c "kms encrypt 'test data' --backend rustyvault --key provisioning-main" > /dev/null
|
||||||
@ -378,7 +400,8 @@ done
|
|||||||
|
|
||||||
### Memory Usage
|
### Memory Usage
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Monitor memory during operations
|
# Monitor memory during operations
|
||||||
while true; do
|
while true; do
|
||||||
nu -c "kms encrypt 'test data' --backend age --key $AGE_RECIPIENT" > /dev/null
|
nu -c "kms encrypt 'test data' --backend age --key $AGE_RECIPIENT" > /dev/null
|
||||||
@ -392,17 +415,20 @@ done
|
|||||||
## Verification Checklist
|
## Verification Checklist
|
||||||
|
|
||||||
### Compilation
|
### Compilation
|
||||||
|
|
||||||
- [x] `cargo check` passes
|
- [x] `cargo check` passes
|
||||||
- [x] `cargo build --release` succeeds
|
- [x] `cargo build --release` succeeds
|
||||||
- [x] Binary created in `target/release/nu_plugin_kms`
|
- [x] Binary created in `target/release/nu_plugin_kms`
|
||||||
- [x] File size reasonable (< 50MB)
|
- [x] File size reasonable (< 50MB)
|
||||||
|
|
||||||
### Plugin Registration
|
### Plugin Registration
|
||||||
|
|
||||||
- [ ] Plugin registers with Nushell
|
- [ ] Plugin registers with Nushell
|
||||||
- [ ] All 4 commands visible in `plugin list`
|
- [ ] All 4 commands visible in `plugin list`
|
||||||
- [ ] Help text accessible for each command
|
- [ ] Help text accessible for each command
|
||||||
|
|
||||||
### Age Backend
|
### Age Backend
|
||||||
|
|
||||||
- [ ] Encryption works with recipient
|
- [ ] Encryption works with recipient
|
||||||
- [ ] Decryption works with identity file
|
- [ ] Decryption works with identity file
|
||||||
- [ ] Key generation produces valid key pair
|
- [ ] Key generation produces valid key pair
|
||||||
@ -410,6 +436,7 @@ done
|
|||||||
- [ ] Auto-detection works when env vars set
|
- [ ] Auto-detection works when env vars set
|
||||||
|
|
||||||
### RustyVault Backend
|
### RustyVault Backend
|
||||||
|
|
||||||
- [ ] Encryption works with Transit engine
|
- [ ] Encryption works with Transit engine
|
||||||
- [ ] Decryption works correctly
|
- [ ] Decryption works correctly
|
||||||
- [ ] Data key generation works
|
- [ ] Data key generation works
|
||||||
@ -417,6 +444,7 @@ done
|
|||||||
- [ ] Auto-detection works when env vars set
|
- [ ] Auto-detection works when env vars set
|
||||||
|
|
||||||
### HTTP Fallback
|
### HTTP Fallback
|
||||||
|
|
||||||
- [ ] Encryption works with HTTP service
|
- [ ] Encryption works with HTTP service
|
||||||
- [ ] Decryption works correctly
|
- [ ] Decryption works correctly
|
||||||
- [ ] Data key generation works
|
- [ ] Data key generation works
|
||||||
@ -424,12 +452,14 @@ done
|
|||||||
- [ ] Auto-detection works as fallback
|
- [ ] Auto-detection works as fallback
|
||||||
|
|
||||||
### Error Handling
|
### Error Handling
|
||||||
|
|
||||||
- [ ] Missing flags produce clear errors
|
- [ ] Missing flags produce clear errors
|
||||||
- [ ] Invalid inputs rejected gracefully
|
- [ ] Invalid inputs rejected gracefully
|
||||||
- [ ] Network errors handled properly
|
- [ ] Network errors handled properly
|
||||||
- [ ] Missing env vars reported clearly
|
- [ ] Missing env vars reported clearly
|
||||||
|
|
||||||
### Integration
|
### Integration
|
||||||
|
|
||||||
- [ ] Auto-detection priority correct
|
- [ ] Auto-detection priority correct
|
||||||
- [ ] Multiple backends can coexist
|
- [ ] Multiple backends can coexist
|
||||||
- [ ] Environment switching works
|
- [ ] Environment switching works
|
||||||
@ -438,21 +468,25 @@ done
|
|||||||
## Success Criteria
|
## Success Criteria
|
||||||
|
|
||||||
✅ **Basic Functionality**
|
✅ **Basic Functionality**
|
||||||
|
|
||||||
- All backends encrypt and decrypt successfully
|
- All backends encrypt and decrypt successfully
|
||||||
- Key generation works for all backends
|
- Key generation works for all backends
|
||||||
- Status command reports correctly
|
- Status command reports correctly
|
||||||
|
|
||||||
✅ **Robustness**
|
✅ **Robustness**
|
||||||
|
|
||||||
- Error messages are clear and actionable
|
- Error messages are clear and actionable
|
||||||
- No panics or crashes
|
- No panics or crashes
|
||||||
- Memory usage is stable
|
- Memory usage is stable
|
||||||
|
|
||||||
✅ **Performance**
|
✅ **Performance**
|
||||||
|
|
||||||
- Operations complete in reasonable time
|
- Operations complete in reasonable time
|
||||||
- No memory leaks
|
- No memory leaks
|
||||||
- Concurrent operations work
|
- Concurrent operations work
|
||||||
|
|
||||||
✅ **Usability**
|
✅ **Usability**
|
||||||
|
|
||||||
- Auto-detection works as expected
|
- Auto-detection works as expected
|
||||||
- Environment configuration is straightforward
|
- Environment configuration is straightforward
|
||||||
- Help text is clear
|
- Help text is clear
|
||||||
@ -461,7 +495,8 @@ done
|
|||||||
|
|
||||||
### Plugin Not Loading
|
### Plugin Not Loading
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Check plugin is registered
|
# Check plugin is registered
|
||||||
nu -c "plugin list" | grep kms
|
nu -c "plugin list" | grep kms
|
||||||
|
|
||||||
@ -474,7 +509,8 @@ nu -c "plugin list --version"
|
|||||||
|
|
||||||
### Environment Variables Not Working
|
### Environment Variables Not Working
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Check env vars are set
|
# Check env vars are set
|
||||||
env | grep -E '(RUSTYVAULT|AGE|KMS)'
|
env | grep -E '(RUSTYVAULT|AGE|KMS)'
|
||||||
|
|
||||||
@ -484,7 +520,8 @@ bash -c 'export AGE_RECIPIENT=...; nu -c "kms status"'
|
|||||||
|
|
||||||
### Compilation Errors
|
### Compilation Errors
|
||||||
|
|
||||||
```bash
|
```nushell
|
||||||
|
bash
|
||||||
# Clean build
|
# Clean build
|
||||||
cargo clean
|
cargo clean
|
||||||
|
|
||||||
|
|||||||
2242
nu_plugin_mcp/Cargo.lock
generated
Normal file
2242
nu_plugin_mcp/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
nu_plugin_mcp/Cargo.toml
Normal file
27
nu_plugin_mcp/Cargo.toml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[[bin]]
|
||||||
|
name = "nu_plugin_mcp"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "nu_plugin_mcp"
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "nu_plugin_mcp"
|
||||||
|
version = "0.111.0"
|
||||||
|
edition = "2021"
|
||||||
|
description = "Nushell plugin for MCP server interaction — connect, discover, and call provisioning tools"
|
||||||
|
authors = ["Provisioning Team"]
|
||||||
|
license = "MIT"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde_json = "1.0"
|
||||||
|
thiserror = "2.0"
|
||||||
|
interprocess = "^2.3.1"
|
||||||
|
nu-plugin = "0.111.0"
|
||||||
|
nu-protocol = "0.111.0"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 3
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
12
nu_plugin_mcp/examples/iac_validate.nu
Normal file
12
nu_plugin_mcp/examples/iac_validate.nu
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env nu
|
||||||
|
# Validate infrastructure config via MCP and display results
|
||||||
|
|
||||||
|
mcp connect provisioning-mcp-server --provisioning-path /opt/provisioning
|
||||||
|
|
||||||
|
let result = mcp tool call guidance_validate_config_file --payload {
|
||||||
|
config_path: "provisioning/config/workspace.ncl"
|
||||||
|
}
|
||||||
|
|
||||||
|
print $result
|
||||||
|
|
||||||
|
mcp disconnect
|
||||||
12
nu_plugin_mcp/examples/rag_search.nu
Normal file
12
nu_plugin_mcp/examples/rag_search.nu
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env nu
|
||||||
|
# Search provisioning documentation via RAG
|
||||||
|
|
||||||
|
mcp connect provisioning-mcp-server --provisioning-path /opt/provisioning
|
||||||
|
|
||||||
|
let docs = mcp tool call guidance_find_docs --payload {
|
||||||
|
query: "nickel validation type-safe configuration"
|
||||||
|
}
|
||||||
|
|
||||||
|
print $docs
|
||||||
|
|
||||||
|
mcp disconnect
|
||||||
8
nu_plugin_mcp/examples/tool_discovery.nu
Normal file
8
nu_plugin_mcp/examples/tool_discovery.nu
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env nu
|
||||||
|
# Discover all available MCP tools and display as a table
|
||||||
|
|
||||||
|
mcp connect provisioning-mcp-server --provisioning-path /opt/provisioning
|
||||||
|
|
||||||
|
mcp tools list | select name description | sort-by name | table
|
||||||
|
|
||||||
|
mcp disconnect
|
||||||
192
nu_plugin_mcp/src/commands/call.rs
Normal file
192
nu_plugin_mcp/src/commands/call.rs
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
use crate::McpPlugin;
|
||||||
|
use nu_plugin::{EvaluatedCall, SimplePluginCommand};
|
||||||
|
use nu_protocol::{
|
||||||
|
Category, Example, LabeledError, Record, Signature, Span, SyntaxShape, Type, Value,
|
||||||
|
};
|
||||||
|
use serde_json::Value as Json;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct McpToolCall;
|
||||||
|
|
||||||
|
impl SimplePluginCommand for McpToolCall {
|
||||||
|
type Plugin = McpPlugin;
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"mcp tool call"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
"Call a tool on the connected MCP server"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build("mcp tool call")
|
||||||
|
.input_output_type(Type::Nothing, Type::Any)
|
||||||
|
.required(
|
||||||
|
"name",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"Tool name (e.g. provision_status)",
|
||||||
|
)
|
||||||
|
.named(
|
||||||
|
"payload",
|
||||||
|
SyntaxShape::Record(vec![]),
|
||||||
|
"Arguments to pass to the tool as a record",
|
||||||
|
Some('a'),
|
||||||
|
)
|
||||||
|
.category(Category::Custom("provisioning".into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example<'_>> {
|
||||||
|
vec![
|
||||||
|
Example {
|
||||||
|
example: "mcp tool call provision_status",
|
||||||
|
description: "Get provisioning infrastructure status",
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
Example {
|
||||||
|
example: "mcp tool call provision_query --payload {query: \"list all servers\"}",
|
||||||
|
description: "Query infrastructure using natural language",
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
Example {
|
||||||
|
example:
|
||||||
|
"mcp tool call guidance_find_docs --payload {query: \"nickel validation\"}",
|
||||||
|
description: "Find relevant documentation",
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
plugin: &McpPlugin,
|
||||||
|
_engine: &nu_plugin::EngineInterface,
|
||||||
|
call: &EvaluatedCall,
|
||||||
|
_input: &Value,
|
||||||
|
) -> Result<Value, LabeledError> {
|
||||||
|
let tool_name: String = call.req(0)?;
|
||||||
|
let payload_val: Option<Value> = call.get_flag("payload")?;
|
||||||
|
let span = call.head;
|
||||||
|
|
||||||
|
let arguments = match payload_val {
|
||||||
|
Some(v) => nu_record_to_json(&v)
|
||||||
|
.map_err(|e| LabeledError::new(format!("payload conversion: {e}")))?,
|
||||||
|
None => Json::Object(Default::default()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut guard = plugin
|
||||||
|
.session
|
||||||
|
.lock()
|
||||||
|
.map_err(|_| LabeledError::new("session mutex poisoned"))?;
|
||||||
|
let session = guard
|
||||||
|
.as_mut()
|
||||||
|
.ok_or_else(|| LabeledError::new("not connected — run `mcp connect <binary>` first"))?;
|
||||||
|
|
||||||
|
let result = session
|
||||||
|
.tool_call(&tool_name, arguments)
|
||||||
|
.map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
|
|
||||||
|
Ok(mcp_result_to_nu(result, span))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert MCP tool result to a Nu value.
|
||||||
|
/// MCP spec: result = { content: [{type: "text", text: "..."}, ...], isError?: bool }
|
||||||
|
fn mcp_result_to_nu(result: Json, span: Span) -> Value {
|
||||||
|
let is_error = result
|
||||||
|
.get("isError")
|
||||||
|
.and_then(|v| v.as_bool())
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
let text = result
|
||||||
|
.get("content")
|
||||||
|
.and_then(|c| c.as_array())
|
||||||
|
.and_then(|arr| arr.first())
|
||||||
|
.and_then(|item| item.get("text"))
|
||||||
|
.and_then(|t| t.as_str())
|
||||||
|
.unwrap_or("")
|
||||||
|
.to_owned();
|
||||||
|
|
||||||
|
if is_error {
|
||||||
|
let mut rec = Record::new();
|
||||||
|
rec.push("error", Value::bool(true, span));
|
||||||
|
rec.push("message", Value::string(text, span));
|
||||||
|
Value::record(rec, span)
|
||||||
|
} else {
|
||||||
|
// Try to parse text as JSON for richer output; fall back to plain string
|
||||||
|
if let Ok(json_val) = serde_json::from_str::<Json>(&text) {
|
||||||
|
json_to_nu_value(json_val, span)
|
||||||
|
} else {
|
||||||
|
Value::string(text, span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn json_to_nu_value(v: Json, span: Span) -> Value {
|
||||||
|
match v {
|
||||||
|
Json::Null => Value::nothing(span),
|
||||||
|
Json::Bool(b) => Value::bool(b, span),
|
||||||
|
Json::Number(n) => {
|
||||||
|
if let Some(i) = n.as_i64() {
|
||||||
|
Value::int(i, span)
|
||||||
|
} else {
|
||||||
|
Value::float(n.as_f64().unwrap_or(0.0), span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Json::String(s) => Value::string(s, span),
|
||||||
|
Json::Array(arr) => {
|
||||||
|
let vals = arr.into_iter().map(|v| json_to_nu_value(v, span)).collect();
|
||||||
|
Value::list(vals, span)
|
||||||
|
}
|
||||||
|
Json::Object(map) => {
|
||||||
|
let mut rec = Record::new();
|
||||||
|
for (k, v) in map {
|
||||||
|
rec.push(k, json_to_nu_value(v, span));
|
||||||
|
}
|
||||||
|
Value::record(rec, span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nu_record_to_json(val: &Value) -> Result<Json, String> {
|
||||||
|
match val {
|
||||||
|
Value::Nothing { .. } => Ok(Json::Object(Default::default())),
|
||||||
|
Value::Record { val, .. } => {
|
||||||
|
let mut map = serde_json::Map::new();
|
||||||
|
for (k, v) in val.iter() {
|
||||||
|
map.insert(k.to_owned(), nu_value_to_json(v)?);
|
||||||
|
}
|
||||||
|
Ok(Json::Object(map))
|
||||||
|
}
|
||||||
|
_ => Err(format!(
|
||||||
|
"payload must be a record, got {:?}",
|
||||||
|
val.get_type()
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nu_value_to_json(val: &Value) -> Result<Json, String> {
|
||||||
|
match val {
|
||||||
|
Value::Nothing { .. } => Ok(Json::Null),
|
||||||
|
Value::Bool { val, .. } => Ok(Json::Bool(*val)),
|
||||||
|
Value::Int { val, .. } => Ok(Json::Number((*val).into())),
|
||||||
|
Value::Float { val, .. } => serde_json::Number::from_f64(*val)
|
||||||
|
.map(Json::Number)
|
||||||
|
.ok_or_else(|| format!("non-finite float: {val}")),
|
||||||
|
Value::String { val, .. } => Ok(Json::String(val.clone())),
|
||||||
|
Value::List { vals, .. } => {
|
||||||
|
let arr: Result<Vec<_>, _> = vals.iter().map(nu_value_to_json).collect();
|
||||||
|
Ok(Json::Array(arr?))
|
||||||
|
}
|
||||||
|
Value::Record { val, .. } => {
|
||||||
|
let mut map = serde_json::Map::new();
|
||||||
|
for (k, v) in val.iter() {
|
||||||
|
map.insert(k.to_owned(), nu_value_to_json(v)?);
|
||||||
|
}
|
||||||
|
Ok(Json::Object(map))
|
||||||
|
}
|
||||||
|
other => Ok(Json::String(
|
||||||
|
other.to_expanded_string(", ", &Default::default()),
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
91
nu_plugin_mcp/src/commands/connect.rs
Normal file
91
nu_plugin_mcp/src/commands/connect.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
use crate::session::McpSession;
|
||||||
|
use crate::McpPlugin;
|
||||||
|
use nu_plugin::{EvaluatedCall, SimplePluginCommand};
|
||||||
|
use nu_protocol::{
|
||||||
|
Category, Example, LabeledError, Record, Signature, Span, SyntaxShape, Type, Value,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct McpConnect;
|
||||||
|
|
||||||
|
impl SimplePluginCommand for McpConnect {
|
||||||
|
type Plugin = McpPlugin;
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"mcp connect"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
"Connect to an MCP server by spawning a binary as a child process"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build("mcp connect")
|
||||||
|
.input_output_type(Type::Nothing, Type::Record(vec![].into()))
|
||||||
|
.required(
|
||||||
|
"binary",
|
||||||
|
SyntaxShape::String,
|
||||||
|
"Path to the MCP server binary or command name on PATH",
|
||||||
|
)
|
||||||
|
.named(
|
||||||
|
"provisioning-path",
|
||||||
|
SyntaxShape::Filepath,
|
||||||
|
"Set PROVISIONING_PATH env var for the spawned server",
|
||||||
|
Some('p'),
|
||||||
|
)
|
||||||
|
.category(Category::Custom("provisioning".into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(&self) -> Vec<Example<'_>> {
|
||||||
|
vec![
|
||||||
|
Example {
|
||||||
|
example: "mcp connect provisioning-mcp-server",
|
||||||
|
description: "Connect to the provisioning MCP server on PATH",
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
Example {
|
||||||
|
example: "mcp connect ./target/release/provisioning-mcp-server --provisioning-path /opt/provisioning",
|
||||||
|
description: "Connect with explicit provisioning path",
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
plugin: &McpPlugin,
|
||||||
|
_engine: &nu_plugin::EngineInterface,
|
||||||
|
call: &EvaluatedCall,
|
||||||
|
_input: &Value,
|
||||||
|
) -> Result<Value, LabeledError> {
|
||||||
|
let binary: String = call.req(0)?;
|
||||||
|
let provisioning_path: Option<String> = call.get_flag("provisioning-path")?;
|
||||||
|
let span = call.head;
|
||||||
|
|
||||||
|
let mut guard = plugin
|
||||||
|
.session
|
||||||
|
.lock()
|
||||||
|
.map_err(|_| LabeledError::new("session mutex poisoned"))?;
|
||||||
|
|
||||||
|
if guard.is_some() {
|
||||||
|
return Err(LabeledError::new(
|
||||||
|
"already connected — run `mcp disconnect` before reconnecting",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let session = McpSession::connect(&binary, provisioning_path.as_deref())
|
||||||
|
.map_err(|e| LabeledError::new(e.to_string()))?;
|
||||||
|
|
||||||
|
*guard = Some(session);
|
||||||
|
drop(guard);
|
||||||
|
|
||||||
|
Ok(connected_record(&binary, span))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connected_record(binary: &str, span: Span) -> Value {
|
||||||
|
let mut rec = Record::new();
|
||||||
|
rec.push("status", Value::string("connected", span));
|
||||||
|
rec.push("binary", Value::string(binary, span));
|
||||||
|
Value::record(rec, span)
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user