Skip to content

Commit

Permalink
Add CSV output for validation errors and further streamline formattin…
Browse files Browse the repository at this point in the history
…g code path (#43)

* Assure txt format still prints schema errors with quiet flag

Signed-off-by: Matt Rutkowski <[email protected]>

* rename error type normalization function to reduce output size

Signed-off-by: Matt Rutkowski <[email protected]>

* rename error type normalization function to reduce output size

Signed-off-by: Matt Rutkowski <[email protected]>

* rename error type normalization function to reduce output size

Signed-off-by: Matt Rutkowski <[email protected]>

* Assure all validate tests output valid JSON where applicable

Signed-off-by: Matt Rutkowski <[email protected]>

* Support csv formatted output for validation errors

Signed-off-by: Matt Rutkowski <[email protected]>

* Fix G104 linter complaint

Signed-off-by: Matt Rutkowski <[email protected]>

* Fix G104 linter complaint

Signed-off-by: Matt Rutkowski <[email protected]>

---------

Signed-off-by: Matt Rutkowski <[email protected]>
  • Loading branch information
mrutkows authored Jun 29, 2023
1 parent 27065e5 commit 0f94ba9
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 68 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"gojsonschema",
"gomod",
"GTPL",
"hashstructure",
"HBOM",
"hokaccha",
"HSQLDB",
Expand Down
4 changes: 2 additions & 2 deletions cmd/license_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ func DisplayLicenseListJson(output io.Writer) {
}
json, _ := log.FormatInterfaceAsJson(lc)

// Note: JSON data files MUST ends in a newline s as this is a POSIX standard
// Note: JSON data files MUST ends in a newline as this is a POSIX standard
fmt.Fprintf(output, "%s\n", json)
}

Expand Down Expand Up @@ -330,7 +330,7 @@ func DisplayLicenseListCSV(output io.Writer) (err error) {
lc.License.Text.Content)

if errWrite := w.Write(currentRow); errWrite != nil {
return getLogger().Errorf("error writing to output (%v): %s", currentRow, err)
return getLogger().Errorf("error writing to output (%v): %s", currentRow, errWrite)
}
}
}
Expand Down
34 changes: 19 additions & 15 deletions cmd/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const (
)

var VALIDATE_SUPPORTED_ERROR_FORMATS = MSG_VALIDATE_FLAG_ERR_FORMAT +
strings.Join([]string{FORMAT_TEXT, FORMAT_JSON}, ", ") + " (default: txt)"
strings.Join([]string{FORMAT_TEXT, FORMAT_JSON, FORMAT_CSV}, ", ") + " (default: txt)"

// limits
const (
Expand Down Expand Up @@ -150,8 +150,9 @@ func validateCmdImpl(cmd *cobra.Command, args []string) error {
return nil
}

// Normalize error/normalizeValidationErrorTypes from the Validate() function
func normalizeValidationErrorTypes(document *schema.Sbom, valid bool, err error) {
// Normalize ErrorTypes from the Validate() function
// Note: this function name should not be changed
func validationError(document *schema.Sbom, valid bool, err error) {

// Consistently display errors before exiting
if err != nil {
Expand Down Expand Up @@ -185,7 +186,8 @@ func Validate(output io.Writer, persistentFlags utils.PersistentCommandFlags, va
// use function closure to assure consistent error output based upon error type
defer func() {
if err != nil {
normalizeValidationErrorTypes(document, valid, err)
// normalize the error output to console
validationError(document, valid, err)
}
}()

Expand Down Expand Up @@ -280,7 +282,7 @@ func Validate(output io.Writer, persistentFlags utils.PersistentCommandFlags, va
getLogger().Infof("SBOM valid against JSON schema: `%t`", result.Valid())
valid = result.Valid()

// Catch general errors from the validation module itself and pass them on'
// Catch general errors from the validation package/library itself and display them
if errValidate != nil {
// we force result to INVALID as any errors from the library means
// we could NOT actually confirm the input documents validity
Expand All @@ -297,19 +299,21 @@ func Validate(output io.Writer, persistentFlags utils.PersistentCommandFlags, va
schemaErrors)

// TODO: de-duplicate errors (e.g., array item not "unique"...)
var formattedErrors string
switch persistentFlags.OutputFormat {
format := persistentFlags.OutputFormat
switch format {
case FORMAT_JSON:
// Note: JSON data files MUST ends in a newline s as this is a POSIX standard
formattedErrors = FormatSchemaErrors(schemaErrors, validateFlags, FORMAT_JSON)
// getLogger().Debugf("%s", formattedErrors)
fmt.Fprintf(output, "%s", formattedErrors)
case FORMAT_TEXT:
fallthrough
case FORMAT_CSV:
fallthrough
case FORMAT_TEXT:
// Note: we no longer add the formatted errors to the actual error "detail" field;
// since BOMs can have large numbers of errors. The new method is to allow
// the user to control the error result output (e.g., file, detail, etc.) via flags
FormatSchemaErrors(output, schemaErrors, validateFlags, format)
default:
// Format error results and append to InvalidSBOMError error "details"
formattedErrors = FormatSchemaErrors(schemaErrors, validateFlags, FORMAT_TEXT)
errInvalid.Details = formattedErrors
// Notify caller that we are defaulting to "txt" format
getLogger().Warningf(MSG_WARN_INVALID_FORMAT, format, FORMAT_TEXT)
FormatSchemaErrors(output, schemaErrors, validateFlags, FORMAT_TEXT)
}

return INVALID, document, schemaErrors, errInvalid
Expand Down
Loading

0 comments on commit 0f94ba9

Please sign in to comment.