Skip to content

Conversation

@dheerajodha
Copy link
Contributor

@dheerajodha dheerajodha commented Nov 18, 2025

User description

...bringing it to feature parity with ec validate image. The text format provides a human-readable, color-coded output that is easier to read than JSON.

  • Add text output format support with templates
  • Change default output from JSON to text (matching validate image)
  • Add ShowSuccesses/ShowWarnings flag support
  • Add comprehensive test coverage
  • Update existing tests for new API

resolves: EC-1493


PR Type

Enhancement


Description

  • Change default output format from JSON to text for better readability

  • Add text output format support with embedded Go templates

  • Pass ShowSuccesses/ShowWarnings flags to report generation

  • Add comprehensive test coverage for text output formatting

  • Update integration tests to explicitly request JSON output


Diagram Walkthrough

flowchart LR
  A["validate input command"] -->|"default output"| B["Text format"]
  A -->|"--output json"| C["JSON format"]
  A -->|"--output yaml"| D["YAML format"]
  B -->|"render templates"| E["Human-readable output"]
  C -->|"marshal"| F["Machine-readable JSON"]
  D -->|"marshal"| G["Machine-readable YAML"]
  E -->|"ShowSuccesses/ShowWarnings"| H["Filtered results"]
Loading

File Walkthrough

Relevant files
Enhancement
5 files
input.go
Update default output format and remove unused import       
+3/-4     
report.go
Add text format support with template rendering                   
+51/-2   
text_report.tmpl
Main text report template with conditional sections           
+28/-0   
_inputs.tmpl
Template for displaying input file paths                                 
+26/-0   
_results.tmpl
Template for rendering violations, warnings, successes     
+53/-0   
Tests
3 files
input_test.go
Add text output tests and update existing tests                   
+88/-1   
report_test.go
Add comprehensive text output format tests                             
+114/-3 
validate_input.feature
Add explicit JSON output to integration test scenarios     
+3/-3     
Documentation
1 files
ec_validate_input.adoc
Update documentation for supported output formats               
+1/-1     
Dependencies
1 files
go.sum
Update Kubernetes dependency version                                         
+0/-2     

@qodo-merge-pro
Copy link

qodo-merge-pro bot commented Nov 18, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Audit Coverage: The new text reporting pathway and default format change introduce user-visible behavior
but the diff does not show any explicit auditing/logging of these critical actions (e.g.,
format selection, report generation), making audit trail adequacy unclear.

