From f4d3a6472bb1861e34c061a554d8ce5fec6a3e86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesu=CC=81s=20Pe=CC=81rez?= Date: Sun, 28 Dec 2025 13:47:49 +0000 Subject: [PATCH] chore: add docs and example about nickel-roundtrip --- docs/nickel.md | 332 +++++++++++++++++- examples/06-integrations/nickel/README.md | 54 ++- .../01-generate-initial-config.sh | 25 ++ .../08-nickel-roundtrip/02-roundtrip-cli.sh | 33 ++ .../08-nickel-roundtrip/03-roundtrip-tui.sh | 33 ++ .../08-nickel-roundtrip/04-roundtrip-web.sh | 49 +++ examples/08-nickel-roundtrip/README.md | 260 ++++++++++++++ examples/08-nickel-roundtrip/ci-form.toml | 237 +++++++++++++ examples/08-nickel-roundtrip/config.ncl | 48 +++ examples/08-nickel-roundtrip/config.ncl.j2 | 52 +++ 10 files changed, 1112 insertions(+), 11 deletions(-) create mode 100755 examples/08-nickel-roundtrip/01-generate-initial-config.sh create mode 100755 examples/08-nickel-roundtrip/02-roundtrip-cli.sh create mode 100755 examples/08-nickel-roundtrip/03-roundtrip-tui.sh create mode 100755 examples/08-nickel-roundtrip/04-roundtrip-web.sh create mode 100644 examples/08-nickel-roundtrip/README.md create mode 100644 examples/08-nickel-roundtrip/ci-form.toml create mode 100644 examples/08-nickel-roundtrip/config.ncl create mode 100644 examples/08-nickel-roundtrip/config.ncl.j2 diff --git a/docs/nickel.md b/docs/nickel.md index 452b550..1e9b75b 100644 --- a/docs/nickel.md +++ b/docs/nickel.md @@ -104,15 +104,22 @@ let rendered = template_engine.render("form.j2", &context)?; ### roundtrip -Idempotent read/write for Nickel schemas. +Idempotent read/write for Nickel schemas - complete workflow from `.ncl` → form → `.ncl`. ```rust use typedialog_core::nickel::RoundtripConfig; -let config = RoundtripConfig::default(); -let schema = parser.parse_file("form.ncl")?; -let modified = transform(schema)?; -serializer.write_file("form.ncl", &modified, &config)?; +let mut config = RoundtripConfig::with_template( + input_ncl, // Path to existing .ncl file + form_toml, // Path to form definition + output_ncl, // Path for generated .ncl + template, // Optional .ncl.j2 template +); +config.validate = true; +config.verbose = true; + +// Execute with any backend (CLI, TUI, Web) +let result = config.execute_with_backend(backend.as_mut()).await?; ``` **Preserves:** @@ -121,6 +128,13 @@ serializer.write_file("form.ncl", &modified, &config)?; - Formatting - Import structure - Custom layouts +- Field contracts and validators + +**Returns:** + +- `RoundtripSummary` with diff viewer +- Validation status +- Change detection (what fields changed) ## Schema Structure @@ -188,6 +202,314 @@ serializer.write_file("form.ncl", &modified, &config)?; } ``` +## Roundtrip Workflow + +The roundtrip workflow enables interactive reconfiguration of existing Nickel files through forms, preserving structure and generating human-readable diffs. + +### Roundtrip Overview + +**Workflow:** `config.ncl` (input) → **Form** (edit) → `config.ncl` (output) + +1. **Load** existing `.ncl` configuration +2. **Extract** default values using `nickel_path` mappings +3. **Populate** form with current values +4. **Edit** via CLI/TUI/Web interface +5. **Generate** new `.ncl` using template (or preserve contracts) +6. **Validate** with `nickel typecheck` +7. **Show** summary with diff viewer + +### The `nickel_path` Attribute + +**Critical:** Fields MUST have `nickel_path` to participate in roundtrip. + +Maps form field names to nested Nickel structure: + +```toml +[[elements]] +name = "parallel_jobs" +type = "text" +prompt = "Parallel Jobs" +default = "4" +nickel_path = ["ci", "github_actions", "parallel_jobs"] +``` + +Extracts from: + +```nickel +{ + ci = { + github_actions = { + parallel_jobs = 4 + } + } +} +``` + +**Rules:** + +- Array of strings representing path +- Each element is a nested key +- Top-level: `["field_name"]` +- Nested: `["parent", "child", "field"]` +- Arrays: Use RepeatingGroup with `nickel_path = ["array_name"]` + +### Roundtrip with CLI Backend + +```bash +typedialog nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 \ + --verbose +``` + +**Output:** + +```text +╔════════════════════════════════════════════════════════════╗ +║ ✅ Configuration Saved Successfully! ║ +╠════════════════════════════════════════════════════════════╣ +║ 📄 File: config.ncl ║ +║ ✓ Validation: ✓ PASSED ║ +║ 📊 Fields: 5/27 changed, 22 unchanged ║ +╠════════════════════════════════════════════════════════════╣ +║ 📋 What Changed: ║ +║ ├─ parallel_jobs: 4 → 8 ║ +║ ├─ timeout_minutes: 60 → 120 ║ +║ ├─ enable_clippy: true → false ║ +║ ├─ rust_version: stable → nightly ║ +║ ├─ cache_enabled: false → true ║ +╠════════════════════════════════════════════════════════════╣ +║ 💡 Next Steps: ║ +║ • Review: cat config.ncl ║ +║ • Apply CI tools: ./setup-ci.sh ║ +║ • Re-configure: ./ci-configure.sh ║ +╚════════════════════════════════════════════════════════════╝ +``` + +### Roundtrip with TUI Backend + +```bash +typedialog-tui nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 +``` + +Interactive TUI form + terminal summary (same as CLI). + +### Roundtrip with Web Backend + +```bash +typedialog-web nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 \ + --verbose +``` + +**Features:** + +- Opens browser to `http://localhost:8080` +- All fields pre-populated with current values +- Real-time validation +- **Summary page** on submit: + - Visual diff viewer (old → new) + - Field statistics + - Download button for generated config + - Auto-close after 30 seconds + +**Terminal output:** + +```text +Starting interactive form on http://localhost:8080 +Complete the form and submit to continue... + +Web UI available at http://localhost:8080 +[web] Complete form initialized with 63 default values + +╔════════════════════════════════════════════════════════════╗ +║ ✅ Configuration Saved Successfully! ║ +╠════════════════════════════════════════════════════════════╣ +... +``` + +### Form Requirements + +For roundtrip to work, your form MUST: + +1. **Include `nickel_path` on ALL fields:** + + ```toml + [[elements]] + name = "project_name" + nickel_path = ["project", "name"] # ✅ Required + ``` + +2. **Use correct path syntax:** + + ```toml + # Flat field + nickel_path = ["enable_ci"] + + # Nested field + nickel_path = ["ci", "github_actions", "timeout"] + + # Array field (RepeatingGroup) + nickel_path = ["ci", "tools", "linters"] + ``` + +3. **Match template variables:** + + ```jinja2 + # Template: config.ncl.j2 + { + project = { + name = "{{ project_name }}", # ← Form field "project_name" + }, + ci = { + enabled = {{ enable_ci }}, # ← Form field "enable_ci" + } + } + ``` + +### Template Support + +Use Tera templates (`.ncl.j2`) for complex output structures: + +**Template:** `config.ncl.j2` + +```jinja2 +# Generated by TypeDialog +let imports = import "ci/lib.ncl" +let validators = import "ci/validators.ncl" + +{ + project = { + name = "{{ project_name }}", + version = "{{ project_version }}", + }, + + ci = { + github_actions = { + enabled = {{ enable_github_actions }}, + parallel_jobs = {{ parallel_jobs }}, + timeout_minutes = {{ timeout_minutes }}, + + {% if enable_cache %} + cache = { + enabled = true, + paths = {{ cache_paths | json }}, + }, + {% endif %} + }, + + tools = { + {% for tool in ci_tools %} + {{ tool.name }} = { + enabled = {{ tool.enabled }}, + version = "{{ tool.version }}", + }, + {% endfor %} + }, + } +} | validators.CiConfig +``` + +**Form values are injected automatically.** + +### Complete Example + +See `examples/08-nickel-roundtrip/` for a full CI configuration workflow: + +```bash +cd examples/08-nickel-roundtrip/ + +# Initial setup +./01-generate-initial-config.sh + +# Edit with CLI +./02-roundtrip-cli.sh + +# Edit with TUI +./03-roundtrip-tui.sh + +# Edit with Web +./04-roundtrip-web.sh +``` + +### Validation + +Roundtrip automatically validates output: + +```bash +typedialog nickel-roundtrip \ + --input config.ncl \ + --form form.toml \ + --output config.ncl \ + --ncl-template template.ncl.j2 +# Runs: nickel typecheck config.ncl +``` + +**Disable validation:** + +```bash +typedialog nickel-roundtrip ... --no-validate +``` + +### Summary Output + +All backends generate summaries showing: + +- **Total fields:** How many fields in the form +- **Changed fields:** Fields with different values +- **Unchanged fields:** Fields that kept the same value +- **Validation status:** Pass/fail from `nickel typecheck` +- **Change list:** Detailed old → new for each change + +**Verbose mode** shows ALL changes (not just first 10): + +```bash +typedialog nickel-roundtrip ... --verbose +``` + +### Roundtrip Troubleshooting + +**Issue: "No default values loaded"** + +✓ Check all fields have `nickel_path`: + +```bash +grep -r "nickel_path" form.toml +``` + +**Issue: "Field not found in output"** + +✓ Verify template includes the field: + +```bash +grep "{{ field_name }}" template.ncl.j2 +``` + +**Issue: "Validation failed"** + +✓ Check Nickel syntax manually: + +```bash +nickel typecheck config.ncl +``` + +**Issue: "Values not showing in web form"** + +✓ Ensure `nickel export` works on input: + +```bash +nickel export config.ncl +``` + ## Building with Nickel Build project with Nickel support: diff --git a/examples/06-integrations/nickel/README.md b/examples/06-integrations/nickel/README.md index 9830cfb..a3dfd82 100644 --- a/examples/06-integrations/nickel/README.md +++ b/examples/06-integrations/nickel/README.md @@ -1,6 +1,6 @@ # Nickel Integration -Type-safe form schema generation using Nickel configuration language. +Type-safe form schema generation and roundtrip workflows using Nickel configuration language. ## Files @@ -10,10 +10,12 @@ Type-safe form schema generation using Nickel configuration language. ## About Nickel Nickel is a powerful configuration language that provides: + - Strong typing - Validation rules - Reusable schemas - Inheritance and composition +- **Roundtrip support** - Edit existing configs via forms ## Usage @@ -30,6 +32,44 @@ nickel eval nickel_schema.ncl > form_config.toml cargo run -p typedialog-web -- --config form_config.toml ``` +### Roundtrip Workflow (Edit Existing Configs) + +**New!** Edit existing Nickel configurations through interactive forms: + +```bash +# CLI backend (command-line prompts) +typedialog nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 + +# TUI backend (full-screen terminal UI) +typedialog-tui nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 + +# Web backend (browser-based form with HTML diff) +typedialog-web nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 +``` + +**Features:** + +- ✓ Load existing values from `.ncl` files +- ✓ Pre-populate form fields with current config +- ✓ Generate new `.ncl` using templates +- ✓ Show diff summary (what changed) +- ✓ Automatic validation with `nickel typecheck` +- ✓ HTML summary page (web backend only) + +**See complete example:** `../08-nickel-roundtrip/` + ### Example Nickel Schema ```nickel @@ -57,11 +97,13 @@ cargo run -p typedialog-web -- --config form_config.toml ## Advanced Features -- Field inheritance -- Custom validators -- Conditional schemas -- Template-driven generation -- Schema composition +- **Field inheritance** - Reuse common field definitions +- **Custom validators** - Built-in schema validation +- **Conditional schemas** - Dynamic form generation +- **Template-driven generation** - Tera template support +- **Schema composition** - Combine multiple schemas +- **Roundtrip editing** - Edit existing configs via forms (NEW!) +- **Diff viewer** - See what changed after editing (NEW!) ## Learn More diff --git a/examples/08-nickel-roundtrip/01-generate-initial-config.sh b/examples/08-nickel-roundtrip/01-generate-initial-config.sh new file mode 100755 index 0000000..c329c48 --- /dev/null +++ b/examples/08-nickel-roundtrip/01-generate-initial-config.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +echo "📝 Generating initial CI configuration..." +echo "" + +# config.ncl is already provided as the initial state +if [ -f "config.ncl" ]; then + echo "✅ Initial config.ncl already exists" + echo "" + echo "Current configuration:" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + cat config.ncl + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + echo "Next steps:" + echo " ./02-roundtrip-cli.sh # Edit with CLI backend" + echo " ./03-roundtrip-tui.sh # Edit with TUI backend" + echo " ./04-roundtrip-web.sh # Edit with Web backend" +else + echo "❌ config.ncl not found!" + exit 1 +fi diff --git a/examples/08-nickel-roundtrip/02-roundtrip-cli.sh b/examples/08-nickel-roundtrip/02-roundtrip-cli.sh new file mode 100755 index 0000000..1cdaced --- /dev/null +++ b/examples/08-nickel-roundtrip/02-roundtrip-cli.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +echo "🔧 Running nickel-roundtrip with CLI backend..." +echo "" + +# Check if config.ncl exists +if [ ! -f "config.ncl" ]; then + echo "❌ config.ncl not found! Run ./01-generate-initial-config.sh first" + exit 1 +fi + +# Backup current config +cp config.ncl "config.ncl.backup.$(date +%Y%m%d_%H%M%S)" + +# Run roundtrip with CLI backend +cargo run -p typedialog --release -- nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 \ + --verbose + +echo "" +echo "✅ Roundtrip completed!" +echo "" +echo "Review changes:" +echo " cat config.ncl" +echo "" +echo "Run again:" +echo " ./02-roundtrip-cli.sh" diff --git a/examples/08-nickel-roundtrip/03-roundtrip-tui.sh b/examples/08-nickel-roundtrip/03-roundtrip-tui.sh new file mode 100755 index 0000000..7839242 --- /dev/null +++ b/examples/08-nickel-roundtrip/03-roundtrip-tui.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +echo "🎨 Running nickel-roundtrip with TUI backend..." +echo "" + +# Check if config.ncl exists +if [ ! -f "config.ncl" ]; then + echo "❌ config.ncl not found! Run ./01-generate-initial-config.sh first" + exit 1 +fi + +# Backup current config +cp config.ncl "config.ncl.backup.$(date +%Y%m%d_%H%M%S)" + +# Run roundtrip with TUI backend +cargo run -p typedialog-tui --release -- nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 \ + --verbose + +echo "" +echo "✅ Roundtrip completed!" +echo "" +echo "Review changes:" +echo " cat config.ncl" +echo "" +echo "Run again:" +echo " ./03-roundtrip-tui.sh" diff --git a/examples/08-nickel-roundtrip/04-roundtrip-web.sh b/examples/08-nickel-roundtrip/04-roundtrip-web.sh new file mode 100755 index 0000000..a03d6b7 --- /dev/null +++ b/examples/08-nickel-roundtrip/04-roundtrip-web.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "$0")" + +echo "🌐 Running nickel-roundtrip with Web backend..." +echo "" + +# Check if config.ncl exists +if [ ! -f "config.ncl" ]; then + echo "❌ config.ncl not found! Run ./01-generate-initial-config.sh first" + exit 1 +fi + +# Backup current config +cp config.ncl "config.ncl.backup.$(date +%Y%m%d_%H%M%S)" + +echo "Starting web server on http://localhost:8080" +echo "Your browser should open automatically..." +echo "" +echo "Features:" +echo " ✓ All fields pre-populated with current values" +echo " ✓ Real-time validation" +echo " ✓ HTML diff viewer on submit" +echo " ✓ Download button for config.ncl" +echo " ✓ Auto-close after 30 seconds" +echo "" +echo "Press Ctrl+C after form is submitted to exit" +echo "" + +# Open browser (macOS) +sleep 2 && open "http://localhost:8080" & + +# Run roundtrip with Web backend +cargo run -p typedialog-web --release -- nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 \ + --verbose + +echo "" +echo "✅ Roundtrip completed!" +echo "" +echo "Review changes:" +echo " cat config.ncl" +echo "" +echo "Run again:" +echo " ./04-roundtrip-web.sh" diff --git a/examples/08-nickel-roundtrip/README.md b/examples/08-nickel-roundtrip/README.md new file mode 100644 index 0000000..fb82dbb --- /dev/null +++ b/examples/08-nickel-roundtrip/README.md @@ -0,0 +1,260 @@ +# Nickel Roundtrip Example + +Complete example demonstrating the roundtrip workflow: load existing configuration, edit via interactive form, and regenerate with diff viewer. + +## Scenario + +CI configuration management - edit GitHub Actions settings through a form interface while preserving the Nickel structure. + +## Files + +- **config.ncl** - Input/output Nickel configuration +- **ci-form.toml** - Form definition with `nickel_path` mappings +- **config.ncl.j2** - Tera template for generating output +- **01-generate-initial-config.sh** - Create initial config +- **02-roundtrip-cli.sh** - Edit via CLI backend +- **03-roundtrip-tui.sh** - Edit via TUI backend +- **04-roundtrip-web.sh** - Edit via Web backend + +## Quick Start + +```bash +# 1. Generate initial configuration +./01-generate-initial-config.sh + +# 2. Edit with your preferred backend: + +# CLI (command-line prompts) +./02-roundtrip-cli.sh + +# TUI (full-screen terminal UI) +./03-roundtrip-tui.sh + +# Web (browser-based form) +./04-roundtrip-web.sh +``` + +## Key Features + +### `nickel_path` Mapping + +Every field in `ci-form.toml` has a `nickel_path` attribute mapping to the Nickel structure: + +```toml +[[elements]] +name = "parallel_jobs" +type = "text" +prompt = "Parallel Jobs" +default = "4" +nickel_path = ["ci", "github_actions", "parallel_jobs"] +``` + +Maps to: + +```nickel +{ + ci = { + github_actions = { + parallel_jobs = 4 + } + } +} +``` + +### Template Rendering + +The `config.ncl.j2` template uses form values to generate valid Nickel: + +```jinja2 +{ + project = { + name = "{{ project_name }}", + description = "{{ project_description }}", + }, + + ci = { + github_actions = { + enabled = {{ enable_github_actions }}, + parallel_jobs = {{ parallel_jobs }}, + timeout_minutes = {{ timeout_minutes }}, + } + } +} +``` + +### Summary with Diff + +After editing, see what changed: + +```text +╔════════════════════════════════════════════════════════════╗ +║ ✅ Configuration Saved Successfully! ║ +╠════════════════════════════════════════════════════════════╣ +║ 📄 File: config.ncl ║ +║ ✓ Validation: ✓ PASSED ║ +║ 📊 Fields: 3/12 changed, 9 unchanged ║ +╠════════════════════════════════════════════════════════════╣ +║ 📋 What Changed: ║ +║ ├─ parallel_jobs: 4 → 8 ║ +║ ├─ timeout_minutes: 60 → 120 ║ +║ ├─ enable_cache: false → true ║ +╠════════════════════════════════════════════════════════════╣ +║ 💡 Next Steps: ║ +║ • Review: cat config.ncl ║ +║ • Apply CI tools: ./setup-ci.sh ║ +║ • Re-configure: ./ci-configure.sh ║ +╚════════════════════════════════════════════════════════════╝ +``` + +## Workflow Details + +### 1. Load Defaults + +Roundtrip reads `config.ncl` and extracts values using `nickel_path`: + +```rust +// Internally: +nickel export config.ncl // → JSON +extract_value_by_path(json, ["ci", "github_actions", "parallel_jobs"]) // → 4 +``` + +### 2. Populate Form + +Form fields get pre-filled with current values: + +- Text fields show current text +- Numbers show current numbers +- Booleans show current true/false +- Select fields pre-select current option + +### 3. Edit Interactively + +User edits via chosen backend (CLI/TUI/Web). + +### 4. Generate Output + +Template renders with new values: + +```jinja2 +parallel_jobs = {{ parallel_jobs }}, // User changed 4 → 8 +``` + +### 5. Validate + +Automatic validation: + +```bash +nickel typecheck config.ncl +``` + +### 6. Show Summary + +Terminal summary (all backends) + HTML summary (web only). + +## Backend Comparison + +| Feature | CLI | TUI | Web | +|---------|-----|-----|-----| +| Terminal UI | ✓ | ✓ | ✓ (summary only) | +| Browser UI | ✗ | ✗ | ✓ | +| Pre-populated values | ✓ | ✓ | ✓ | +| Real-time validation | ✗ | ✓ | ✓ | +| HTML diff viewer | ✗ | ✗ | ✓ | +| Download button | ✗ | ✗ | ✓ | + +## Customization + +### Add More Fields + +1. **Update form:** + + ```toml + [[elements]] + name = "rust_version" + type = "select" + prompt = "Rust Version" + options = [ + { value = "stable", label = "Stable" }, + { value = "nightly", label = "Nightly" } + ] + nickel_path = ["ci", "rust", "version"] + ``` + +2. **Update template:** + + ```jinja2 + ci = { + rust = { + version = "{{ rust_version }}", + } + } + ``` + +3. **Update initial config:** + + ```nickel + { + ci = { + rust = { + version = "stable" + } + } + } + ``` + +### Change Template Logic + +Add conditionals: + +```jinja2 +{% if enable_cache %} +cache = { + enabled = true, + paths = {{ cache_paths | json }}, +}, +{% endif %} +``` + +### Disable Validation + +```bash +typedialog nickel-roundtrip \ + --input config.ncl \ + --form ci-form.toml \ + --output config.ncl \ + --ncl-template config.ncl.j2 \ + --no-validate # ← Skip nickel typecheck +``` + +## Troubleshooting + +**No defaults loaded:** + +```bash +# Check nickel export works +nickel export config.ncl + +# Verify all fields have nickel_path +grep "nickel_path" ci-form.toml | wc -l +``` + +**Template errors:** + +```bash +# Test template separately +echo '{"project_name": "test"}' | \ + tera --template config.ncl.j2 +``` + +**Validation fails:** + +```bash +# Check manually +nickel typecheck config.ncl +``` + +## Learn More + +- [nickel.md](../../docs/nickel.md) - Full roundtrip documentation +- [Nickel Language](https://nickel-lang.org) - Nickel reference +- [Tera Templates](https://tera.netlify.app) - Template syntax diff --git a/examples/08-nickel-roundtrip/ci-form.toml b/examples/08-nickel-roundtrip/ci-form.toml new file mode 100644 index 0000000..909f8a0 --- /dev/null +++ b/examples/08-nickel-roundtrip/ci-form.toml @@ -0,0 +1,237 @@ +name = "CI Configuration Editor" +description = "Interactive form for editing CI/CD configuration" +display_mode = "complete" + +# ============================================================================= +# PROJECT INFORMATION +# ============================================================================= + +[[elements]] +name = "project_header" +type = "section_header" +title = "📦 Project Information" +border_top = true +border_bottom = true + +[[elements]] +name = "project_name" +type = "text" +prompt = "Project Name" +required = true +default = "my-rust-project" +nickel_path = ["project", "name"] + +[[elements]] +name = "project_description" +type = "text" +prompt = "Project Description" +required = true +default = "A Rust project with CI/CD" +nickel_path = ["project", "description"] + +[[elements]] +name = "project_repository" +type = "text" +prompt = "Repository URL" +required = true +default = "https://github.com/example/my-rust-project" +nickel_path = ["project", "repository"] + +# ============================================================================= +# GITHUB ACTIONS CONFIGURATION +# ============================================================================= + +[[elements]] +name = "github_header" +type = "section_header" +title = "🚀 GitHub Actions Configuration" +border_top = true +border_bottom = true + +[[elements]] +name = "enable_github_actions" +type = "confirm" +prompt = "Enable GitHub Actions CI?" +default = true +nickel_path = ["ci", "github_actions", "enabled"] + +[[elements]] +name = "parallel_jobs" +type = "text" +prompt = "Parallel Jobs" +default = "4" +when = "enable_github_actions == true" +help = "Number of parallel CI jobs (1-20)" +nickel_path = ["ci", "github_actions", "parallel_jobs"] + +[[elements]] +name = "timeout_minutes" +type = "text" +prompt = "Job Timeout (minutes)" +default = "60" +when = "enable_github_actions == true" +help = "Maximum duration for each job" +nickel_path = ["ci", "github_actions", "timeout_minutes"] + +# ============================================================================= +# RUST CONFIGURATION +# ============================================================================= + +[[elements]] +name = "rust_header" +type = "section_header" +title = "🦀 Rust Configuration" +border_top = true +border_bottom = true +when = "enable_github_actions == true" + +[[elements]] +name = "rust_version" +type = "select" +prompt = "Rust Version" +default = "stable" +when = "enable_github_actions == true" +options = [ + { value = "stable", label = "Stable - Latest stable release" }, + { value = "nightly", label = "Nightly - Cutting edge features" }, + { value = "1.70.0", label = "1.70.0 - Specific version" }, +] +nickel_path = ["ci", "github_actions", "rust", "version"] + +# ============================================================================= +# CACHING +# ============================================================================= + +[[elements]] +name = "cache_header" +type = "section_header" +title = "💾 Build Cache" +border_top = true +border_bottom = true +when = "enable_github_actions == true" + +[[elements]] +name = "enable_cache" +type = "confirm" +prompt = "Enable dependency caching?" +default = false +when = "enable_github_actions == true" +help = "Cache Cargo dependencies to speed up builds" +nickel_path = ["ci", "github_actions", "cache", "enabled"] + +# ============================================================================= +# TOOLS CONFIGURATION +# ============================================================================= + +[[elements]] +name = "tools_header" +type = "section_header" +title = "🔧 CI Tools" +border_top = true +border_bottom = true +when = "enable_github_actions == true" + +[[elements]] +name = "enable_clippy" +type = "confirm" +prompt = "Enable cargo clippy (linter)?" +default = true +when = "enable_github_actions == true" +help = "Run Rust linter on code" +nickel_path = ["ci", "github_actions", "tools", "clippy", "enabled"] + +[[elements]] +name = "clippy_args" +type = "text" +prompt = "Clippy Arguments" +default = "-D warnings" +when = "enable_github_actions == true && enable_clippy == true" +help = "Command-line arguments for clippy" +nickel_path = ["ci", "github_actions", "tools", "clippy", "args"] + +[[elements]] +name = "enable_rustfmt" +type = "confirm" +prompt = "Enable rustfmt (formatter)?" +default = true +when = "enable_github_actions == true" +help = "Check code formatting" +nickel_path = ["ci", "github_actions", "tools", "rustfmt", "enabled"] + +[[elements]] +name = "rustfmt_edition" +type = "select" +prompt = "Rust Edition for rustfmt" +default = "2021" +when = "enable_github_actions == true && enable_rustfmt == true" +options = [ + { value = "2015", label = "2015" }, + { value = "2018", label = "2018" }, + { value = "2021", label = "2021" }, +] +nickel_path = ["ci", "github_actions", "tools", "rustfmt", "edition"] + +[[elements]] +name = "enable_cargo_audit" +type = "confirm" +prompt = "Enable cargo-audit (security)?" +default = false +when = "enable_github_actions == true" +help = "Scan for security vulnerabilities" +nickel_path = ["ci", "github_actions", "tools", "cargo_audit", "enabled"] + +# ============================================================================= +# DEPLOYMENT +# ============================================================================= + +[[elements]] +name = "deployment_header" +type = "section_header" +title = "🚢 Deployment" +border_top = true +border_bottom = true + +[[elements]] +name = "enable_deployment" +type = "confirm" +prompt = "Enable deployment?" +default = false +help = "Automatically deploy on successful builds" +nickel_path = ["deployment", "enabled"] + +[[elements]] +name = "deployment_environment" +type = "select" +prompt = "Deployment Environment" +default = "production" +when = "enable_deployment == true" +options = [ + { value = "development", label = "Development" }, + { value = "staging", label = "Staging" }, + { value = "production", label = "Production" }, +] +nickel_path = ["deployment", "environment"] + +[[elements]] +name = "auto_deploy" +type = "confirm" +prompt = "Auto-deploy on main branch?" +default = false +when = "enable_deployment == true" +help = "Automatically deploy when main branch is updated" +nickel_path = ["deployment", "auto_deploy"] + +# ============================================================================= +# SUMMARY +# ============================================================================= + +[[elements]] +name = "summary_header" +type = "section_header" +title = "✅ Review & Save" +border_top = true + +[[elements]] +name = "summary" +type = "section" +content = "Review your configuration above. Click Submit to save and see what changed." diff --git a/examples/08-nickel-roundtrip/config.ncl b/examples/08-nickel-roundtrip/config.ncl new file mode 100644 index 0000000..4324401 --- /dev/null +++ b/examples/08-nickel-roundtrip/config.ncl @@ -0,0 +1,48 @@ +# CI Configuration +# Generated by TypeDialog - Edit via ci-configure.sh + +{ + project = { + name = "my-rust-project", + description = "A Rust project with CI/CD", + repository = "https://github.com/example/my-rust-project", + }, + + ci = { + github_actions = { + enabled = true, + parallel_jobs = 4, + timeout_minutes = 60, + + rust = { + version = "stable", + targets = ["x86_64-unknown-linux-gnu"], + }, + + cache = { + enabled = false, + paths = [], + }, + + tools = { + clippy = { + enabled = true, + args = ["-D", "warnings"], + }, + rustfmt = { + enabled = true, + edition = "2021", + }, + cargo_audit = { + enabled = false, + }, + }, + }, + }, + + deployment = { + enabled = false, + environment = "production", + auto_deploy = false, + }, +} diff --git a/examples/08-nickel-roundtrip/config.ncl.j2 b/examples/08-nickel-roundtrip/config.ncl.j2 new file mode 100644 index 0000000..0f46795 --- /dev/null +++ b/examples/08-nickel-roundtrip/config.ncl.j2 @@ -0,0 +1,52 @@ +# CI Configuration +# Generated by TypeDialog - Edit via ci-configure.sh + +{ + project = { + name = "{{ project_name }}", + description = "{{ project_description }}", + repository = "{{ project_repository }}", + }, + + ci = { + github_actions = { + enabled = {{ enable_github_actions }}, + parallel_jobs = {{ parallel_jobs }}, + timeout_minutes = {{ timeout_minutes }}, + + rust = { + version = "{{ rust_version }}", + targets = ["x86_64-unknown-linux-gnu"], + }, + + cache = { + enabled = {{ enable_cache }}, + paths = [], + }, + + tools = { + clippy = { + enabled = {{ enable_clippy }}, + {% if enable_clippy and clippy_args %} + args = {{ clippy_args | split(pat=" ") | json }}, + {% else %} + args = [], + {% endif %} + }, + rustfmt = { + enabled = {{ enable_rustfmt }}, + edition = "{{ rustfmt_edition }}", + }, + cargo_audit = { + enabled = {{ enable_cargo_audit }}, + }, + }, + }, + }, + + deployment = { + enabled = {{ enable_deployment }}, + environment = "{{ deployment_environment }}", + auto_deploy = {{ auto_deploy }}, + }, +}