You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add JSON output format support to the validate command (roadmap task 12.10). This is part of Phase 2 of the JSON output epic (#348), which aims to implement JSON output for all remaining commands so that JSON can eventually become the default output format.
The validate command currently only outputs human-readable text progress messages and a validation summary. This task adds a machine-readable JSON alternative that automation workflows, CI/CD pipelines, and AI agents can parse programmatically.
Key characteristic: The validate command takes an --env-file <PATH> argument and performs validation without creating any deployment state. Its output reflects configuration properties extracted from the file — environment name, provider, and enabled feature flags (Prometheus, Grafana, HTTPS, backup). There is no domain Environment state object involved — the DTO is built directly from ValidationResult.
Follow the existing view module structure established in destroy/ (has view_data/)
ValidateDetailsData is a plain presentation DTO deriving Serialize, PartialEq (not Deserialize) with a named constructor from_result(&Path, &ValidationResult)
JsonView::render() returns String — serialization errors handled inline via unwrap_or_else
TextView::render() formats the same data as human-readable text and also returns String
Architectural Constraints
No business logic in presentation layer — only rendering
Error handling follows project conventions
Output must go through UserOutput methods — never println! or eprintln! directly
The ValidateDetailsData DTO must derive serde::Serialize (output-only — no Deserialize needed)
Implement ValidateDetailsData DTO with from_result() constructor in view_data/validate_details.rs
Implement JsonView::render() in views/json_view.rs
Implement TextView::render() in views/text_view.rs
Register validate in src/presentation/cli/views/commands/mod.rs
Phase 2: Controller + Router
Add output_format: OutputFormat parameter to ValidateCommandController::execute()
Refactor complete_workflow() to accept and dispatch on output_format
Update router to pass output_format from context to controller
Phase 3: Tests + Manual Verification + Docs
Unit tests for JsonView::render()
Unit tests for TextView::render()
Manual verification: run cargo run -- validate --env-file envs/lxd-local-example.json and confirm text output is unchanged
Manual verification: run cargo run -- validate --env-file envs/lxd-local-example.json --output-format json 2>/dev/null and confirm JSON output matches spec
Update docs/user-guide/commands/validate.md with JSON output examples
Acceptance Criteria
Note for Contributors: These criteria define what the PR reviewer will check. Use this as your pre-review checklist before submitting the PR to minimize back-and-forth iterations.
Quality Checks:
Pre-commit checks pass: ./scripts/pre-commit.sh
Task-Specific Criteria:
validate --output-format json outputs valid JSON with all expected fields
validate --output-format text (default) produces human-readable output identical to current output
Overview
Add JSON output format support to the
validatecommand (roadmap task 12.10). This is part of Phase 2 of the JSON output epic (#348), which aims to implement JSON output for all remaining commands so that JSON can eventually become the default output format.The
validatecommand currently only outputs human-readable text progress messages and a validation summary. This task adds a machine-readable JSON alternative that automation workflows, CI/CD pipelines, and AI agents can parse programmatically.Key characteristic: The
validatecommand takes an--env-file <PATH>argument and performs validation without creating any deployment state. Its output reflects configuration properties extracted from the file — environment name, provider, and enabled feature flags (Prometheus, Grafana, HTTPS, backup). There is no domainEnvironmentstate object involved — the DTO is built directly fromValidationResult.Specification
See detailed specification: docs/issues/390-add-json-output-to-validate-command.md
🏗️ Architecture Requirements
DDD Layer: Presentation
Module Path:
src/presentation/cli/views/commands/validate/Pattern: Strategy Pattern for rendering (same as
provision,create,show,run,list,configure,release,test,destroy)Module Structure Requirements
destroy/(hasview_data/)ValidateDetailsDatais a plain presentation DTO derivingSerialize,PartialEq(notDeserialize) with a named constructorfrom_result(&Path, &ValidationResult)JsonView::render()returnsString— serialization errors handled inline viaunwrap_or_elseTextView::render()formats the same data as human-readable text and also returnsStringArchitectural Constraints
UserOutputmethods — neverprintln!oreprintln!directlyValidateDetailsDataDTO must deriveserde::Serialize(output-only — noDeserializeneeded)Anti-Patterns to Avoid
println!/eprintln!instead ofUserOutputImplementation Plan
Phase 1: View Module
src/presentation/cli/views/commands/validate/mod.rsValidateDetailsDataDTO withfrom_result()constructor inview_data/validate_details.rsJsonView::render()inviews/json_view.rsTextView::render()inviews/text_view.rsvalidateinsrc/presentation/cli/views/commands/mod.rsPhase 2: Controller + Router
output_format: OutputFormatparameter toValidateCommandController::execute()complete_workflow()to accept and dispatch onoutput_formatoutput_formatfrom context to controllerPhase 3: Tests + Manual Verification + Docs
JsonView::render()TextView::render()cargo run -- validate --env-file envs/lxd-local-example.jsonand confirm text output is unchangedcargo run -- validate --env-file envs/lxd-local-example.json --output-format json 2>/dev/nulland confirm JSON output matches specdocs/user-guide/commands/validate.mdwith JSON output examplesAcceptance Criteria
Quality Checks:
./scripts/pre-commit.shTask-Specific Criteria:
validate --output-format jsonoutputs valid JSON with all expected fieldsvalidate --output-format text(default) produces human-readable output identical to current outputRelated
src/presentation/cli/views/commands/destroy/src/presentation/cli/views/commands/test/