provisioning/docs/src/architecture/adr/adr-012-nushell-nickel-plugin-cli-wrapper.md

2 lines
11 KiB
Markdown
Raw Normal View History

# ADR-014: Nushell Nickel Plugin - CLI Wrapper Architecture\n\n## Status\n\n**Accepted** - 2025-12-15\n\n## Context\n\nThe provisioning system integrates with Nickel for configuration management in advanced\nscenarios. Users need to evaluate Nickel files and work with their output in Nushell\nscripts. The `nu_plugin_nickel` plugin provides this integration.\n\nThe architectural decision was whether the plugin should:\n\n1. **Implement Nickel directly using pure Rust** (`nickel-lang-core` crate)\n2. **Wrap the official Nickel CLI** (`nickel` command)\n\n### System Requirements\n\nNickel configurations in provisioning use the **module system**:\n\n```\n# config/database.ncl\nimport "lib/defaults" as defaults\nimport "lib/validation" as valid\n\n{\n databases: {\n primary = defaults.database & {\n name = "primary"\n host = "localhost"\n }\n }\n}\n```\n\nModule system includes:\n\n- Import resolution with search paths\n- Standard library (`builtins`, stdlib packages)\n- Module caching\n- Complex evaluation context\n\n## Decision\n\nImplement the `nu_plugin_nickel` plugin as a **CLI wrapper** that invokes the external `nickel` command.\n\n### Architecture Diagram\n\n```\n┌─────────────────────────────┐\n│ Nushell Script │\n│ │\n│ nickel-export json /file │\n│ nickel-eval /file │\n│ nickel-format /file │\n└────────────┬────────────────┘\n │\n ▼\n┌─────────────────────────────┐\n│ nu_plugin_nickel │\n│ │\n│ - Command handling │\n│ - Argument parsing │\n│ - JSON output parsing │\n│ - Caching logic │\n└────────────┬────────────────┘\n │\n ▼\n┌─────────────────────────────┐\n│ std::process::Command │\n│ │\n│ "nickel export /file ..." │\n└────────────┬────────────────┘\n │\n ▼\n┌─────────────────────────────┐\n│ Nickel Official CLI │\n│ │\n│ - Module resolution │\n│ - Import handling │\n│ - Standard library access │\n│ - Output formatting │\n│ - Error reporting │\n└────────────┬────────────────┘\n │\n ▼\n┌─────────────────────────────┐\n│ Nushell Records/Lists │\n│ │\n│ ✅ Proper types │\n│ ✅ Cell path access works │\n│ ✅ Piping works │\n└─────────────────────────────┘\n```\n\n### Implementation Characteristics\n\n**Plugin provides**:\n\n- ✅ Nushell commands: `nickel-export`, `nickel-eval`, `nickel-format`, `nickel-validate`\n- ✅ JSON/YAML output parsing (serde_json → nu_protocol::Value)\n- ✅ Automatic caching (SHA256-based, ~80-90% hit rate)\n- ✅ Error handling (CLI errors → Nushell errors)\n- ✅ Type-safe output (nu_protocol::Value::Record, not strings)\n\n**Plugin delegates to Nickel CLI**:\n\n- ✅ Module resolution with search paths\n- ✅ Standard library access and discovery\n- ✅ Evaluation context setup\n- ✅ Module caching\n- ✅ Output formatting\n\n## Rationale\n\n### Why CLI Wrapper Is The Correct Choice\n\n| Aspect | Pure Rust (nickel-lang-core) | CLI Wrapper (chosen) |\n| -------- | ------------------------------- | ---------------------- |\n| **Module resol