Referred Code
	targets = append(targets, Text)
}
for _, targetName := range targets {
	target, err := p.Parse(targetName)
	if err != nil {
		allErrors = errors.Join(allErrors, err)
		continue
	}

	data, err := r.toFormat(target.Format)
	if err != nil {
		allErrors = errors.Join(allErrors, err)
		continue
	}

	if !bytes.HasSuffix(data, []byte{'\n'}) {
		data = append(data, "\n"...)
	}

	if _, err := target.Write(data); err != nil {
		allErrors = errors.Join(allErrors, err)


 ... (clipped 18 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Text Render Errors: The new text report generation returns errors from template rendering but the diff does
not show user-facing context or fallback behavior when rendering fails, which may impact
robustness.

Referred Code
//go:embed templates/*.tmpl
var efs embed.FS

func generateTextReport(r *Report) ([]byte, error) {
	// Prepare some template input
	// Calculate totals for the test report structure
	var successes, failures, warnings int
	for _, input := range r.FilePaths {
		successes += input.SuccessCount
		failures += len(input.Violations)
		warnings += len(input.Warnings)
	}

	result := "SUCCESS"
	if failures > 0 {
		result = "FAILURE"
	} else if warnings > 0 {
		result = "WARNING"
	}

	testReport := TestReport{


 ... (clipped 18 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Error Exposure: It is unclear whether errors from template parsing/rendering or invalid format selection
could surface internal details to end users since the diff adds a new Text path without
showing user-facing error sanitization.

Referred Code
func (r *Report) toFormat(format string) (data []byte, err error) {
	switch format {
	case JSON:
		data, err = json.Marshal(r)
	case YAML:
		data, err = yaml.Marshal(r)
	case Text:
		data, err = generateTextReport(r)
	case Summary:
		data, err = json.Marshal(r.toSummary())
	default:
		return nil, fmt.Errorf("%q is not a valid report format", format)
	}
	return

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Template Inputs: The new text templates use data from inputs and metadata to render output and the diff
does not show sanitization or escaping policy in templates, requiring verification that
user-controlled content cannot lead to unsafe rendering.

Referred Code
//go:embed templates/*.tmpl
var efs embed.FS

func generateTextReport(r *Report) ([]byte, error) {
	// Prepare some template input
	// Calculate totals for the test report structure
	var successes, failures, warnings int
	for _, input := range r.FilePaths {
		successes += input.SuccessCount
		failures += len(input.Violations)
		warnings += len(input.Warnings)
	}

	result := "SUCCESS"
	if failures > 0 {
		result = "FAILURE"
	} else if warnings > 0 {
		result = "WARNING"
	}

	testReport := TestReport{


 ... (clipped 18 lines)

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-merge-pro
Copy link

qodo-merge-pro bot commented Nov 18, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
PR silently removes multiple output formats

The PR silently removes support for multiple output formats like appstudio and
junit from the ec validate input command. This is a major breaking change that
should be reverted or explicitly documented.

Examples:

cmd/validate/input.go [237]
	validOutputFormats := []string{input.JSON, input.YAML, input.Text, input.Summary}
docs/modules/ROOT/pages/ec_validate_input.adoc [55]
json, yaml, text, summary. In following format and file path

Solution Walkthrough:

Before:

// file: cmd/validate/input.go
...
validOutputFormats := applicationsnapshot.OutputFormats
cmd.Flags().StringSliceVarP(&data.output, "output", "o", data.output, hd.Doc(`
...
Possible formats are:
`+strings.Join(validOutputFormats, ", ")+`...`))
...

// file: docs/modules/ROOT/pages/ec_validate_input.adoc
...
Possible formats are:
json, yaml, text, appstudio, summary, summary-markdown, junit, attestation, policy-input, vsa.
...

After:

// file: cmd/validate/input.go
...
validOutputFormats := []string{input.JSON, input.YAML, input.Text, input.Summary}
cmd.Flags().StringSliceVarP(&data.output, "output", "o", data.output, hd.Doc(`
...
Possible formats are:
`+strings.Join(validOutputFormats, ", ")+`...`))
...

// file: docs/modules/ROOT/pages/ec_validate_input.adoc
...
Possible formats are:
json, yaml, text, summary.
...
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a major, undocumented breaking change where several output formats are removed, which significantly impacts users and is not mentioned in the PR description.

High
Possible issue
Align report result with overall success

Update the logic for determining the result string in the text report to also
consider the r.Success field, ensuring consistency with the overall validation
outcome.

internal/input/report.go [232-237]

 	result := "SUCCESS"
-	if failures > 0 {
+	if !r.Success || failures > 0 {
 		result = "FAILURE"
 	} else if warnings > 0 {
 		result = "WARNING"
 	}
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a potential inconsistency where the text report's Result field might not reflect the overall Success status of the report, which could lead to misleading output.

Medium
  • Update

bringing it to feature parity with ec validate image. The text format
provides a human-readable, color-coded output that is easier to read
than JSON.

- Add text output format support with templates
- Change default output from JSON to text (matching validate image)
- Add ShowSuccesses/ShowWarnings flag support
- Add comprehensive test coverage
- Update existing tests for new API

resolves: EC-1493
@codecov
Copy link

codecov bot commented Nov 19, 2025

Codecov Report

❌ Patch coverage is 94.11765% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/input/report.go 93.54% 2 Missing ⚠️
Flag Coverage Δ
acceptance 55.54% <17.64%> (?)
generative 19.01% <0.00%> (-50.00%) ⬇️
integration 27.89% <2.94%> (-41.11%) ⬇️
unit 67.57% <94.11%> (-1.43%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cmd/validate/input.go 93.86% <100.00%> (+0.61%) ⬆️
internal/input/report.go 88.23% <93.54%> (+18.37%) ⬆️

... and 49 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@dheerajodha dheerajodha marked this pull request as ready for review November 19, 2025 13:58
@qodo-merge-pro
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Audit Coverage: The new text output path and default behavior change add user-facing functionality but
introduce no explicit auditing/logging of critical actions in the added lines, and it is
unclear from the diff whether such actions are logged elsewhere.

Referred Code
report, err := input.NewReport(inputs, data.policy, manyPolicyInput, showSuccesses, showWarnings)
if err != nil {
	return err
}

p := format.NewTargetParser(input.Text, format.Options{ShowSuccesses: showSuccesses, ShowWarnings: showWarnings}, cmd.OutOrStdout(), utils.FS(cmd.Context()))
if err := report.WriteAll(data.output, p); err != nil {
	return err
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Input Exposure: The text report rendering includes detailed policy result metadata and file paths which
may risk exposing sensitive info in user-facing output depending on inputs;
validation/sanitization is not evident in the new lines.

Referred Code
func generateTextReport(r *Report) ([]byte, error) {
	// Prepare some template input
	// Calculate totals for the test report structure
	var successes, failures, warnings int
	for _, input := range r.FilePaths {
		successes += input.SuccessCount
		failures += len(input.Violations)
		warnings += len(input.Warnings)
	}

	result := "SUCCESS"
	if failures > 0 {
		result = "FAILURE"
	} else if warnings > 0 {
		result = "WARNING"
	}

	testReport := TestReport{
		Timestamp: r.created.Format(time.RFC3339),
		Namespace: "",
		Successes: successes,


 ... (clipped 15 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-merge-pro
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
The PR removes several output formats

The PR removes support for several output formats like appstudio and junit for
the validate input command. This is a breaking change that is not mentioned in
the PR description and should be restored or explicitly documented.

Examples:

cmd/validate/input.go [237-241]
	validOutputFormats := []string{input.JSON, input.YAML, input.Text, input.Summary}
	cmd.Flags().StringSliceVarP(&data.output, "output", "o", data.output, hd.Doc(`
		Write output to a file in a specific format, e.g. yaml=/tmp/output.yaml. Use empty string
		path for stdout, e.g. yaml. May be used multiple times. Possible formats are:
		`+strings.Join(validOutputFormats, ", ")+`. In following format and file path
docs/modules/ROOT/pages/ec_validate_input.adoc [54-55]
path for stdout, e.g. yaml. May be used multiple times. Possible formats are:
json, yaml, text, summary. In following format and file path

Solution Walkthrough:

Before:

// cmd/validate/input.go
import "github.com/conforma/cli/internal/applicationsnapshot"
...
func validateInputCmd(...) *cobra.Command {
    ...
    validOutputFormats := applicationsnapshot.OutputFormats
    cmd.Flags().StringSliceVarP(&data.output, "output", "o", data.output, hd.Doc(`
        ... Possible formats are:
        `+strings.Join(validOutputFormats, ", ")+`...`))
    ...
}

After:

// cmd/validate/input.go
import "github.com/conforma/cli/internal/input"
...
func validateInputCmd(...) *cobra.Command {
    ...
    validOutputFormats := []string{input.JSON, input.YAML, input.Text, input.Summary}
    cmd.Flags().StringSliceVarP(&data.output, "output", "o", data.output, hd.Doc(`
        ... Possible formats are:
        `+strings.Join(validOutputFormats, ", ")+`...`))
    ...
}
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a significant, undocumented breaking change where multiple output formats for the validate input command were removed, which could break existing user workflows.

High
General
Align report result with displayed content

In generateTextReport, update the logic to set the result to "WARNING" only if
there are warnings and they are configured to be shown.

internal/input/report.go [232-237]

 	result := "SUCCESS"
 	if failures > 0 {
 		result = "FAILURE"
-	} else if warnings > 0 {
+	} else if warnings > 0 && r.ShowWarnings {
 		result = "WARNING"
 	}
  • Apply / Chat
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a logic flaw where the report summary could show a "WARNING" result without displaying any warnings, leading to user confusion.

Medium
  • More

Copy link
Contributor

@robnester-rh robnester-rh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@simonbaird
Copy link
Member

What do we think about "The PR removes support for several output formats..". Is Qodo right about that?

@simonbaird
Copy link
Member

What do we think about "The PR removes support for several output formats..". Is Qodo right about that?

I guess it's this part:

- 	validOutputFormats := applicationsnapshot.OutputFormats
+ 	validOutputFormats := []string{input.JSON, input.YAML, input.Text, input.Summary}

Are the other formats incompatible with validate input?

@dheerajodha
Copy link
Contributor Author

What do we think about "The PR removes support for several output formats..". Is Qodo right about that?

Qodo is not right about that. ec validate input command never supported those formats (ref). I tested this:

$ ec validate input --file data.yaml --policy policy-1.yaml --output appstudio
Error: "appstudio" is not a valid report format

$ ec validate input --file data.yaml --policy policy-1.yaml --output junit
Error: "junit" is not a valid report format

Are the other formats incompatible with validate input?

Yes, other formats are incompatible. This subcommand only supports json, yaml, text, summary formats.

@dheerajodha
Copy link
Contributor Author

FTR: Here's how the text format looks like, for example:

$ ./dist/ec validate input --file ../playground/data.yaml --policy ../playground/policy-1.yaml --output text

Success: true
Result: SUCCESS
Violations: 0, Warnings: 0, Successes: 1
Input File: ../playground/data.yaml

Copy link
Member

@simonbaird simonbaird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@dheerajodha dheerajodha merged commit 1a6ca15 into conforma:main Nov 26, 2025
11 checks passed
@dheerajodha dheerajodha deleted the EC-1493 branch November 26, 2025 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants