⚡ 100% Vibe Coded - This entire project was created through AI-assisted development using Amazon Q Developer.
A native Nushell plugin for SDKMAN! written in Rust, using the Nushell 0.110.0 plugin protocol.
✅ Production Ready - Core functionality complete with comprehensive test coverage and documentation.
- Native Nushell plugin (binary, not scripts)
- Full SDKMAN! API integration
- Command coverage matching bash SDKMAN (24 commands + aliases)
- Structured data output for Nushell pipelines
- Cross-platform support (Linux, macOS, Windows)
- Fast and efficient Rust implementation
- Pure Rust archive handling (no external tools required)
- Comprehensive test suite (22 tests, 100% passing)
- Full API documentation
- Rust toolchain (1.70+)
- Nushell 0.110.0+
cargo build --releaseRun the install script:
# Using bash/zsh
curl -fsSL https://raw.githubusercontent.com/mikolas/nu_plugin_sdkman/master/install.sh | bash
# Or using Nushell
http get https://raw.githubusercontent.com/mikolas/nu_plugin_sdkman/master/install.nu | save install.nu
nu install.nuThe installer will:
- Download the correct binary for your platform
- Install to
~/.local/bin/nu_plugin_sdkman - Register the plugin with Nushell
- Create
~/.sdkman/bin/sdkman-init.nufor PATH setup
Then add these lines to your ~/.config/nushell/config.nu:
# SDKMAN
$env.SDKMAN_DIR = ($env.HOME | path join ".sdkman")
source ~/.sdkman/bin/sdkman-init.nuRestart Nushell and you're ready!
-
Download the binary for your platform from Releases:
- Linux x86_64:
nu_plugin_sdkman-x86_64-unknown-linux-gnu - Linux ARM64:
nu_plugin_sdkman-aarch64-unknown-linux-gnu - macOS x86_64:
nu_plugin_sdkman-x86_64-apple-darwin - macOS ARM64:
nu_plugin_sdkman-aarch64-apple-darwin - Windows x86_64:
nu_plugin_sdkman-x86_64-pc-windows-msvc.exe
- Linux x86_64:
-
Make it executable (Unix):
chmod +x nu_plugin_sdkman-* -
Move to a directory in your PATH:
mv nu_plugin_sdkman-* ~/.local/bin/nu_plugin_sdkman
-
Register with Nushell:
plugin add ~/.local/bin/nu_plugin_sdkman
-
Create the init script:
mkdir -p ~/.sdkman/bin cat > ~/.sdkman/bin/sdkman-init.nu << 'EOF' # SDKMAN Nushell initialization $env.PATH = ($env.PATH | prepend ( ls ~/.sdkman/candidates/*/current/bin | get name )) EOF
-
Add to
~/.config/nushell/config.nu:# SDKMAN $env.SDKMAN_DIR = ($env.HOME | path join ".sdkman") source ~/.sdkman/bin/sdkman-init.nu
-
Restart Nushell
Prerequisites:
- Rust toolchain (1.70+)
- Nushell 0.110.0+
Build and install:
git clone https://github.com/mikolas/nu_plugin_sdkman.git
cd nu_plugin_sdkman
cargo build --release
plugin add ./target/release/nu_plugin_sdkmanThen follow steps 5-7 from "From Pre-built Binaries" above.
sdk # Show help and available commands
sdk --help # Show help
sdk list --help # Show help for list commandsdk list # List all candidates with descriptions
sdk ls # Alias for list
sdk list | less # Paged view
sdk list java # List Java versions grouped by vendor
sdk list java | less # Paged viewOutput format:
sdk list(no args) returns pre-formatted text from SDKMAN APIsdk list <candidate>returns structured table with columns: vendor, use, version, dist, status, identifier
sdk install java # Install latest Java
sdk i java 17 # Alias: install Java 17
sdk install java 17 --local /path/to/java.tar.gz # Install from local archivesdk use java 17 # Switch to Java 17
sdk u java 17 # Alias for use
sdk default java 17 # Set Java 17 as default
sdk d java 17 # Alias for defaultsdk current # Show all current versions
sdk c # Alias for current
sdk current java # Show current Java versionsdk home java 17 # Print Java 17 home directory path
sdk h java 17 # Alias for homeGlobal Mode (default):
sdk env init # Create .sdkmanrc in current directory
sdk env install # Install all SDKs from .sdkmanrc
sdk env # Load and use versions from .sdkmanrc
sdk env clear # Clear environmentLocal Mode (project isolation):
sdk env init # Create .sdkmanrc AND .sdkman/ directory
source .sdkman/env.nu # Activate local environment
sdk env install # Install to global, symlink locally
sdk env # Use local versions
sdk env clear # Clear local symlinks onlyHow Local Mode Works:
sdk env initcreates.sdkman/directory withenv.nuactivation script- SDKs are installed once to
~/.sdkman/(shared across projects) - Local symlinks in
.sdkman/candidates/*/currentpoint to global installations - Each project has its own
currentpointers without duplicating SDK files - Activate with
source .sdkman/env.nuto prepend local paths to PATH
Benefits:
- ✅ True project isolation - different projects use different versions
- ✅ No disk space waste - SDKs installed once, symlinked per-project
- ✅ Fast setup - only creates symlinks, no downloads
- ✅ Explicit activation - like Python venv or Node nvm
Example:
# Project A needs Java 17
cd ~/project-a
sdk env init
source .sdkman/env.nu
sdk use java 17
java --version # Java 17
# Project B needs Java 21 (in another terminal)
cd ~/project-b
sdk env init
source .sdkman/env.nu
sdk use java 21
java --version # Java 21
# Both use the same SDK files, just different symlinks!sdk upgrade # Upgrade all to latest
sdk ug java # Alias: upgrade Java to latest
sdk update # Update local candidate cache
sdk flush # Clear all caches
sdk flush tmp # Clear temp files only
sdk version # Show plugin version
sdk v # Alias for versionsdk config # Edit configuration file
sdk offline enable # Enable offline mode
sdk offline disable # Disable offline modesdk uninstall java 17 # Remove Java 17
sdk rm java 17 # Alias for uninstallUses Nushell 0.110.0 plugin protocol with MessagePack serialization for efficient communication between Nushell and the plugin binary.
All commands are implemented as PluginCommand traits:
Main Commands:
sdk- Show help and usagesdk list- List candidates/versions (formatted text)sdk install- Download and install SDKs (supports --local)sdk uninstall- Remove installationssdk use- Set current versionsdk default- Set default versionsdk current- Show current versionssdk upgrade- Upgrade to latestsdk home- Print home directory pathsdk env- Manage .sdkmanrc files (init/install/clear)sdk version- Show plugin versionsdk update- Update candidate cachesdk flush- Clear cachessdk config- Edit configurationsdk offline- Enable/disable offline mode
Aliases:
ls→listi→installrm→uninstallu→used→defaultc→currentug→upgradeh→homev→version
Nushell → Plugin Protocol → Command Handler → API/Filesystem → Response → Nushell
sdk list(no args) returns pre-formatted text from SDKMAN APIsdk list <candidate>returns structured table with columns: vendor, use, version, dist, status, identifier- Other commands return structured data or status messages
~/.sdkman/
├── candidates/
│ ├── java/
│ │ ├── 17.0.9/
│ │ ├── 21.0.1/
│ │ └── current → 17.0.9 (symlink on Unix)
│ └── gradle/
│ └── 8.5/
The plugin creates symlinks (Unix) or version markers (Windows) at ~/.sdkman/candidates/<candidate>/current that point to the active version.
When you run sdk use java 17 or sdk default java 17, the plugin updates the current symlink to point to that version. The install script creates ~/.sdkman/bin/sdkman-init.nu which automatically adds all current/bin directories to your PATH.
In your config.nu:
# SDKMAN
$env.SDKMAN_DIR = ($env.HOME | path join ".sdkman")
source ~/.sdkman/bin/sdkman-init.nuThe init script dynamically discovers all installed candidates:
# ~/.sdkman/bin/sdkman-init.nu
$env.PATH = ($env.PATH | prepend (
ls ~/.sdkman/candidates/*/current/bin
| get name
))After setup, switching versions is automatic:
sdk use java 17 # Updates the 'current' symlink to Java 17
java --version # Uses Java 17
sdk use java 21 # Updates the 'current' symlink to Java 21
java --version # Uses Java 21No need to modify PATH or restart Nushell - the symlink/marker handles it dynamically.
- PATH Management: Uses Nushell init script (similar to bash's
sdkman-init.sh) - Binary Plugin: Compiled Rust binary, not shell scripts
- Explicit Commands: All operations are explicit plugin commands
- Feature Complete: All major bash commands implemented (24 commands total)
- Aliases Supported: All bash aliases (i, rm, ls, u, c, ug, d, h, v) work
- Compatible: Can coexist with bash SDKMAN (shares same directory structure)
Note: Some commands have basic implementations:
config- Opens editor but doesn't manage config file yetoffline- Command exists but offline mode not fully implementedflush- Clears directories but cache management is basic
src/
├── main.rs # Plugin entry point
├── lib.rs # Plugin registration
├── commands/ # Command implementations
│ ├── help.rs
│ ├── list.rs
│ ├── install.rs
│ ├── uninstall.rs
│ ├── use.rs
│ ├── default.rs
│ ├── current.rs
│ ├── upgrade.rs
│ ├── home.rs
│ ├── version.rs
│ ├── env.rs
│ ├── update.rs
│ ├── flush.rs
│ ├── config.rs
│ ├── offline.rs
│ └── aliases.rs
├── core/ # Core functionality
│ ├── api.rs # SDKMAN API client
│ └── env.rs # Environment/filesystem
└── utils/ # Utilities
├── download.rs # HTTP downloads
└── archive.rs # Archive extraction
- Create new file in
src/commands/ - Implement
PluginCommandtrait - Register in
src/lib.rs
cargo testTest Coverage:
- ✅ API version parsing (5 tests)
- ✅ Archive extraction (5 tests - tar.gz and zip)
- ✅ .sdkmanrc parsing (6 tests)
- ✅ Symlink handling (3 tests)
- ✅ Integration tests (3 tests)
Total: 22/22 tests passing (100%)
Test Isolation:
- All tests use temporary directories
- No tests touch user's home directory
- Environment variable isolation with
#[serial]
Generate API documentation:
cargo doc --openAll public APIs are documented with:
- Function purpose and behavior
- Arguments and return values
- Error conditions
- Platform-specific notes
- Examples where helpful
- Nushell 0.110.0 or later
- Internet connection for downloading SDKs
Apache License 2.0 (same as SDKMAN!)
This project was entirely vibe coded using Amazon Q Developer - from initial concept to full implementation, including:
- Complete Rust codebase (24 commands + aliases)
- GitHub Actions CI/CD pipeline
- Cross-platform builds (Linux, macOS, Windows)
- Installation scripts
- Documentation
No manual coding was required. The entire development process was conversational, demonstrating the power of AI-assisted development.
This is a Nushell plugin implementation of SDKMAN!. For the original project: https://github.com/sdkman/sdkman-cli
Issues and pull requests are welcome at: https://github.com/mikolas/nu_plugin_sdkman