nushell-plugins/docs/PLUGIN_EXCLUSION_GUIDE.md

403 lines
11 KiB
Markdown
Raw Normal View History

# Plugin Exclusion Guide
## Quick Reference
**What is plugin exclusion?**: A mechanism to prevent certain plugins (like `nu_plugin_example`) from being included in distributions and installations, while keeping them available for development and testing.
**Who should read this?**:
- 📦 Release managers
- 👨‍💻 Plugin developers
- 🔧 Maintainers
- 📚 Users who want to understand the distribution process
---
## Quick Start
### For Users
**Question**: I found `nu_plugin_example` but it's not in my installation. Why?
**Answer**: The example plugin is intentionally excluded from distributions. It's a reference implementation for plugin developers, not a user-facing tool.
**If you want to use it**:
1. Clone the repository
2. Build it: `just build`
3. Use the binary directly: `./nushell/target/release/nu_plugin_example`
---
### For Developers
**Question**: I want to exclude my plugin from distributions. How?
**Answer**: Add it to the exclusion list in `etc/plugin_registry.toml`:
```toml
[distribution]
excluded_plugins = [
"nu_plugin_example",
"nu_plugin_my_new_plugin" # ← Add your plugin here
]
```
That's it! The collection and packaging systems will automatically skip it.
---
### For Release Managers
**Checklist before release**:
1. **Verify exclusion list is correct**:
```bash
nu -c "open ./etc/plugin_registry.toml | get distribution.excluded_plugins"
```
2. **Verify collection respects it**:
```bash
just collect
find distribution -name "*example*" # Should find nothing
```
3. **Verify packaging respects it**:
```bash
just pack-full
tar -tzf bin_archives/*.tar.gz | grep example # Should find nothing
```
4. **Verify builds still include everything** (for testing):
```bash
just build
ls nushell/target/release/ | grep example # Should find the binary
```
---
## Common Tasks
### Task 1: Add a Plugin to Exclusion List
**Scenario**: You have a new reference plugin that shouldn't be shipped to users.
**Steps**:
1. Create your plugin in `nushell/crates/nu_plugin_myref/`
2. Update `etc/plugin_registry.toml`:
```toml
[distribution]
excluded_plugins = [
"nu_plugin_example",
"nu_plugin_myref" # ← Add here
]
```
3. Update `scripts/templates/default_config.nu` - remove it from the `plugin_binaries` list if it was there
4. Test:
```bash
just collect && find distribution -name "*myref*" # Should be empty
```
---
### Task 2: Remove a Plugin from Exclusion List
**Scenario**: Your reference plugin is now stable and ready for distribution.
**Steps**:
1. Update `etc/plugin_registry.toml`:
```toml
[distribution]
excluded_plugins = [
"nu_plugin_example" # ← Removed your plugin
]
```
2. Update `scripts/templates/default_config.nu` - add it to the `plugin_binaries` list if you want auto-loading
3. Test:
```bash
just collect && find distribution -name "*myref*" # Should exist now
```
---
### Task 3: Check Current Build Includes Excluded Plugin
**Scenario**: You want to verify that excluded plugins are still being built.
**Steps**:
```bash
# Build everything including excluded plugins
just build
# Verify excluded plugin was built
ls nushell/target/release/nu_plugin_example
# Output: nushell/target/release/nu_plugin_example
```
**Why?** Excluded plugins are still useful for:
- Testing and validation
- Reference implementations
- Developer documentation
- Internal reference
---
### Task 4: Understand Distribution Workflow
**Scenario**: You want to understand how plugins flow through the build/collect/package process.
**Diagram**:
```
SOURCE (all plugins built)
├── nu_plugin_example (excluded)
├── nu_plugin_auth
├── nu_plugin_kms
└── ... others
↓ (just build - NO filtering)
BUILD OUTPUT (target/release)
├── nu_plugin_example ✅ (built)
├── nu_plugin_auth ✅ (built)
├── nu_plugin_kms ✅ (built)
└── ... others ✅ (built)
↓ (just collect - WITH filtering)
COLLECTION (distribution/)
├── nu_plugin_example ❌ (excluded)
├── nu_plugin_auth ✅ (collected)
├── nu_plugin_kms ✅ (collected)
└── ... others ✅ (collected)
↓ (just pack - WITH filtering)
PACKAGING (bin_archives/)
├── nushell-0.109.0-linux-x64.tar.gz
│ ├── nu
│ ├── nu_plugin_auth ✅
│ ├── nu_plugin_kms ✅
│ └── ... (no example plugin)
└── nushell-0.109.0-darwin-arm64.tar.gz
├── nu
├── nu_plugin_auth ✅
├── nu_plugin_kms ✅
└── ... (no example plugin)
↓ (installation)
USER SYSTEM
├── ~/.local/bin/nu ✅
├── ~/.local/bin/nu_plugin_auth ✅
├── ~/.local/bin/nu_plugin_kms ✅
├── ~/.config/nushell/env.nu
└── ~/.config/nushell/config.nu (auto-loads auth, kms; example not in list)
```
---
## Technical Details
### How Exclusion Works
**Mechanism**: The system reads `etc/plugin_registry.toml` and filters at two points:
1. **Collection** (`just collect` / `just collect-full`):
- Reads exclusion list from registry
- Skips excluded plugins during binary collection
- Result: `distribution/` dir doesn't have excluded plugins
2. **Packaging** (`just pack` / `just pack-full`):
- Reads exclusion list from registry
- Skips excluded plugins during package creation
- Result: `bin_archives/*.tar.gz` don't have excluded plugins
3. **Installation** (auto-load configuration):
- `scripts/templates/default_config.nu` manually removes excluded plugins from the auto-load list
- Result: User installations don't auto-load excluded plugins
### Files Involved
| File | Role |
|------|------|
| `etc/plugin_registry.toml` | Source of truth for exclusion list |
| `scripts/collect_full_binaries.nu` | Implements collection-time filtering |
| `scripts/create_distribution_packages.nu` | Implements packaging-time filtering |
| `scripts/templates/default_config.nu` | Defines auto-load list (manually edited) |
| `justfile` + `justfiles/*.just` | Provides build/collect/pack commands |
### Registry Format
```toml
[distribution]
excluded_plugins = [
"nu_plugin_example" # Plugin directory name
]
reason = "Reference plugin" # Documentation (optional)
```
**Key Points**:
- `excluded_plugins` is a list of plugin directory names (not binary names)
- Must match the `nu_plugin_*` directory in the repo
- Case-sensitive
- Empty list `[]` means no exclusions
---
## Troubleshooting
### Problem: Excluded Plugin Still Appears in Distribution
**Possible Causes**:
1. Registry file not saved properly
2. Collection script using cached data
3. Plugin name mismatch
**Solution**:
```bash
# Verify registry is correct
nu -c "open ./etc/plugin_registry.toml | get distribution.excluded_plugins"
# Clean and rebuild
rm -rf distribution bin_archives
just collect
find distribution -name "*example*" # Should be empty
```
---
### Problem: Can't Find Excluded Plugin After Build
**Expected Behavior**: Excluded plugins ARE still built (just not distributed)
**Verification**:
```bash
just build
ls nushell/target/release/nu_plugin_example # Should exist
# If it doesn't, the plugin may not be in the build system
just build-nushell --verbose
```
---
### Problem: Manual Plugin Registration Failing
**Issue**: User manually adds excluded plugin but it doesn't work
**Cause**: Plugin binary not in PATH
**Solution**:
```bash
# Build the plugin
just build
# Use full path
./nushell/target/release/nu_plugin_example --version
# Or install it manually
cp ./nushell/target/release/nu_plugin_example ~/.local/bin/
nu -c "plugin add ~/.local/bin/nu_plugin_example"
```
---
## FAQs
**Q: Will my excluded plugin still be tested?**
A: Yes. Excluded plugins are still built and tested. They're only excluded from user-facing distributions.
**Q: Can I exclude a plugin from builds but not distributions?**
A: No, the current system doesn't support this. The exclusion system only affects distribution. To exclude from builds, use Cargo features.
**Q: Can different distributions have different exclusion lists?**
A: Not currently, but this is planned as a future enhancement (profile-based exclusions).
**Q: What happens if I exclude a plugin that doesn't exist?**
A: It's ignored. The filtering works by checking if a plugin name is in the exclusion list, so non-existent plugins are silently skipped.
**Q: Can I exclude plugins selectively (e.g., exclude from macOS but not Linux)?**
A: Not currently. This would require platform-based exclusion profiles (future enhancement).
---
## Best Practices
### ✅ DO
- **Update the comment** in config when excluding/including plugins
- **Test after changes**: `just collect && just pack-full && just build`
- **Document the reason** in `plugin_registry.toml` (optional but recommended)
- **Run verification** before releases (see Release Manager checklist)
- **Keep registry clean** - don't exclude plugins you won't maintain
### ❌ DON'T
- **Edit multiple files** - only touch `etc/plugin_registry.toml` for the core change
- **Assume exclusion happens at build time** - it only happens during collect/pack
- **Forget to test** - exclusion changes should be verified before release
- **Add plugins to exclusion list without documenting why** in the code
- **Exclude plugins that users depend on** - use this only for reference/experimental plugins
---
## Integration with CI/CD
### GitHub Actions Example
```yaml
name: Distribution Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Verify exclusion list
- name: Verify Exclusion List
run: |
nu -c "open ./etc/plugin_registry.toml | get distribution.excluded_plugins"
# Build (includes all plugins)
- name: Build
run: just build-full-release
# Collect (excludes specified plugins)
- name: Collect
run: just collect-full
# Verify excluded plugins not in distribution
- name: Verify Exclusions
run: |
! find distribution -name "*example*"
# Package
- name: Package
run: just pack-full-checksums
# Release
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: bin_archives/*
```
---
## See Also
- **Architecture Details**: [`docs/architecture/PLUGIN_EXCLUSION_SYSTEM.md`](./architecture/PLUGIN_EXCLUSION_SYSTEM.md)
- **Build System**: [`docs/BUILDING.md`](./BUILDING.md)
- **Plugin Development**: `nushell/crates/nu_plugin_example/` (reference implementation)
- **Registry Configuration**: `etc/plugin_registry.toml`
---
**Version**: 1.0.0
**Last Updated**: 2025-12-03
**Status**: Stable