Skip to content

Add JSON output format support to create command#351

Merged
josecelano merged 5 commits intomainfrom
349-add-json-output-to-create-command
Feb 16, 2026
Merged

Add JSON output format support to create command#351
josecelano merged 5 commits intomainfrom
349-add-json-output-to-create-command

Conversation

@josecelano
Copy link
Copy Markdown
Member

Summary

Implements issue #349 - Adds machine-readable JSON output format to the create environment command, enabling automation workflows and CI/CD integration.

Changes

Architecture (5 Phases)

Phase 0: View Layer Extraction (67c10ff)

  • Extracted view layer for create command following MVC pattern
  • Created EnvironmentDetailsData DTO and EnvironmentDetailsView
  • Aligned with existing provision/list/show command architecture

Phase 1: Global OutputFormat Argument (7ce64b0)

  • Added OutputFormat enum (Text | Json) with clap integration
  • Added --output-format global CLI argument
  • Extended GlobalArgs and ExecutionContext with format support

Phase 2: Strategy Pattern Implementation (2ecb391)

  • Separated TextView and JsonView implementations
  • Applied SOLID principles with Strategy Pattern
  • Added Serialize derive to EnvironmentDetailsData

Phase 3: Format Switching (afa7ef9)

  • Wired output_format through ExecutionContext → Router → Controller
  • Implemented format switching with match expression
  • Added OutputFormatting error variant with detailed help

Phase 4: Documentation (ad2ac21)

  • Added comprehensive "Output Formats" section to user guide
  • Documented JSON schema with field descriptions
  • Added 8+ automation examples (Shell, CI/CD, Python, multi-env)
  • Explained stdout/stderr channel separation

Features

Two Output Formats:

  • Text (default): Human-readable numbered list with progress indicators
  • JSON: Machine-readable structured data for automation

JSON Output Schema:

{
  "environment_name": "my-env",
  "instance_name": "torrust-tracker-vm-my-env",
  "data_dir": "./data/my-env",
  "build_dir": "./build/my-env",
  "created_at": "2026-02-16T13:38:02.446056727Z"
}

CLI Usage:

# Default text output
torrust-tracker-deployer create environment --env-file config.json

# JSON output for automation
torrust-tracker-deployer create environment --env-file config.json --output-format json

# Short form
torrust-tracker-deployer create environment --env-file config.json -o json

Quality Assurance

  • ✅ All 2230 unit tests pass
  • ✅ All 394 doctests pass
  • ✅ All linters pass (clippy, rustfmt, markdown, yaml, toml, cspell, shellcheck)
  • ✅ Pre-commit checks pass
  • ✅ E2E testing completed:
    • Default text output verified
    • JSON output validated with jq
    • Error handling tested
    • Channel separation confirmed (stdout/stderr)
  • ✅ No unused dependencies (cargo-machete clean)

Documentation

  • User guide updated with comprehensive examples
  • JSON schema documented with field descriptions
  • Automation examples for Shell, CI/CD, Python
  • Output channel separation explained
  • Usage guidelines included

Testing

Manual Verification

# Text output (default)
./target/release/torrust-tracker-deployer create environment \
  --env-file envs/test.json

# JSON output
./target/release/torrust-tracker-deployer create environment \
  --env-file envs/test.json \
  --output-format json

# JSON validation with jq
./target/release/torrust-tracker-deployer create environment \
  --env-file envs/test.json \
  -o json \
  --log-output file-only | jq .

Automation Example

# Extract environment details
DATA_DIR=$(./target/release/torrust-tracker-deployer create environment \
  --env-file config.json \
  -o json \
  --log-output file-only | jq -r '.data_dir')

Related

Breaking Changes

None. This is a backward-compatible addition. Default behavior (text output) is preserved.

Future Work

This implementation provides the foundation for adding JSON output to other commands:

Extract output formatting logic from controller to view layer, matching
the MVC pattern used by provision, list, and show commands.

Changes:
- Create src/presentation/views/commands/create/ module
- Add EnvironmentDetailsData struct (presentation DTO)
- Add EnvironmentDetailsView with render_human_readable() method
- Implement From<&Environment<Created>> for data conversion
- Update controller to delegate formatting to view
- Add 3 unit tests for view rendering logic

Testing:
- All 426 tests pass
- Golden test output unchanged (backward compatible)
- View layer independently testable

This refactoring is a prerequisite for adding JSON output support.
The view layer separation makes format switching straightforward.

Related: #349 (Phase 0 of 5)
- Add OutputFormat enum with Text (default) and Json variants
- Add output_format field to GlobalArgs (global CLI argument)
- Update specification to document OutputFormat approach
- Follow existing LogFormat pattern for consistency

This is Phase 1: CLI argument infrastructure.
Phases 2-3 will implement JSON rendering in views and controllers.
Split view into separate format-specific views following SOLID principles:

- environment_details.rs: DTO only (data structure)
- text_view.rs: Human-readable text rendering
- json_view.rs: Machine-readable JSON rendering

Benefits:
- Open/Closed Principle: Add formats without modifying existing code
- Single Responsibility: Each view has one job
- Strategy Pattern: Different rendering strategies for same data
- Scalability: Easy to add XML, YAML, CSV, etc.

Updated:
- Controller now uses TextView::render() instead of EnvironmentDetailsView
- Module exports TextView and JsonView separately
- All tests pass (6 view tests, 41 controller tests)

This refactor makes Phase 3 (format switching) cleaner and more maintainable.
- Add global --output-format argument (text|json) to CLI
- Implement Strategy Pattern with TextView and JsonView
- Wire output_format through ExecutionContext to controllers
- Add format switching logic in create environment handler
- Create test helper default_global_args() for test contexts
- Add OutputFormatting error variant with detailed help
- Update all doctests to use new ExecutionContext signature
- Fix clippy issues (doc backticks, inline format args)

The implementation follows SOLID principles with clear separation
between data (EnvironmentDetailsData), rendering strategies
(TextView/JsonView), and controller orchestration.
- Add comprehensive Output Formats section to create command guide
- Document JSON schema with field descriptions and table
- Add automation examples (Shell, CI/CD, Python, multi-env scripts)
- Explain output channel separation (stdout vs stderr)
- Add usage guidelines for text vs JSON format selection
- Include validation and debugging examples with jq
- Update common options to include --output-format flag
- Mark Phase 4 documentation complete in issue spec
@josecelano josecelano self-assigned this Feb 16, 2026
@josecelano
Copy link
Copy Markdown
Member Author

ACK ad2ac21

@josecelano josecelano merged commit c1aad28 into main Feb 16, 2026
39 checks passed
@josecelano josecelano deleted the 349-add-json-output-to-create-command branch February 16, 2026 16:01
josecelano added a commit that referenced this pull request Feb 16, 2026
- Task 12.1: Add JSON output to create command
- Completed via Issue #349 and PR #351
@josecelano josecelano mentioned this pull request Feb 16, 2026
41 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add JSON Output to create Command

1 participant