From 39bfb28652957d5d58e17930a7ab54993316cac0 Mon Sep 17 00:00:00 2001 From: Matt Rutkowski Date: Fri, 8 Nov 2024 11:13:49 -0600 Subject: [PATCH] Enable loading of remote JSON schemas (e.g., "https") on --force flag (#112) * Enable loading of remote JSON schemas on --force flag Signed-off-by: Matt Rutkowski * Enable loading of remote JSON schemas on --force flag Signed-off-by: Matt Rutkowski * Change use of accent char. to single quote char. in log msgs. Signed-off-by: Matt Rutkowski --------- Signed-off-by: Matt Rutkowski --- .vscode/launch.json | 11 ++++ README.md | 87 ++++++++++++++++++++---------- cmd/component.go | 12 ++--- cmd/diff.go | 22 ++++---- cmd/diff_test.go | 6 +-- cmd/document.go | 18 +++---- cmd/errors.go | 2 +- cmd/license.go | 14 ++--- cmd/license_list.go | 6 +-- cmd/license_policy.go | 8 +-- cmd/license_policy_test.go | 40 +++++++------- cmd/license_test.go | 8 +-- cmd/normalize_test.go | 10 ++-- cmd/patch.go | 12 ++--- cmd/patch_format.go | 4 +- cmd/patch_test.go | 30 +++++------ cmd/patch_verify_test.go | 2 +- cmd/query.go | 8 +-- cmd/query_test.go | 6 +-- cmd/report.go | 14 ++--- cmd/report_test.go | 8 +-- cmd/resource.go | 14 ++--- cmd/root.go | 12 ++--- cmd/root_test.go | 8 +-- cmd/schema.go | 14 ++--- cmd/stats.go | 10 ++-- cmd/trim.go | 18 +++---- cmd/trim_test.go | 12 ++--- cmd/validate.go | 61 ++++++++++++++------- cmd/validate_custom.go | 8 +-- cmd/validate_custom_test.go | 10 ++-- cmd/validate_format.go | 4 +- cmd/validate_test.go | 30 +++++------ cmd/vulnerability.go | 10 ++-- common/query_types.go | 2 +- log/log.go | 4 +- main.go | 4 +- schema/bom.go | 10 ++-- schema/bom_hash.go | 14 ++--- schema/bom_hash_test.go | 12 ++--- schema/bom_query.go | 8 +-- schema/license_expression.go | 16 +++--- schema/license_expression_test.go | 12 ++--- schema/license_policy_config.go | 60 ++++++++++----------- schema/schema_custom_validation.go | 8 +-- schema/schema_errors.go | 6 +-- schema/schema_formats.go | 20 +++---- utils/config.go | 14 ++--- utils/regex.go | 2 +- utils/timestamps.go | 6 +-- 50 files changed, 402 insertions(+), 335 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 4193ec70..1a6c23f2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,17 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + + { + "showGlobalVariables": true, + "name": "Debug: validate", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "main.go", // "program": "${file}", + "args": ["validate", "-i", "examples/cyclonedx/SBOM/protonmail-webclient-v4-0912dff/bom.json"], + "dlvFlags": ["--check-go-version=false"] + }, { "showGlobalVariables": true, "name": "Debug: validate", diff --git a/README.md b/README.md index 56412530..528eb9d1 100644 --- a/README.md +++ b/README.md @@ -328,13 +328,20 @@ Use the [schema](#schema) command to list supported schemas formats, versions an Customized JSON schemas can also be permanently configured as named schema "variants" within the utility's configuration file. See [adding schemas](#adding-schemas). -- **"Customized" schema** variants, perhaps derived from standard BOM schemas, can be used for validation using the `--variant` flag (e.g., industry or company-specific schemas). -- **Overriding default schema** - You can override an BOM's declared BOM version using the `--force` flag (e.g., verify a BOM against a newer specification version). +- **Overriding default schema** + - Using the [`--force` flag](#--force-flag) and passing in a URI to an alternative JSON schema. +- **"Customized" schema** variants, perhaps derived from standard BOM schemas, can be used for validation using the `--variant` flag (e.g., industry or company-specific schemas). + - **Note**: *These variants need to be built into the utility binary as a resource.* #### Validate flags The following flags can be used to improve performance when formatting error output results: +##### `--force` flag + +You can override the schema used for validation *(which defaults to the schema that matches the declared format and version found in the input BOM file)* by providing a different one using the `--force` flag. This may be useful to verify a BOM contents against a newer specification version or provide a customized schema. + - **Note**: *The `--force` flag works with schema files with valid URIs which include URLs (e.g., 'https://') and files (e.g., 'file://').* + ##### `--error-limit` flag Use the `--error-limit x` (default: `10`) flag to reduce the formatted error result output to the first `x` errors. By default, only the first 10 errors are output with an informational messaging indicating `x/y` errors were shown. @@ -358,17 +365,15 @@ Validating the "juice shop" SBOM (CycloneDX 1.2) example provided in this reposi ``` ```bash -[INFO] Loading (embedded) default schema config file: `config.json`... -[INFO] Loading (embedded) default license policy file: `license.json`... -[INFO] Attempting to load and unmarshal data from: `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json`... -[INFO] Successfully unmarshalled data from: `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json` +[INFO] Attempting to load and unmarshal data from: 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json'... +[INFO] Successfully unmarshalled data from: 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json' [INFO] Determining file's BOM format and version... -[INFO] Determined BOM format, version (variant): `CycloneDX`, `1.2` (latest) +[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.2' (latest) [INFO] Matching BOM schema (for validation): schema/cyclonedx/1.2/bom-1.2.schema.json -[INFO] Loading schema `schema/cyclonedx/1.2/bom-1.2.schema.json`... -[INFO] Schema `schema/cyclonedx/1.2/bom-1.2.schema.json` loaded. -[INFO] Validating `examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json`... -[INFO] BOM valid against JSON schema: `true` +[INFO] Loading schema 'schema/cyclonedx/1.2/bom-1.2.schema.json'... +[INFO] Schema 'schema/cyclonedx/1.2/bom-1.2.schema.json' loaded. +[INFO] Validating 'examples/cyclonedx/SBOM/juice-shop-11.1.2/bom.json'... +[INFO] BOM valid against JSON schema: 'true' ``` You can also verify the [exit code](#exit-codes) from the validate command: @@ -381,7 +386,37 @@ echo $? 0 // no error (valid) ``` -#### Example: Validate using "custom" schema variants +##### Example: Validate using a remote JSON schema file using '--force' flag + +```bash +./sbom-utility validate -i test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json --force https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json +``` + +```bash +[INFO] Attempting to load and unmarshal data from: 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json'... +[INFO] Successfully unmarshalled data from: 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json' +[INFO] Determining file's BOM format and version... +[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.6' (latest) +[INFO] Matching BOM schema (for validation): schema/cyclonedx/1.6/bom-1.6.schema.json +[INFO] Loading schema from '--force' flag: 'https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json'... +[INFO] Validating document using forced schema (i.e., '--force https://raw.githubusercontent.com/CycloneDX/specification/master/schema/bom-1.6.schema.json') +[INFO] Schema 'schema/cyclonedx/1.6/bom-1.6.schema.json' loaded. +[INFO] Validating 'test/cyclonedx/1.6/cdx-1-6-valid-cbom-full-1.6.json'... +[INFO] BOM valid against JSON schema: 'true' +``` + +You can also verify the [exit code](#exit-codes) from the validate command: + +```bash +echo $? +``` + +```bash +0 // no error (valid) +``` + + +##### Example: Validate using "custom" schema variants The validation command will use the declared format and version found within the SBOM JSON file itself to lookup the default (latest) matching schema version (as declared in`config.json`; however, if variants of that same schema (same format and version) are declared, they can be requested via the `--variant` command line flag: @@ -392,19 +427,17 @@ The validation command will use the declared format and version found within the If you run the sample command above, you would see several "custom" schema errors resulting in an invalid SBOM determination (i.e., `exit status 2`): ```text -[INFO] Loading (embedded) default schema config file: `config.json`... -[INFO] Loading (embedded) default license policy file: `license.json`... -[INFO] Attempting to load and unmarshal data from: `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`... -[INFO] Successfully unmarshalled data from: `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json` +[INFO] Attempting to load and unmarshal data from: 'test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json'... +[INFO] Successfully unmarshalled data from: 'test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json' [INFO] Determining file's BOM format and version... -[INFO] Determined BOM format, version (variant): `CycloneDX`, `1.4` custom +[INFO] Determined BOM format, version (variant): 'CycloneDX', '1.4' custom [INFO] Matching BOM schema (for validation): schema/test/bom-1.4-custom.schema.json -[INFO] Loading schema `schema/test/bom-1.4-custom.schema.json`... -[INFO] Schema `schema/test/bom-1.4-custom.schema.json` loaded. -[INFO] Validating `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`... -[INFO] BOM valid against JSON schema: `false` +[INFO] Loading schema 'schema/test/bom-1.4-custom.schema.json'... +[INFO] Schema 'schema/test/bom-1.4-custom.schema.json' loaded. +[INFO] Validating 'test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json'... +[INFO] BOM valid against JSON schema: 'false' [INFO] (3) schema errors detected. -[INFO] Formatting error results (`txt` format)... +[INFO] Formatting error results ('txt' format)... 1. { "type": "contains", "field": "metadata.properties", @@ -445,7 +478,7 @@ If you run the sample command above, you would see several "custom" schema error ] } [ERROR] invalid SBOM: schema errors found (test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json) -[INFO] document `test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json`: valid=[false] +[INFO] document 'test/custom/cdx-1-4-test-custom-metadata-property-disclaimer-invalid.json': valid=[false] ``` confirming the exit code: @@ -458,7 +491,7 @@ echo $? 2 // SBOM error ``` -##### Why validation failed +###### Why validation failed The output shows a first schema error indicating the failing JSON object; in this case, @@ -467,7 +500,7 @@ The output shows a first schema error indicating the failing JSON object; in thi - the `value` field SHOULD have had a constant value of `"This SBOM is current as of the date it was generated and is subject to change."` (as was required by the custom schema's regex). - However, it was found to have only a partial match of `"This SBOM is current as of the date it was generated."`. -##### Details of the schema error +###### Details of the schema error Use the `--debug` or `-d` flag to see all schema error details: @@ -496,7 +529,7 @@ The details include the full context of the failing `metadata.properties` object } ``` -#### Example: Validate using "JSON" format +###### Example: Validate using "JSON" output format The JSON format will provide an `array` of schema error results that can be post-processed as part of validation toolchain. @@ -571,7 +604,7 @@ The JSON format will provide an `array` of schema error results that can be post ] ``` -##### Reducing output size using `error-value=false` flag +###### Reducing output size using `error-value=false` flag In many cases, BOMs may have many errors and having the `value` information details included can be too verbose and lead to large output files to inspect. In those cases, simply set the `error-value` flag to `false`. diff --git a/cmd/component.go b/cmd/component.go index 8e12d21a..92d4d0aa 100644 --- a/cmd/component.go +++ b/cmd/component.go @@ -177,12 +177,12 @@ func NewCommandComponent() *cobra.Command { // Make sure (optional) subcommand is known/valid if len(args) == 1 { if !preRunTestForSubcommand(VALID_SUBCOMMANDS_COMPONENT, args[0]) { - return getLogger().Errorf("Subcommand provided is not valid: `%v`", args[0]) + return getLogger().Errorf("Subcommand provided is not valid: '%v'", args[0]) } } if len(args) == 0 { - getLogger().Tracef("No subcommands provided; defaulting to: `%s` subcommand", SUBCOMMAND_SCHEMA_LIST) + getLogger().Tracef("No subcommands provided; defaulting to: '%s' subcommand", SUBCOMMAND_SCHEMA_LIST) } // Test for required flags (parameters) @@ -200,14 +200,14 @@ func componentCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFilename, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFilename, writer) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -258,7 +258,7 @@ func ListComponents(writer io.Writer, persistentFlags utils.PersistentCommandFla } format := persistentFlags.OutputFormat - getLogger().Infof("Outputting listing (`%s` format)...", format) + getLogger().Infof("Outputting listing ('%s' format)...", format) switch format { case FORMAT_TEXT: err = DisplayComponentListText(document, writer, flags) @@ -268,7 +268,7 @@ func ListComponents(writer io.Writer, persistentFlags utils.PersistentCommandFla err = DisplayComponentListMarkdown(document, writer, flags) default: // Default to Text output for anything else (set as flag default) - getLogger().Warningf("Listing not supported for `%s` format; defaulting to `%s` format...", + getLogger().Warningf("Listing not supported for '%s' format; defaulting to '%s' format...", format, FORMAT_TEXT) err = DisplayComponentListText(document, writer, flags) } diff --git a/cmd/diff.go b/cmd/diff.go index 7496df27..858d337b 100644 --- a/cmd/diff.go +++ b/cmd/diff.go @@ -79,7 +79,7 @@ func preRunTestForFiles(args []string) error { if baseFilename == "" { return getLogger().Errorf("Missing required argument(s): %s", FLAG_FILENAME_INPUT) } else if _, err := os.Stat(baseFilename); err != nil { - return getLogger().Errorf("File not found: `%s`", baseFilename) + return getLogger().Errorf("File not found: '%s'", baseFilename) } // Make sure the revision file is present and exists @@ -87,7 +87,7 @@ func preRunTestForFiles(args []string) error { if revisedFilename == "" { return getLogger().Errorf("Missing required argument(s): %s", FLAG_DIFF_FILENAME_REVISION) } else if _, err := os.Stat(revisedFilename); err != nil { - return getLogger().Errorf("File not found: `%s`", revisedFilename) + return getLogger().Errorf("File not found: '%s'", revisedFilename) } return nil @@ -100,7 +100,7 @@ func diffCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFile, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFile, writer) // use function closure to assure consistent error output based upon error type defer func() { @@ -110,7 +110,7 @@ func diffCmdImpl(cmd *cobra.Command, args []string) (err error) { if err != nil { return } - getLogger().Infof("Closed output file: `%s`", utils.GlobalFlags.PersistentFlags.OutputFile) + getLogger().Infof("Closed output file: '%s'", utils.GlobalFlags.PersistentFlags.OutputFile) } }() @@ -143,11 +143,11 @@ func Diff(persistentFlags utils.PersistentCommandFlags, flags utils.DiffCommandF // always close the output file if outputFile != nil { err = outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() - getLogger().Infof("Reading file (--input-file): `%s` ...", inputFilename) + getLogger().Infof("Reading file (--input-file): '%s' ...", inputFilename) // #nosec G304 (suppress warning) bBaseData, errReadBase := os.ReadFile(inputFilename) if errReadBase != nil { @@ -158,7 +158,7 @@ func Diff(persistentFlags utils.PersistentCommandFlags, flags utils.DiffCommandF return } - getLogger().Infof("Reading file (--input-revision): `%s` ...", revisedFilename) + getLogger().Infof("Reading file (--input-revision): '%s' ...", revisedFilename) // #nosec G304 (suppress warning) bRevisedData, errReadDelta := os.ReadFile(revisedFilename) if errReadDelta != nil { @@ -170,7 +170,7 @@ func Diff(persistentFlags utils.PersistentCommandFlags, flags utils.DiffCommandF } // Compare the base with the revision - getLogger().Infof("Comparing files: `%s` (base) to `%s` (revised) ...", inputFilename, revisedFilename) + getLogger().Infof("Comparing files: '%s' (base) to '%s' (revised) ...", inputFilename, revisedFilename) diffResults, errCompare := compareBinaryData(bBaseData, bRevisedData) if errCompare != nil { return errCompare @@ -179,7 +179,7 @@ func Diff(persistentFlags utils.PersistentCommandFlags, flags utils.DiffCommandF // Output the result var diffString string if diffResults.Modified() { - getLogger().Infof("Outputting listing (`%s` format)...", format) + getLogger().Infof("Outputting listing ('%s' format)...", format) switch outputFormat { case FORMAT_TEXT: var aJson map[string]interface{} @@ -202,14 +202,14 @@ func Diff(persistentFlags utils.PersistentCommandFlags, flags utils.DiffCommandF // Note: JSON data files MUST ends in a newline as this is a POSIX standard default: // Default to Text output for anything else (set as flag default) - getLogger().Warningf("Diff output format not supported for `%s` format.", format) + getLogger().Warningf("Diff output format not supported for '%s' format.", format) } // Output complete diff in either supported format fmt.Fprintf(output, "%s\n", diffString) } else { - getLogger().Infof("No deltas found. baseFilename: `%s`, revisedFilename=`%s` match.", + getLogger().Infof("No deltas found. baseFilename: '%s', revisedFilename='%s' match.", inputFilename, revisedFilename) } diff --git a/cmd/diff_test.go b/cmd/diff_test.go index 6f89143f..acb71a7f 100644 --- a/cmd/diff_test.go +++ b/cmd/diff_test.go @@ -90,7 +90,7 @@ func innerDiffTest(t *testing.T, testInfo *DiffTestInfo) (actualError error) { utils.GlobalFlags.DiffFlags.RevisedFile = testInfo.RevisedFilename utils.GlobalFlags.DiffFlags.Colorize = testInfo.Colorize - getLogger().Tracef("baseFilename: `%s`, revisedFilename=`%s`, actualError=`%T`", + getLogger().Tracef("baseFilename: '%s', revisedFilename='%s', actualError=`%T`", utils.GlobalFlags.PersistentFlags.InputFile, utils.GlobalFlags.DiffFlags.RevisedFile, actualError) @@ -101,8 +101,8 @@ func innerDiffTest(t *testing.T, testInfo *DiffTestInfo) (actualError error) { if !ErrorTypesMatch(actualError, testInfo.ResultExpectedError) { switch t := actualError.(type) { default: - fmt.Printf("unhandled error type: `%v`\n", t) - fmt.Printf(">> value: `%v`\n", t) + fmt.Printf("unhandled error type: '%v'\n", t) + fmt.Printf(">> value: '%v'\n", t) getLogger().Error(actualError) } t.Errorf("expected error type: `%T`, actual type: `%T`", testInfo.ResultExpectedError, actualError) diff --git a/cmd/document.go b/cmd/document.go index 1f25448b..c60d5430 100644 --- a/cmd/document.go +++ b/cmd/document.go @@ -32,21 +32,21 @@ func LoadInputBOMFileAndDetectSchema() (document *schema.BOM, err error) { inputFile := utils.GlobalFlags.PersistentFlags.InputFile // check for required fields on command - getLogger().Tracef("utils.Flags.InputFile: `%s`", inputFile) + getLogger().Tracef("utils.Flags.InputFile: '%s'", inputFile) if inputFile == "" { - return nil, fmt.Errorf("invalid input file (-%s): `%s` ", FLAG_FILENAME_INPUT_SHORT, inputFile) + return nil, fmt.Errorf("invalid input file (-%s): '%s' ", FLAG_FILENAME_INPUT_SHORT, inputFile) } // Construct a BOM document object around the input file document = schema.NewBOM(inputFile) // Load the raw, candidate BOM (file) as JSON data - getLogger().Infof("Attempting to load and unmarshal data from: `%s`...", document.GetFilenameInterpolated()) + getLogger().Infof("Attempting to load and unmarshal data from: '%s'...", document.GetFilenameInterpolated()) err = document.UnmarshalBOMAsJSONMap() // i.e., utils.Flags.InputFile if err != nil { return } - getLogger().Infof("Successfully unmarshalled data from: `%s`", document.GetFilenameInterpolated()) + getLogger().Infof("Successfully unmarshalled data from: '%s'", document.GetFilenameInterpolated()) // Search the document keys/values for known BOM formats and schema in the config. file getLogger().Infof("Determining file's BOM format and version...") @@ -56,7 +56,7 @@ func LoadInputBOMFileAndDetectSchema() (document *schema.BOM, err error) { } // Display detected format, version with (optional) schema variant (i.e., if requested on command line) - getLogger().Infof("Determined BOM format, version (variant): `%s`, `%s` %s", + getLogger().Infof("Determined BOM format, version (variant): '%s', '%s' %s", document.FormatInfo.CanonicalName, document.SchemaInfo.Version, schema.FormatSchemaVariant(document.SchemaInfo.Variant)) @@ -69,19 +69,19 @@ func LoadBOMFile(inputFile string) (document *schema.BOM, err error) { defer getLogger().Exit() if inputFile == "" { - return nil, fmt.Errorf("invalid input file (-%s): `%s` ", FLAG_FILENAME_INPUT_SHORT, inputFile) + return nil, fmt.Errorf("invalid input file (-%s): '%s'", FLAG_FILENAME_INPUT_SHORT, inputFile) } // Construct a BOM document object around the input file document = schema.NewBOM(inputFile) // Load the raw, candidate BOM (file) as JSON data - getLogger().Infof("Attempting to load and unmarshal data from: `%s`...", document.GetFilenameInterpolated()) + getLogger().Infof("Attempting to load and unmarshal data from: '%s'...", document.GetFilenameInterpolated()) err = document.UnmarshalBOMAsJSONMap() // i.e., utils.Flags.InputFile if err != nil { return } - getLogger().Infof("Successfully unmarshalled data from: `%s`", document.GetFilenameInterpolated()) + getLogger().Infof("Successfully unmarshalled data from: '%s'", document.GetFilenameInterpolated()) // Search the document keys/values for known BOM formats and schema in the config. file getLogger().Infof("Determining file's BOM format and version...") @@ -91,7 +91,7 @@ func LoadBOMFile(inputFile string) (document *schema.BOM, err error) { } // Display detected format, version with (optional) schema variant (i.e., if requested on command line) - getLogger().Infof("Determined BOM format, version (variant): `%s`, `%s` %s", + getLogger().Infof("Determined BOM format, version (variant): '%s', '%s' %s", document.FormatInfo.CanonicalName, document.SchemaInfo.Version, schema.FormatSchemaVariant(document.SchemaInfo.Variant)) diff --git a/cmd/errors.go b/cmd/errors.go index dd9cc7be..6642742e 100644 --- a/cmd/errors.go +++ b/cmd/errors.go @@ -57,7 +57,7 @@ const ( // Validation messages const ( - MSG_FORMAT_TYPE = "format: `%s`" + MSG_FORMAT_TYPE = "format: '%s'" MSG_SCHEMA_ERRORS = "schema errors found" MSG_PROPERTY_NOT_FOUND = "property not found" MSG_PROPERTY_REGEX_FAILED = "check failed: property regex mismatch" diff --git a/cmd/license.go b/cmd/license.go index 18661db3..264f9370 100644 --- a/cmd/license.go +++ b/cmd/license.go @@ -57,7 +57,7 @@ func NewCommandLicense() *cobra.Command { } // Make sure subcommand is known if !preRunTestForSubcommand(VALID_SUBCOMMANDS_LICENSE, args[0]) { - return getLogger().Errorf("Subcommand provided is not valid: `%v`", args[0]) + return getLogger().Errorf("Subcommand provided is not valid: '%v'", args[0]) } return } @@ -143,7 +143,7 @@ func warnNoLicenseFound(bom *schema.BOM, location int) { // Note: An actual error SHOULD ONLY be returned by the custom validation code. func warnInvalidResourceLicense(resourceType string, bomRef string, name string, version string) { - getLogger().Warningf("%s. resourceType: `%s`: bomRef: `%s`, name:`%s`, version: `%s`", + getLogger().Warningf("%s. resourceType: '%s': bomRef: '%s', name:'%s', version: '%s'", MSG_LICENSE_NOT_FOUND, resourceType, bomRef, name, version) } @@ -162,7 +162,7 @@ func hashMetadataLicenses(bom *schema.BOM, policyConfig *schema.LicensePolicyCon var licenseInfo schema.LicenseInfo for _, pLicenseChoice := range *pLicenses { - getLogger().Tracef("hashing license: id: `%s`, name: `%s`", + getLogger().Tracef("hashing license: id: '%s', name: '%s'", pLicenseChoice.License.Id, pLicenseChoice.License.Name) licenseInfo.LicenseChoice = pLicenseChoice @@ -233,7 +233,7 @@ func hashComponentLicense(bom *schema.BOM, policyConfig *schema.LicensePolicyCon if pLicenses != nil && len(*pLicenses) > 0 { for _, licenseChoice := range *pLicenses { getLogger().Debugf("licenseChoice: %s", getLogger().FormatStruct(licenseChoice)) - getLogger().Tracef("hashing license for component=`%s`", cdxComponent.Name) + getLogger().Tracef("hashing license for component='%s'", cdxComponent.Name) licenseInfo = *schema.NewLicenseInfoFromComponent(cdxComponent, licenseChoice, location) err = hashLicenseInfoByLicenseType(bom, policyConfig, licenseInfo, whereFilters, licenseFlags) @@ -277,7 +277,7 @@ func hashServiceLicense(bom *schema.BOM, policyConfig *schema.LicensePolicyConfi if pLicenses != nil && len(*pLicenses) > 0 { for _, licenseChoice := range *pLicenses { getLogger().Debugf("licenseChoice: %s", getLogger().FormatStruct(licenseChoice)) - getLogger().Tracef("Hashing license for service=`%s`", cdxService.Name) + getLogger().Tracef("Hashing license for service='%s'", cdxService.Name) licenseInfo = *schema.NewLicenseInfoFromService(cdxService, licenseChoice, location) err = hashLicenseInfoByLicenseType(bom, policyConfig, licenseInfo, whereFilters, licenseFlags) if err != nil { @@ -338,7 +338,7 @@ func hashLicenseInfoByLicenseType(bom *schema.BOM, policyConfig *schema.LicenseP // without schema validation (which would find this as an error) // Note: licenseInfo.LicenseChoiceType = 0 // default, invalid baseError := NewSbomLicenseDataError() - baseError.AppendMessage(fmt.Sprintf(": for entity: `%s` (%s)", + baseError.AppendMessage(fmt.Sprintf(": for entity: '%s' (%s)", licenseInfo.BOMRef, licenseInfo.ResourceName)) err = baseError @@ -347,7 +347,7 @@ func hashLicenseInfoByLicenseType(bom *schema.BOM, policyConfig *schema.LicenseP if err != nil { baseError := NewSbomLicenseDataError() - baseError.AppendMessage(fmt.Sprintf(": for entity: `%s` (%s)", + baseError.AppendMessage(fmt.Sprintf(": for entity: '%s' (%s)", licenseInfo.BOMRef, licenseInfo.ResourceName)) err = baseError diff --git a/cmd/license_list.go b/cmd/license_list.go index 95090afc..b3464aab 100644 --- a/cmd/license_list.go +++ b/cmd/license_list.go @@ -163,7 +163,7 @@ func listCmdImpl(cmd *cobra.Command, args []string) (err error) { // always close the output file if outputFile != nil { err = outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -212,7 +212,7 @@ func ListLicenses(writer io.Writer, policyConfig *schema.LicensePolicyConfig, } format := persistentFlags.OutputFormat - getLogger().Infof("Outputting listing (`%s` format)...", format) + getLogger().Infof("Outputting listing ('%s' format)...", format) switch format { case FORMAT_JSON: err = DisplayLicenseListJson(document, writer, licenseFlags) @@ -224,7 +224,7 @@ func ListLicenses(writer io.Writer, policyConfig *schema.LicensePolicyConfig, err = DisplayLicenseListText(document, writer, licenseFlags) default: // Default to JSON output for anything else - getLogger().Warningf("Listing not supported for `%s` format; defaulting to `%s` format...", + getLogger().Warningf("Listing not supported for '%s' format; defaulting to '%s' format...", format, FORMAT_JSON) err = DisplayLicenseListJson(document, writer, licenseFlags) } diff --git a/cmd/license_policy.go b/cmd/license_policy.go index f099fc5d..4b2870d2 100644 --- a/cmd/license_policy.go +++ b/cmd/license_policy.go @@ -133,12 +133,12 @@ func NewCommandPolicy() *cobra.Command { // Make sure (optional) subcommand is known/valid if len(args) == 1 { if !preRunTestForSubcommand(VALID_SUBCOMMANDS_POLICY, args[0]) { - return getLogger().Errorf("Subcommand provided is not valid: `%v`", args[0]) + return getLogger().Errorf("Subcommand provided is not valid: '%v'", args[0]) } } if len(args) == 0 { - getLogger().Tracef("No subcommands provided; defaulting to: `%s` subcommand", SUBCOMMAND_SCHEMA_LIST) + getLogger().Tracef("No subcommands provided; defaulting to: '%s' subcommand", SUBCOMMAND_SCHEMA_LIST) } return @@ -158,7 +158,7 @@ func policyCmdImpl(cmd *cobra.Command, args []string) (err error) { // always close the output file if outputFile != nil { err = outputFile.Close() - getLogger().Infof("Closed output file: `%s`", utils.GlobalFlags.PersistentFlags.OutputFile) + getLogger().Infof("Closed output file: '%s'", utils.GlobalFlags.PersistentFlags.OutputFile) } }() @@ -226,7 +226,7 @@ func ListLicensePolicies(writer io.Writer, policyConfig *schema.LicensePolicyCon err = DisplayLicensePoliciesMarkdown(writer, filteredMap, licenseFlags) default: // default to text format for anything else - getLogger().Warningf("Unsupported format: `%s`; using default format.", + getLogger().Warningf("Unsupported format: '%s'; using default format.", utils.GlobalFlags.PersistentFlags.OutputFormat) err = DisplayLicensePoliciesTabbedText(writer, filteredMap, licenseFlags) } diff --git a/cmd/license_policy_test.go b/cmd/license_policy_test.go index 80c2d1d7..ca13f5a2 100644 --- a/cmd/license_policy_test.go +++ b/cmd/license_policy_test.go @@ -157,7 +157,7 @@ func TestLicensePolicyUsageConjunctionsANDCombinations(t *testing.T) { } resolvedPolicy := parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 2. schema.POLICY_DENY AND schema.POLICY_NEEDS_REVIEW @@ -169,7 +169,7 @@ func TestLicensePolicyUsageConjunctionsANDCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 3. schema.POLICY_DENY AND schema.POLICY_DENY @@ -181,7 +181,7 @@ func TestLicensePolicyUsageConjunctionsANDCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 4. schema.POLICY_NEEDS_REVIEW AND schema.POLICY_ALLOW @@ -193,7 +193,7 @@ func TestLicensePolicyUsageConjunctionsANDCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 5. schema.POLICY_NEEDS_REVIEW AND schema.POLICY_NEEDS_REVIEW @@ -205,7 +205,7 @@ func TestLicensePolicyUsageConjunctionsANDCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 6. schema.POLICY_ALLOW AND schema.POLICY_ALLOW @@ -217,7 +217,7 @@ func TestLicensePolicyUsageConjunctionsANDCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } } @@ -247,7 +247,7 @@ func TestLicensePolicyUsageConjunctionsORCombinations(t *testing.T) { } resolvedPolicy := parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 2. schema.POLICY_ALLOW OR schema.POLICY_NEEDS_REVIEW @@ -259,7 +259,7 @@ func TestLicensePolicyUsageConjunctionsORCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 3. schema.POLICY_ALLOW OR schema.POLICY_ALLOW @@ -271,7 +271,7 @@ func TestLicensePolicyUsageConjunctionsORCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 4. schema.POLICY_NEEDS_REVIEW OR schema.POLICY_DENY @@ -283,7 +283,7 @@ func TestLicensePolicyUsageConjunctionsORCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 5. schema.POLICY_NEEDS_REVIEW OR schema.POLICY_NEEDS_REVIEW @@ -295,7 +295,7 @@ func TestLicensePolicyUsageConjunctionsORCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } // 6. schema.POLICY_DENY OR schema.POLICY_DENY @@ -307,7 +307,7 @@ func TestLicensePolicyUsageConjunctionsORCombinations(t *testing.T) { } resolvedPolicy = parsedExpression.CompoundUsagePolicy if resolvedPolicy != EXPECTED_USAGE_POLICY { - t.Errorf("schema.ParseExpression(): \"%s\" returned: `%s`; expected: `%s`", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) + t.Errorf("schema.ParseExpression(): \"%s\" returned: '%s'; expected: '%s'", EXP, resolvedPolicy, EXPECTED_USAGE_POLICY) } } @@ -343,10 +343,10 @@ func TestLicensePolicyCustomListGoodBadMaybe(t *testing.T) { TEST_VALUES := []string{REPORT_LIST_TITLE_ROW_SEPARATOR} matchFoundLine, matchFound := bufferLineContainsValues(outputBuffer, TEST_LINE_NUM, TEST_VALUES...) if !matchFound { - t.Errorf("policy file does not contain expected values: `%v` at line: %v\n", TEST_VALUES, TEST_LINE_NUM) + t.Errorf("policy file does not contain expected values: '%v' at line: %v\n", TEST_VALUES, TEST_LINE_NUM) return } else { - getLogger().Tracef("policy file contains expected values: `%v` at line: %v\n", TEST_VALUES, matchFoundLine) + getLogger().Tracef("policy file contains expected values: '%v' at line: %v\n", TEST_VALUES, matchFoundLine) } // Assure "bad" policy has usage "deny" @@ -354,10 +354,10 @@ func TestLicensePolicyCustomListGoodBadMaybe(t *testing.T) { TEST_VALUES = []string{LICENSE_ID_BAD, schema.POLICY_DENY} matchFoundLine, matchFound = bufferLineContainsValues(outputBuffer, TEST_LINE_NUM, TEST_VALUES...) if !matchFound { - t.Errorf("policy file does not contain expected values: `%v` at line: %v\n", TEST_VALUES, TEST_LINE_NUM) + t.Errorf("policy file does not contain expected values: '%v' at line: %v\n", TEST_VALUES, TEST_LINE_NUM) return } else { - getLogger().Tracef("policy file contains expected values: `%v` at line: %v\n", TEST_VALUES, matchFoundLine) + getLogger().Tracef("policy file contains expected values: '%v' at line: %v\n", TEST_VALUES, matchFoundLine) } // Assure "good" policy has usage "allow" @@ -365,10 +365,10 @@ func TestLicensePolicyCustomListGoodBadMaybe(t *testing.T) { TEST_VALUES = []string{LICENSE_ID_GOOD, schema.POLICY_ALLOW} matchFoundLine, matchFound = bufferLineContainsValues(outputBuffer, TEST_LINE_NUM, TEST_VALUES...) if !matchFound { - t.Errorf("policy file does not contain expected values: `%v` at line: %v\n", TEST_VALUES, TEST_LINE_NUM) + t.Errorf("policy file does not contain expected values: '%v' at line: %v\n", TEST_VALUES, TEST_LINE_NUM) return } else { - getLogger().Tracef("policy file contains expected values: `%v` at line: %v\n", TEST_VALUES, matchFoundLine) + getLogger().Tracef("policy file contains expected values: '%v' at line: %v\n", TEST_VALUES, matchFoundLine) } // Assure "maybe" policy has usage "needs-review" @@ -376,10 +376,10 @@ func TestLicensePolicyCustomListGoodBadMaybe(t *testing.T) { TEST_VALUES = []string{LICENSE_ID_MAYBE, schema.POLICY_NEEDS_REVIEW} matchFoundLine, matchFound = bufferLineContainsValues(outputBuffer, TEST_LINE_NUM, TEST_VALUES...) if !matchFound { - t.Errorf("policy file does not contain expected values: `%v` at line: %v\n", TEST_VALUES, TEST_LINE_NUM) + t.Errorf("policy file does not contain expected values: '%v' at line: %v\n", TEST_VALUES, TEST_LINE_NUM) return } else { - getLogger().Tracef("policy file contains expected values: `%v` at line: %v\n", TEST_VALUES, matchFoundLine) + getLogger().Tracef("policy file contains expected values: '%v' at line: %v\n", TEST_VALUES, matchFoundLine) } } diff --git a/cmd/license_test.go b/cmd/license_test.go index 27b27dc8..698073f0 100644 --- a/cmd/license_test.go +++ b/cmd/license_test.go @@ -123,12 +123,12 @@ func innerTestLicenseExpressionParsing(t *testing.T, expression string, expected var err error parsedExpression, err = schema.ParseExpression(LicensePolicyConfig, expression) if err != nil { - t.Errorf("unable to parse expression: `%s`\n", expression) + t.Errorf("unable to parse expression: '%s'\n", expression) } getLogger().Infof("expression:\n%v", parsedExpression) if parsedExpression.CompoundUsagePolicy != expectedPolicy { - t.Errorf("License Expression: expected `%s`, actual `%s`\n", + t.Errorf("License Expression: expected '%s', actual '%s'\n", expectedPolicy, parsedExpression.CompoundUsagePolicy) } return @@ -355,7 +355,7 @@ func TestLicenseExpressionParsingTestComplex1(t *testing.T) { EXPECTED_POLICY := schema.POLICY_ALLOW result := innerTestLicenseExpressionParsing(t, SPDX_LICENSE_EXPRESSION_TEST1, EXPECTED_POLICY) if result.LeftUsagePolicy != schema.POLICY_ALLOW && result.RightUsagePolicy != schema.POLICY_ALLOW { - t.Errorf("License Expression: expectedLeft `%s`, actualLeft `%s`, expectedRight `%s`, actualRight `%s`\n", + t.Errorf("License Expression: expectedLeft '%s', actualLeft '%s', expectedRight '%s', actualRight '%s'\n", schema.POLICY_ALLOW, result.LeftUsagePolicy, schema.POLICY_ALLOW, result.RightUsagePolicy) } } @@ -365,7 +365,7 @@ func TestLicenseExpressionParsingTestComplex2(t *testing.T) { EXPECTED_POLICY := schema.POLICY_NEEDS_REVIEW result := innerTestLicenseExpressionParsing(t, SPDX_LICENSE_EXPRESSION_TEST1, EXPECTED_POLICY) if result.LeftUsagePolicy != schema.POLICY_ALLOW && result.RightUsagePolicy != schema.POLICY_ALLOW { - t.Errorf("License Expression: expectedLeft `%s`, actualLeft `%s`, expectedRight `%s`, actualRight `%s`\n", + t.Errorf("License Expression: expectedLeft '%s', actualLeft '%s', expectedRight '%s', actualRight '%s'\n", schema.POLICY_ALLOW, result.LeftUsagePolicy, schema.POLICY_ALLOW, result.RightUsagePolicy) } } diff --git a/cmd/normalize_test.go b/cmd/normalize_test.go index 6066431e..44c05bfe 100644 --- a/cmd/normalize_test.go +++ b/cmd/normalize_test.go @@ -119,14 +119,14 @@ func innerBufferedTestNormalize(testInfo *NormalizeTestInfo) (outputBuffer bytes defer bufferedWriter.Flush() } else { outputFile, outputWriter, err = createOutputFile(testInfo.OutputFile) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", testInfo.OutputFile, outputWriter) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", testInfo.OutputFile, outputWriter) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file (even if error, as long as file handle returned) if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", testInfo.OutputFile) + getLogger().Infof("Closed output file: '%s'", testInfo.OutputFile) } }() @@ -251,7 +251,7 @@ func TestNormalizeCdx15VulnerabilitiesNatsBox(t *testing.T) { // // Immediately grab the Type of the dereferenced interface{} // rvoType := rvoItfc.Type() -// fmt.Printf("Interface: Type: `%v`, Kind: `%v`\n", rvoType.String(), rvoType.Kind()) +// fmt.Printf("Interface: Type: '%v', Kind: '%v'\n", rvoType.String(), rvoType.Kind()) // if rvoType.Kind() == reflect.Struct { // // Iterate over all fields of the Struct type (if any) @@ -266,7 +266,7 @@ func TestNormalizeCdx15VulnerabilitiesNatsBox(t *testing.T) { // fvKind := fieldValue.Kind() // fvValueOf := reflect.ValueOf(fieldValue) // // TODO: explore `field.PkgPath` -// fmt.Printf(">> Field(%v): `%s`, Kind: `%s`, Tags: `%s`, Value: `%v`\n", i, fieldName, fvKind.String(), field.Tag, fvValueOf) +// fmt.Printf(">> Field(%v): '%s', Kind: '%s', Tags: '%s', Value: '%v'\n", i, fieldName, fvKind.String(), field.Tag, fvValueOf) // // TODO: explore use of isItfc := field.CanInterface() // if fvKind == reflect.Ptr || fvKind == reflect.Interface { @@ -277,6 +277,6 @@ func TestNormalizeCdx15VulnerabilitiesNatsBox(t *testing.T) { // } // } // } else { -// fmt.Printf("!!! Unhandled Kind(): `%v`", rvoType.Kind()) +// fmt.Printf("!!! Unhandled Kind(): '%v'", rvoType.Kind()) // } // } diff --git a/cmd/patch.go b/cmd/patch.go index 85f6368a..82bc5517 100644 --- a/cmd/patch.go +++ b/cmd/patch.go @@ -65,7 +65,7 @@ func preRunTestForPatchFile(args []string) error { if patchFilename == "" { return getLogger().Errorf("Missing required argument(s): %s", FLAG_PATCH_FILE) } else if _, err := os.Stat(patchFilename); err != nil { - return getLogger().Errorf("File not found: `%s`", patchFilename) + return getLogger().Errorf("File not found: '%s'", patchFilename) } return nil } @@ -105,7 +105,7 @@ func initCommandPatchFlags(command *cobra.Command) (err error) { command.PersistentFlags().BoolVar(&utils.GlobalFlags.PersistentFlags.OutputNormalize, FLAG_OUTPUT_NORMALIZE, false, MSG_FLAG_OUTPUT_NORMALIZE) err = command.MarkFlagRequired(FLAG_PATCH_FILE) if err != nil { - err = getLogger().Errorf("unable to mark flag `%s` as required: %s", FLAG_PATCH_FILE, err) + err = getLogger().Errorf("unable to mark flag '%s' as required: %s", FLAG_PATCH_FILE, err) } return } @@ -117,7 +117,7 @@ func patchCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFilename, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFilename, writer) // Overcome Cobra limitation in variable reuse between diff. commands // That is, as soon as ANY command sets a default value, it cannot be changed @@ -128,7 +128,7 @@ func patchCmdImpl(cmd *cobra.Command, args []string) (err error) { // always close the output file if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -212,13 +212,13 @@ func Patch(writer io.Writer, persistentFlags utils.PersistentCommandFlags, patch // Output the "patched" version of the Input BOM format := persistentFlags.OutputFormat - getLogger().Infof("Writing patched BOM (`%s` format)...", format) + getLogger().Infof("Writing patched BOM ('%s' format)...", format) switch format { case FORMAT_JSON: err = document.WriteAsEncodedJSONInt(writer, utils.GlobalFlags.PersistentFlags.GetOutputIndentInt()) default: // Default to Text output for anything else (set as flag default) - getLogger().Warningf("Patch not supported for `%s` format; defaulting to `%s` format...", + getLogger().Warningf("Patch not supported for '%s' format; defaulting to '%s' format...", format, FORMAT_JSON) err = document.WriteAsEncodedJSONInt(writer, utils.GlobalFlags.PersistentFlags.GetOutputIndentInt()) } diff --git a/cmd/patch_format.go b/cmd/patch_format.go index 03ba569d..3ecc76a9 100644 --- a/cmd/patch_format.go +++ b/cmd/patch_format.go @@ -79,7 +79,7 @@ func (document *IETF6902Document) ReadRawBytes() (err error) { if document.rawBytes == nil { // validate filename if len(document.filename) == 0 { - return fmt.Errorf("schema: invalid filename: `%s`", document.filename) + return fmt.Errorf("schema: invalid filename: '%s'", document.filename) } // Conditionally append working directory if no abs. path detected @@ -103,7 +103,7 @@ func (document *IETF6902Document) ReadRawBytes() (err error) { return } - getLogger().Tracef("read data from: `%s`", document.filename) + getLogger().Tracef("read data from: '%s'", document.filename) getLogger().Tracef("\n >> rawBytes[:100]=[%s]", document.rawBytes[:100]) } return diff --git a/cmd/patch_test.go b/cmd/patch_test.go index ea1b069d..9ceb8fe1 100644 --- a/cmd/patch_test.go +++ b/cmd/patch_test.go @@ -180,14 +180,14 @@ func innerBufferedTestPatch(testInfo *PatchTestInfo) (outputBuffer bytes.Buffer, defer bufferedWriter.Flush() } else { outputFile, outputWriter, err = createOutputFile(testInfo.OutputFile) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", testInfo.OutputFile, outputWriter) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", testInfo.OutputFile, outputWriter) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file (even if error, as long as file handle returned) if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", testInfo.OutputFile) + getLogger().Infof("Closed output file: '%s'", testInfo.OutputFile) } }() @@ -303,7 +303,7 @@ func TestPatchRFC6902AppendixA1Patch1(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"baz\":\"qux\",\"foo\":\"bar\"}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -321,7 +321,7 @@ func TestPatchRFC6902AppendixA1BaseAddInteger(t *testing.T) { // Note: Go maps are not committed to preserving order; however, alpha. appears the default TEST_RESULT := "{\"foo\":\"bar\",\"integer\":100}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -339,7 +339,7 @@ func TestPatchRFC6902AppendixA1BaseAddFloat(t *testing.T) { // Note: Go maps are not committed to preserving order; however, alpha. appears the default TEST_RESULT := "{\"float\":3.14,\"foo\":\"bar\"}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -357,7 +357,7 @@ func TestPatchRFC6902AppendixA1BaseAddBool(t *testing.T) { // Note: Go maps are not committed to preserving order; however, alpha. appears the default TEST_RESULT := "{\"boolean\":true,\"foo\":\"bar\"}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -384,7 +384,7 @@ func TestPatchRFC6902AppendixA2Patch1(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"foo\":[\"bar\",\"qux\",\"baz\"]}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -401,7 +401,7 @@ func TestPatchRFC6902AppendixA2Patch2(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"foo\":[\"bar\",\"baz\",\"qux\"]}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -418,7 +418,7 @@ func TestPatchRFC6902AppendixA2Patch3(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"foo\":[\"bar\",\"baz\",\"qux\"]}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -435,7 +435,7 @@ func TestPatchRFC6902AppendixA2Patch4(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"foo\":[\"bar\",\"baz\",\"qux\"]}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -452,7 +452,7 @@ func TestPatchRFC6902AppendixA3Patch1Remove(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"foo\":\"bar\"}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -469,7 +469,7 @@ func TestPatchRFC6902AppendixA4Patch1Remove(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"foo\":[\"bar\",\"baz\"]}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -486,7 +486,7 @@ func TestPatchRFC6902AppendixA5Patch1Replace(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"baz\":\"boo\",\"foo\":\"bar\"}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -544,7 +544,7 @@ func TestPatchRFC6902AppendixA10Patch1(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"child\":{\"grandchild\":{}},\"foo\":\"bar\"}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } @@ -561,7 +561,7 @@ func TestPatchRFC6902AppendixA16Patch1(t *testing.T) { getLogger().Tracef("%s\n", buffer.String()) TEST_RESULT := "{\"foo\":[\"bar\",[\"abc\",\"def\"]]}\n" if buffer.String() != TEST_RESULT { - t.Errorf("invalid patch result. Expected:\n`%s`,\nActual:\n`%s`", TEST_RESULT, buffer.String()) + t.Errorf("invalid patch result. Expected:\n'%s',\nActual:\n'%s'", TEST_RESULT, buffer.String()) } } diff --git a/cmd/patch_verify_test.go b/cmd/patch_verify_test.go index 8fba35dc..7b192337 100644 --- a/cmd/patch_verify_test.go +++ b/cmd/patch_verify_test.go @@ -113,7 +113,7 @@ func VerifyPatched(record IETF6902Record, pResult interface{}, key string) (err case IETF_RFC6902_OP_ADD: if _, ok := typedResult[key]; !ok { formattedResult, _ := utils.EncodeAnyToDefaultIndentedJSONStr(typedResult) - err = getLogger().Errorf("patch failed. Key `%s`, found in: `%s`", key, formattedResult.String()) + err = getLogger().Errorf("patch failed. Key '%s', found in: '%s'", key, formattedResult.String()) return } case IETF_RFC6902_OP_REMOVE: diff --git a/cmd/query.go b/cmd/query.go index ad32d375..ee01087c 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -93,14 +93,14 @@ func queryCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFilename, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFilename, writer) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -431,7 +431,7 @@ func whereFilterMatch(mapObject map[string]interface{}, whereFilters []common.Wh value, present := mapObject[key] if !present { match = false - err = getLogger().Errorf("key `%s` not found in object map", key) + err = getLogger().Errorf("key '%s' not found in object map", key) break } @@ -455,7 +455,7 @@ func whereFilterMatch(mapObject map[string]interface{}, whereFilters []common.Wh err = enc.Encode(value) if err != nil { - err = getLogger().Errorf("Unable to convert value: `%v`, to []byte", value) + err = getLogger().Errorf("Unable to convert value: '%v', to []byte", value) return } diff --git a/cmd/query_test.go b/cmd/query_test.go index ab5dd1db..87d2bba3 100644 --- a/cmd/query_test.go +++ b/cmd/query_test.go @@ -103,14 +103,14 @@ func innerBufferedTestQuery(testInfo *CommonTestInfo, queryRequest *common.Query defer bufferedWriter.Flush() } else { outputFile, outputWriter, err = createOutputFile(testInfo.OutputFile) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", testInfo.OutputFile, outputWriter) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", testInfo.OutputFile, outputWriter) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file (even if error, as long as file handle returned) if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", testInfo.OutputFile) + getLogger().Infof("Closed output file: '%s'", testInfo.OutputFile) } }() @@ -159,7 +159,7 @@ func VerifySelectedFieldsInJsonMap(t *testing.T, keys []string, results interfac for _, key := range keys { _, exists = resultMap[key] if !exists { - t.Errorf("invalid results: key: `%s` does not exist.", key) + t.Errorf("invalid results: key: '%s' does not exist.", key) } } return diff --git a/cmd/report.go b/cmd/report.go index 6611a95b..ecaa561a 100644 --- a/cmd/report.go +++ b/cmd/report.go @@ -85,7 +85,7 @@ func processWhereFlag(cmd *cobra.Command) (whereFilters []common.WhereFilter, er whereValues, errGet := cmd.Flags().GetString(FLAG_REPORT_WHERE) if errGet != nil { - err = getLogger().Errorf("failed to read flag `%s` value", FLAG_REPORT_WHERE) + err = getLogger().Errorf("failed to read flag '%s' value", FLAG_REPORT_WHERE) return } @@ -153,10 +153,10 @@ func wrapTableRowText(maxChars int, joinChar string, columns ...interface{}) (ta // NOTE: JSON Unmarshal() always decodes JSON Numbers as "float64" type rowData[iCol] = strconv.FormatFloat(data, 'f', -1, 64) case nil: - //getLogger().Tracef("nil value for column: `%v`", columnData.DataKey) + //getLogger().Tracef("nil value for column: '%v'", columnData.DataKey) rowData[iCol] = REPORT_LIST_VALUE_NONE default: - err = getLogger().Errorf("Unexpected type for report data: column: %s, type: `%T`, value: `%v`", rowData[iCol], data, data) + err = getLogger().Errorf("Unexpected type for report data: column: %s, type: `%T`, value: '%v'", rowData[iCol], data, data) } } @@ -235,12 +235,12 @@ func prepareReportLineData(structIn interface{}, formatData []ColumnFormatData, if !dataFound { // TODO: change back? - getLogger().Errorf("data not found in structure: key: `%s`", columnData.DataKey) + getLogger().Errorf("data not found in structure: key: '%s'", columnData.DataKey) data = "" //return } - //fmt.Printf("data: `%v` (%T)\n", data, data) + //fmt.Printf("data: '%v' (%T)\n", data, data) switch typedData := data.(type) { case string: // replace line feeds with spaces in description @@ -284,10 +284,10 @@ func prepareReportLineData(structIn interface{}, formatData []ColumnFormatData, lineData = append(lineData, joinedData) case nil: - //getLogger().Tracef("nil value for column: `%v`", columnData.DataKey) + //getLogger().Tracef("nil value for column: '%v'", columnData.DataKey) lineData = append(lineData, REPORT_LIST_VALUE_NONE) default: - err = getLogger().Errorf("Unexpected type for report data: column: %s, type: `%T`, value: `%v`", columnData.DataKey, data, data) + err = getLogger().Errorf("Unexpected type for report data: column: %s, type: `%T`, value: '%v'", columnData.DataKey, data, data) } } diff --git a/cmd/report_test.go b/cmd/report_test.go index ebfcd91d..1e1882ab 100644 --- a/cmd/report_test.go +++ b/cmd/report_test.go @@ -58,11 +58,11 @@ func innerRunReportResultTests(t *testing.T, testInfo *CommonTestInfo, outputBuf if len(testInfo.ResultLineContainsValues) > 0 { matchFoundLine, matchFound := bufferLineContainsValues(outputBuffer, testInfo.ResultLineContainsValuesAtLineNum, testInfo.ResultLineContainsValues...) if !matchFound { - err = getLogger().Errorf("output does not contain expected values: `%v` at line: %v\n", strings.Join(testInfo.ResultLineContainsValues, ","), testInfo.ResultLineContainsValuesAtLineNum) + err = getLogger().Errorf("output does not contain expected values: '%v' at line: %v\n", strings.Join(testInfo.ResultLineContainsValues, ","), testInfo.ResultLineContainsValuesAtLineNum) t.Error(err.Error()) return } - getLogger().Tracef("output contains expected values: `%v` at line: %v\n", testInfo.ResultLineContainsValues, matchFoundLine) + getLogger().Tracef("output contains expected values: '%v' at line: %v\n", testInfo.ResultLineContainsValues, matchFoundLine) } // TEST: valid JSON if format JSON @@ -70,12 +70,12 @@ func innerRunReportResultTests(t *testing.T, testInfo *CommonTestInfo, outputBuf if testInfo.OutputFormat == FORMAT_JSON { // Use Marshal to test for validity if !utils.IsValidJsonRaw(outputBuffer.Bytes()) { - err = getLogger().Errorf("output did not contain valid format data; expected: `%s`", FORMAT_JSON) + err = getLogger().Errorf("output did not contain valid format data; expected: '%s'", FORMAT_JSON) t.Error(err.Error()) t.Logf("%s", outputBuffer.String()) return } - getLogger().Tracef("success: validated output format: `%s`", FORMAT_JSON) + getLogger().Tracef("success: validated output format: '%s'", FORMAT_JSON) } // TODO: add general validation for CSV and Markdown formats diff --git a/cmd/resource.go b/cmd/resource.go index c3f71ba5..090014a5 100644 --- a/cmd/resource.go +++ b/cmd/resource.go @@ -98,12 +98,12 @@ func NewCommandResource() *cobra.Command { // Make sure (optional) subcommand is known/valid if len(args) == 1 { if !preRunTestForSubcommand(VALID_SUBCOMMANDS_RESOURCE, args[0]) { - return getLogger().Errorf("Subcommand provided is not valid: `%v`", args[0]) + return getLogger().Errorf("Subcommand provided is not valid: '%v'", args[0]) } } if len(args) == 0 { - getLogger().Tracef("No subcommands provided; defaulting to: `%s` subcommand", SUBCOMMAND_SCHEMA_LIST) + getLogger().Tracef("No subcommands provided; defaulting to: '%s' subcommand", SUBCOMMAND_SCHEMA_LIST) } // Test for required flags (parameters) @@ -124,7 +124,7 @@ func retrieveResourceType(cmd *cobra.Command) (resourceType string, err error) { // validate resource type is a known keyword if !schema.IsValidResourceType(resourceType) { // invalid - err = getLogger().Errorf("invalid resource `%s`: `%s`", FLAG_RESOURCE_TYPE, resourceType) + err = getLogger().Errorf("invalid resource '%s': '%s'", FLAG_RESOURCE_TYPE, resourceType) } return @@ -137,14 +137,14 @@ func resourceCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFilename, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFilename, writer) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -201,7 +201,7 @@ func ListResources(writer io.Writer, persistentFlags utils.PersistentCommandFlag } format := persistentFlags.OutputFormat - getLogger().Infof("Outputting listing (`%s` format)...", format) + getLogger().Infof("Outputting listing ('%s' format)...", format) switch format { case FORMAT_TEXT: DisplayResourceListText(document, writer) @@ -211,7 +211,7 @@ func ListResources(writer io.Writer, persistentFlags utils.PersistentCommandFlag DisplayResourceListMarkdown(document, writer) default: // Default to Text output for anything else (set as flag default) - getLogger().Warningf("Listing not supported for `%s` format; defaulting to `%s` format...", + getLogger().Warningf("Listing not supported for '%s' format; defaulting to '%s' format...", format, FORMAT_TEXT) DisplayResourceListText(document, writer) } diff --git a/cmd/root.go b/cmd/root.go index 5ef5d468..14824f9a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -230,8 +230,8 @@ func initConfigurations() { getLogger().Enter() defer getLogger().Exit() - getLogger().Tracef("Executable Directory`: `%s`", utils.GlobalFlags.ExecDir) - getLogger().Tracef("Working Directory`: `%s`", utils.GlobalFlags.WorkingDir) + getLogger().Tracef("Executable Directory`: '%s'", utils.GlobalFlags.ExecDir) + getLogger().Tracef("Working Directory`: '%s'", utils.GlobalFlags.WorkingDir) // Print global flags in debug mode flagInfo, errFormat := getLogger().FormatStructE(utils.GlobalFlags) @@ -259,7 +259,7 @@ func initConfigurations() { err = LicensePolicyConfig.LoadHashPolicyConfigurationFile(licensePolicyFile, DEFAULT_LICENSE_POLICY_CONFIG) if err != nil { getLogger().Warning(err.Error()) - getLogger().Warningf("All license policies will default to `%s`.", schema.POLICY_UNDEFINED) + getLogger().Warningf("All license policies will default to '%s'.", schema.POLICY_UNDEFINED) } } @@ -303,7 +303,7 @@ func preRunTestForInputFile(args []string) error { } else if inputFilename == INPUT_TYPE_STDIN { return nil } else if _, err := os.Stat(inputFilename); err != nil { - return getLogger().Errorf("File not found: `%s`", inputFilename) + return getLogger().Errorf("File not found: '%s'", inputFilename) } return nil } @@ -313,11 +313,11 @@ func preRunTestForInputFile(args []string) error { func preRunTestForSubcommand(validSubcommands []string, subcommand string) bool { getLogger().Enter() defer getLogger().Exit() - getLogger().Tracef("subcommands: %v, subcommand: `%v`", validSubcommands, subcommand) + getLogger().Tracef("subcommands: %v, subcommand: '%v'", validSubcommands, subcommand) for _, value := range validSubcommands { if value == subcommand { - getLogger().Tracef("Valid subcommand `%v` found", subcommand) + getLogger().Tracef("Valid subcommand '%v' found", subcommand) return true } } diff --git a/cmd/root_test.go b/cmd/root_test.go index 11118452..f51fd5cc 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -175,7 +175,7 @@ func TestMain(m *testing.M) { // Run test exitCode := m.Run() - getLogger().Tracef("exit code: `%v`", exitCode) + getLogger().Tracef("exit code: '%v'", exitCode) // Exit with exit value from tests os.Exit(exitCode) @@ -224,7 +224,7 @@ func initTestApplicationDirectories() (err error) { // Need 'workingDir' to prepend to relative test files utils.GlobalFlags.WorkingDir, _ = os.Getwd() - getLogger().Infof("Set `utils.GlobalFlags.WorkingDir`: `%s`", utils.GlobalFlags.WorkingDir) + getLogger().Infof("Set `utils.GlobalFlags.WorkingDir`: '%s'", utils.GlobalFlags.WorkingDir) } return @@ -242,7 +242,7 @@ func EvaluateErrorAndKeyPhrases(t *testing.T, err error, messages []string) (mat for _, substring := range messages { if !strings.Contains(errorMessage, substring) { matched = false - t.Errorf("expected string: `%s` not found in error message: `%s`", substring, err.Error()) + t.Errorf("expected string: '%s' not found in error message: '%s'", substring, err.Error()) } } } @@ -276,7 +276,7 @@ func bufferLineContainsValues(buffer bytes.Buffer, lineNum int, values ...string if !strings.Contains(line, value) { // if we failed to match all values on the specified line return failure if curLineNum == lineNum { - getLogger().Infof("Actual contents of line %v: `%s`", curLineNum, line) + getLogger().Infof("Actual contents of line %v: '%s'", curLineNum, line) return curLineNum, false } // else, keep checking next line diff --git a/cmd/schema.go b/cmd/schema.go index 8a7d815c..7aaf43a2 100644 --- a/cmd/schema.go +++ b/cmd/schema.go @@ -75,7 +75,7 @@ func NewCommandSchema() *cobra.Command { var command = new(cobra.Command) command.Use = CMD_USAGE_SCHEMA_LIST // "schema" command.Short = "View supported SBOM schemas" - command.Long = fmt.Sprintf("View built-in BOM schemas supported by the utility. The default command produces a list based upon `%s`.", DEFAULT_SCHEMA_CONFIG) + command.Long = fmt.Sprintf("View built-in BOM schemas supported by the utility. The default command produces a list based upon '%s'.", DEFAULT_SCHEMA_CONFIG) command.Flags().StringVarP(&utils.GlobalFlags.PersistentFlags.OutputFormat, FLAG_FILE_OUTPUT_FORMAT, "", FORMAT_TEXT, FLAG_SCHEMA_OUTPUT_FORMAT_HELP+SCHEMA_LIST_SUPPORTED_FORMATS) command.Flags().StringP(FLAG_REPORT_WHERE, "", "", FLAG_REPORT_WHERE_HELP) @@ -92,12 +92,12 @@ func NewCommandSchema() *cobra.Command { // Make sure (optional) subcommand is known/valid if len(args) == 1 { if !preRunTestForSubcommand(VALID_SUBCOMMANDS_SCHEMA, args[0]) { - return getLogger().Errorf("Subcommand provided is not valid: `%v`", args[0]) + return getLogger().Errorf("Subcommand provided is not valid: '%v'", args[0]) } } if len(args) == 0 { - getLogger().Tracef("No subcommands provided; defaulting to: `%s` subcommand", SUBCOMMAND_SCHEMA_LIST) + getLogger().Tracef("No subcommands provided; defaulting to: '%s' subcommand", SUBCOMMAND_SCHEMA_LIST) } return } @@ -111,14 +111,14 @@ func schemaCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFile, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFile, writer) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file if outputFile != nil { err = outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -216,7 +216,7 @@ func ListSchemas(writer io.Writer, persistentFlags utils.PersistentCommandFlags, err = DisplaySchemasMarkdown(writer, filteredSchemas) default: // default to text format for anything else - getLogger().Warningf("unsupported format: `%s`; using default format.", format) + getLogger().Warningf("unsupported format: '%s'; using default format.", format) err = DisplaySchemasTabbedText(writer, filteredSchemas) } return @@ -236,7 +236,7 @@ func DisplaySchemasTabbedText(writer io.Writer, filteredSchemas []schema.FormatS // Emit no schemas found warning into output if len(filteredSchemas) == 0 { - getLogger().Warningf("No supported built-in schemas found in `%s`.\n", DEFAULT_SCHEMA_CONFIG) + getLogger().Warningf("No supported built-in schemas found in '%s'.\n", DEFAULT_SCHEMA_CONFIG) return } diff --git a/cmd/stats.go b/cmd/stats.go index b456c97a..be6b28d7 100644 --- a/cmd/stats.go +++ b/cmd/stats.go @@ -57,14 +57,14 @@ func statsCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFilename, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFilename, writer) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -111,7 +111,7 @@ func ListStats(writer io.Writer, persistentFlags utils.PersistentCommandFlags, s } format := persistentFlags.OutputFormat - getLogger().Infof("Outputting listing (`%s` format)...", format) + getLogger().Infof("Outputting listing ('%s' format)...", format) switch format { case FORMAT_TEXT: DisplayStatsText(document, writer) @@ -121,7 +121,7 @@ func ListStats(writer io.Writer, persistentFlags utils.PersistentCommandFlags, s // DisplayResourceListMarkdown(writer) default: // Default to Text output for anything else (set as flag default) - getLogger().Warningf("Stats not supported for `%s` format; defaulting to `%s` format...", + getLogger().Warningf("Stats not supported for '%s' format; defaulting to '%s' format...", format, FORMAT_TEXT) DisplayStatsText(document, writer) } @@ -152,7 +152,7 @@ func loadComponentStats(document *schema.BOM) (err error) { if len(aComponents) > 1 { // TODO: are they unique entries? or are DeepEqual() duplicates? - getLogger().Warningf("component `%v` has duplicate `%v` entries", key, len(aComponents)) + getLogger().Warningf("component '%v' has duplicate '%v' entries", key, len(aComponents)) } // for _, c := range aComponents { diff --git a/cmd/trim.go b/cmd/trim.go index 0c89884b..1aa35786 100644 --- a/cmd/trim.go +++ b/cmd/trim.go @@ -78,7 +78,7 @@ func initCommandTrimFlags(command *cobra.Command) (err error) { command.Flags().StringVarP(&utils.GlobalFlags.TrimFlags.RawKeys, FLAG_TRIM_MAP_KEYS, "", "", MSG_FLAG_TRIM_KEYS) err = command.MarkFlagRequired(FLAG_TRIM_MAP_KEYS) if err != nil { - err = getLogger().Errorf("unable to mark flag `%s` as required: %s", FLAG_TRIM_MAP_KEYS, err) + err = getLogger().Errorf("unable to mark flag '%s' as required: %s", FLAG_TRIM_MAP_KEYS, err) } return } @@ -90,31 +90,31 @@ func trimCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFilename, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFilename, writer) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() // --keys parameter if keys := utils.GlobalFlags.TrimFlags.RawKeys; keys != "" { utils.GlobalFlags.TrimFlags.Keys = strings.Split(keys, TRIM_KEYS_SEP) - getLogger().Tracef("Trim: keys: `%v`\n", keys) + getLogger().Tracef("Trim: keys: '%v'\n", keys) } else { - getLogger().Tracef("Trim: required parameter NOT found for `%s` flag", FLAG_TRIM_MAP_KEYS) + getLogger().Tracef("Trim: required parameter NOT found for '%s' flag", FLAG_TRIM_MAP_KEYS) } // --from parameter if paths := utils.GlobalFlags.TrimFlags.RawPaths; paths != "" { utils.GlobalFlags.TrimFlags.FromPaths = common.ParseFromPaths(paths) - getLogger().Tracef("Trim: paths: `%v`\n", paths) + getLogger().Tracef("Trim: paths: '%v'\n", paths) } else { - getLogger().Tracef("Trim: required parameter NOT found for `%s` flag", FLAG_TRIM_FROM_PATHS) + getLogger().Tracef("Trim: required parameter NOT found for '%s' flag", FLAG_TRIM_FROM_PATHS) } if err == nil { @@ -213,13 +213,13 @@ func Trim(writer io.Writer, persistentFlags utils.PersistentCommandFlags, trimFl // Output the "trimmed" version of the Input BOM format := persistentFlags.OutputFormat - getLogger().Infof("Writing trimmed BOM (`%s` format)...", format) + getLogger().Infof("Writing trimmed BOM ('%s' format)...", format) switch format { case FORMAT_JSON: err = document.WriteAsEncodedJSONInt(writer, utils.GlobalFlags.PersistentFlags.GetOutputIndentInt()) default: // Default to Text output for anything else (set as flag default) - getLogger().Warningf("Trim not supported for `%s` format; defaulting to `%s` format...", + getLogger().Warningf("Trim not supported for '%s' format; defaulting to '%s' format...", format, FORMAT_JSON) err = document.WriteAsEncodedJSONInt(writer, utils.GlobalFlags.PersistentFlags.GetOutputIndentInt()) } diff --git a/cmd/trim_test.go b/cmd/trim_test.go index ba341c42..cc525287 100644 --- a/cmd/trim_test.go +++ b/cmd/trim_test.go @@ -120,14 +120,14 @@ func innerBufferedTestTrim(testInfo *TrimTestInfo) (outputBuffer bytes.Buffer, e defer bufferedWriter.Flush() } else { outputFile, outputWriter, err = createOutputFile(testInfo.OutputFile) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", testInfo.OutputFile, outputWriter) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", testInfo.OutputFile, outputWriter) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file (even if error, as long as file handle returned) if outputFile != nil { outputFile.Close() - getLogger().Infof("Closed output file: `%s`", testInfo.OutputFile) + getLogger().Infof("Closed output file: '%s'", testInfo.OutputFile) } }() @@ -192,7 +192,7 @@ func VerifyTrimmed(pResult interface{}, key string) (err error) { // verify map key was removed if _, ok := typedValue[key]; ok { formattedValue, _ := utils.MarshalAnyToFormattedJsonString(typedValue) - err = getLogger().Errorf("trim failed. Key `%s`, found in: `%s`", key, formattedValue) + err = getLogger().Errorf("trim failed. Key '%s', found in: '%s'", key, formattedValue) return } case []interface{}: @@ -232,11 +232,11 @@ func TestTrimCdx14PreserveUnencodedChars(t *testing.T) { outputString := outputBuffer.String() if strings.Contains(outputString, TEST1) { - t.Errorf("removed expected utf8 characters from string: `%s`", TEST1) + t.Errorf("removed expected utf8 characters from string: '%s'", TEST1) } if strings.Contains(outputString, TEST2) { - t.Errorf("removed expected utf8 characters from string: `%s`", TEST2) + t.Errorf("removed expected utf8 characters from string: '%s'", TEST2) } } @@ -249,7 +249,7 @@ func TestTrimCdx14ComponentPropertiesSampleXXLBuffered(t *testing.T) { ti.ResultExpectedByteSize = 8121420 outputBuffer, _ := innerBufferedTestTrim(ti) // verify "after" trim lengths and content have removed properties - getLogger().Tracef("Len(outputBuffer): `%v`\n", outputBuffer.Len()) + getLogger().Tracef("Len(outputBuffer): '%v'\n", outputBuffer.Len()) if ti.ResultExpectedByteSize > 0 { if outputBuffer.Len() != ti.ResultExpectedByteSize { t.Error(fmt.Errorf("invalid trim result size (bytes): expected: %v, actual: %v", ti.ResultExpectedByteSize, outputBuffer.Len())) diff --git a/cmd/validate.go b/cmd/validate.go index 590c3e2c..00a8eba6 100644 --- a/cmd/validate.go +++ b/cmd/validate.go @@ -23,6 +23,7 @@ import ( "encoding/json" "fmt" "io" + "net/url" "os" "strings" @@ -39,7 +40,7 @@ const ( ) // validation flags -// TODO: support a `--truncate “ flag (or similar... `err-value-truncate` ) used +// TODO: support a '--truncate “ flag (or similar... 'err-value-truncate' ) used // to truncate formatted "value" (details) to bytes. // This would replace the hardcoded "DEFAULT_MAX_ERR_DESCRIPTION_LEN" value const ( @@ -72,7 +73,7 @@ const ( ) func NewCommandValidate() *cobra.Command { - // NOTE: `RunE` function takes precedent over `Run` (anonymous) function if both provided + // NOTE: 'RunE' function takes precedent over 'Run' (anonymous) function if both provided var command = new(cobra.Command) command.Use = CMD_USAGE_VALIDATE command.Short = "Validate input file against its declared BOM schema" @@ -122,7 +123,7 @@ func validateCmdImpl(cmd *cobra.Command, args []string) error { // always close the output file if outputFile != nil { err = outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -170,13 +171,13 @@ func validationError(document *schema.BOM, valid bool, err error) { } getLogger().Error(err) default: - getLogger().Tracef("unhandled error type: `%v`", t) + getLogger().Tracef("unhandled error type: '%v'", t) getLogger().Error(err) } } // ALWAYS output valid/invalid result (as informational) - message := fmt.Sprintf("document `%s`: valid=[%t]", document.GetFilename(), valid) + message := fmt.Sprintf("document '%s': valid=[%t]", document.GetFilename(), valid) getLogger().Info(message) } @@ -229,7 +230,7 @@ func Validate(writer io.Writer, persistentFlags utils.PersistentCommandFlags, va } if documentLoader == nil { - return INVALID, bom, schemaErrors, fmt.Errorf("unable to load document: `%s`", bom.GetFilename()) + return INVALID, bom, schemaErrors, fmt.Errorf("unable to load document: '%s'", bom.GetFilename()) } schemaName := bom.SchemaInfo.File @@ -239,15 +240,26 @@ func Validate(writer io.Writer, persistentFlags utils.PersistentCommandFlags, va // TODO: support remote schema load (via URL) with a flag (default should always be local file for security) forcedSchemaFile := validateFlags.ForcedJsonSchemaFile if forcedSchemaFile != "" { - getLogger().Infof("Validating document using forced schema (i.e., `--force %s`)", forcedSchemaFile) - //schemaName = document.SchemaInfo.File - schemaName = "file://" + forcedSchemaFile - getLogger().Infof("Loading schema `%s`...", schemaName) - schemaLoader = gojsonschema.NewReferenceLoader(schemaName) + + if !isValidURIPrefix(forcedSchemaFile) { + // attempt to load as a local file + forcedSchemaFile = "file://" + forcedSchemaFile + getLogger().Warningf("invalid schema URI: '%s'. Attempting to load as a local file...", forcedSchemaFile) + } + + _, errParseURI := url.ParseRequestURI(forcedSchemaFile) + if errParseURI != nil { + errSchemaURI := fmt.Errorf("invalid schema URI: '%s'. %w", forcedSchemaFile, errParseURI) + return INVALID, bom, schemaErrors, errSchemaURI + } + + getLogger().Infof("Loading schema from '--force' flag: '%s'...", forcedSchemaFile) + schemaLoader = gojsonschema.NewReferenceLoader(forcedSchemaFile) + getLogger().Infof("Validating document using forced schema (i.e., '--force %s')", forcedSchemaFile) } else { // Load the matching JSON schema (format, version and variant) from embedded resources // i.e., using the matching schema found in config.json (as SchemaInfo) - getLogger().Infof("Loading schema `%s`...", bom.SchemaInfo.File) + getLogger().Infof("Loading schema '%s'...", bom.SchemaInfo.File) bSchema, errRead = resources.BOMSchemaFiles.ReadFile(bom.SchemaInfo.File) if errRead != nil { @@ -262,7 +274,7 @@ func Validate(writer io.Writer, persistentFlags utils.PersistentCommandFlags, va if schemaLoader == nil { // we force result to INVALID as any errors from the library means // we could NOT actually confirm the input documents validity - return INVALID, bom, schemaErrors, fmt.Errorf("unable to read schema: `%s`", schemaName) + return INVALID, bom, schemaErrors, fmt.Errorf("unable to read schema: '%s'", schemaName) } // create a reusable schema object (TODO: validate multiple documents) @@ -285,18 +297,18 @@ func Validate(writer io.Writer, persistentFlags utils.PersistentCommandFlags, va } if errLoad != nil { - return INVALID, bom, schemaErrors, fmt.Errorf("unable to load schema: `%s`", schemaName) + return INVALID, bom, schemaErrors, fmt.Errorf("unable to load schema: '%s'", schemaName) } - getLogger().Infof("Schema `%s` loaded.", schemaName) + getLogger().Infof("Schema '%s' loaded.", schemaName) // Validate against the schema and save result determination - getLogger().Infof("Validating `%s`...", bom.GetFilenameInterpolated()) + getLogger().Infof("Validating '%s'...", bom.GetFilenameInterpolated()) result, errValidate := jsonBOMSchema.Validate(documentLoader) // ALWAYS set the valid return parameter and provide user an informative message valid = result.Valid() - getLogger().Infof("BOM valid against JSON schema: `%t`", valid) + getLogger().Infof("BOM valid against JSON schema: '%t'", valid) // Catch general errors from the validation package/library itself and display them if errValidate != nil { @@ -305,8 +317,8 @@ func Validate(writer io.Writer, persistentFlags utils.PersistentCommandFlags, va return INVALID, bom, schemaErrors, errValidate } - // Note: actual schema validation errors appear in the `result` object - // Save all schema errors found in the `result` object in an explicit, typed error + // Note: actual schema validation errors appear in the 'result' object + // Save all schema errors found in the 'result' object in an explicit, typed error if schemaErrors = result.Errors(); len(schemaErrors) > 0 { errInvalid := NewInvalidSBOMError( bom, @@ -377,6 +389,17 @@ func validateCustom(document *schema.BOM, policyConfig *schema.LicensePolicyConf return VALID, nil } +func isValidURIPrefix(str string) bool { + // Check for common URI prefixes + prefixes := []string{"http://", "https://", "file://"} + for _, prefix := range prefixes { + if strings.HasPrefix(str, prefix) { + return true + } + } + return false +} + // func isJSONSchema(filePath string) (isSchema bool, err error) { // isSchema = false // file, err := os.Open(filePath) diff --git a/cmd/validate_custom.go b/cmd/validate_custom.go index 0cddfe44..d01c4f95 100644 --- a/cmd/validate_custom.go +++ b/cmd/validate_custom.go @@ -140,7 +140,7 @@ func validateCustomMetadataProperties(document *schema.BOM) (err error) { } for _, checks := range validationProps { - getLogger().Tracef("Running validation checks: Property name: `%s`, checks(s): `%v`...", checks.Name, checks) + getLogger().Tracef("Running validation checks: Property name: '%s', checks(s): '%v'...", checks.Name, checks) values, found := hashmap.Get(checks.Name) if !found { err = NewSbomMetadataPropertyError( @@ -154,7 +154,7 @@ func validateCustomMetadataProperties(document *schema.BOM) (err error) { // i.e., Multiple values with same "key" (specified), not provided // TODO: currently hashmap assumes "name" as the key; this could be dynamic (using reflect) if checks.CheckUnique != "" { - getLogger().Tracef("CheckUnique: key: `%s`, `%s`, value(s): `%v`...", checks.Key, checks.CheckUnique, values) + getLogger().Tracef("CheckUnique: key: '%s', '%s', value(s): '%v'...", checks.Key, checks.CheckUnique, values) // if multi-hashmap has more than one value, property is NOT unique if len(values) > 1 { err := NewSbomMetadataPropertyError( @@ -166,7 +166,7 @@ func validateCustomMetadataProperties(document *schema.BOM) (err error) { } if checks.CheckRegex != "" { - getLogger().Tracef("CheckRegex: field: `%s`, regex: `%v`...", checks.CheckRegex, checks.Value) + getLogger().Tracef("CheckRegex: field: '%s', regex: '%v'...", checks.CheckRegex, checks.Value) compiledRegex, errCompile := utils.CompileRegex(checks.Value) if errCompile != nil { return errCompile @@ -175,7 +175,7 @@ func validateCustomMetadataProperties(document *schema.BOM) (err error) { // TODO: check multiple values if provided value := values[0] if stringValue, ok := value.(string); ok { - getLogger().Debugf(">> Testing value: `%s`...", stringValue) + getLogger().Debugf(">> Testing value: '%s'...", stringValue) matched := compiledRegex.Match([]byte(stringValue)) if !matched { err = NewSbomMetadataPropertyError( diff --git a/cmd/validate_custom_test.go b/cmd/validate_custom_test.go index b7c86f25..94156a3e 100644 --- a/cmd/validate_custom_test.go +++ b/cmd/validate_custom_test.go @@ -88,7 +88,7 @@ func TestValidateCustomFormatUnsupportedSPDX(t *testing.T) { func TestValidateCustomErrorCdx14NoLicensesFound(t *testing.T) { vti := NewValidateTestInfo(TEST_CUSTOM_CDX_1_4_INVALID_LICENSES_NOT_FOUND, FORMAT_ANY, SCHEMA_VARIANT_NONE, &InvalidSBOMError{}) document, results, _ := innerTestValidateCustom(t, *vti) - getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) + getLogger().Debugf("filename: '%s', results:\n%v", document.GetFilename(), results) } // ------------------------------------------- @@ -98,13 +98,13 @@ func TestValidateCustomErrorCdx14NoLicensesFound(t *testing.T) { func TestValidateCustomCdx14MetadataPropsMissingDisclaimer(t *testing.T) { vti := NewValidateTestInfo(TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_MISSING, FORMAT_TEXT, SCHEMA_VARIANT_CUSTOM, &InvalidSBOMError{}) document, results, _ := innerTestValidate(t, *vti) - getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) + getLogger().Debugf("filename: '%s', results:\n%v", document.GetFilename(), results) } func TestValidateCustomCdx14MetadataPropsMissingClassification(t *testing.T) { vti := NewValidateTestInfo(TEST_CUSTOM_CDX_1_4_METADATA_PROPS_CLASSIFICATION_MISSING, FORMAT_TEXT, SCHEMA_VARIANT_CUSTOM, &InvalidSBOMError{}) document, results, _ := innerTestValidate(t, *vti) - getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) + getLogger().Debugf("filename: '%s', results:\n%v", document.GetFilename(), results) } func TestValidateCustomCdx14MetadataPropsInvalidDisclaimer(t *testing.T) { @@ -167,7 +167,7 @@ func TestValidateCustomCdx14MetadataPropertyUniqueDisclaimer(t *testing.T) { TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_UNIQUE, SCHEMA_VARIANT_NONE, &SBOMMetadataPropertyError{}) - getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) + getLogger().Debugf("filename: '%s', results:\n%v", document.GetFilename(), results) } func TestValidateCustomCdx14MetadataPropertyUniqueClassification(t *testing.T) { @@ -175,7 +175,7 @@ func TestValidateCustomCdx14MetadataPropertyUniqueClassification(t *testing.T) { TEST_CUSTOM_CDX_1_4_METADATA_PROPS_DISCLAIMER_UNIQUE, SCHEMA_VARIANT_NONE, &SBOMMetadataPropertyError{}) - getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) + getLogger().Debugf("filename: '%s', results:\n%v", document.GetFilename(), results) } // ------------------------------------------- diff --git a/cmd/validate_format.go b/cmd/validate_format.go index 32593949..b8ee6971 100644 --- a/cmd/validate_format.go +++ b/cmd/validate_format.go @@ -62,11 +62,11 @@ const ( // Recurring / translatable messages const ( - MSG_INFO_FORMATTING_ERROR_RESULTS = "Formatting error results (`%s` format)..." + MSG_INFO_FORMATTING_ERROR_RESULTS = "Formatting error results ('%s' format)..." MSG_INFO_SCHEMA_ERRORS_DETECTED = "(%d) schema errors detected." MSG_INFO_TOO_MANY_ERRORS = "Too many errors. Showing (%v/%v) errors." MSG_ERROR_FORMATTING_ERROR = "formatting error: %s" - MSG_WARN_INVALID_FORMAT = "invalid format. error results not supported for `%s` format; defaulting to `%s` format..." + MSG_WARN_INVALID_FORMAT = "invalid format. error results not supported for '%s' format; defaulting to '%s' format..." ) var VALIDATION_ERROR_TITLES = []string{ diff --git a/cmd/validate_test.go b/cmd/validate_test.go index 2a0f7381..1ffda842 100644 --- a/cmd/validate_test.go +++ b/cmd/validate_test.go @@ -128,20 +128,20 @@ func innerTestValidate(t *testing.T, vti ValidateTestInfo) (document *schema.BOM utils.GlobalFlags.ValidateFlags, ) - getLogger().Tracef("document: `%s`, isValid=`%t`, actualError=`%T`", document.GetFilename(), isValid, actualError) + getLogger().Tracef("document: '%s', isValid=`%t`, actualError=`%T`", document.GetFilename(), isValid, actualError) // Always compare actual against expected error (even if it is `nil`) expectedError := vti.ResultExpectedError if !ErrorTypesMatch(actualError, expectedError) { if len(schemaErrors) > 0 { - getLogger().Debugf("schemaErrors=`%s`", schemaErrors) + getLogger().Debugf("schemaErrors='%s'", schemaErrors) } switch t := actualError.(type) { default: - fmt.Printf("unhandled error type: `%v`\n", t) - fmt.Printf(">> value: `%v`\n", t) + fmt.Printf("unhandled error type: '%v'\n", t) + fmt.Printf(">> value: '%v'\n", t) getLogger().Error(actualError) } t.Errorf("expected error type: `%T`, actual type: `%T`", expectedError, actualError) @@ -168,7 +168,7 @@ func innerTestValidate(t *testing.T, vti ValidateTestInfo) (document *schema.BOM } } else if !utils.IsValidJsonRaw(outputBuffer.Bytes()) { - err := getLogger().Errorf("output did not contain valid format data; expected: `%s`", FORMAT_JSON) + err := getLogger().Errorf("output did not contain valid format data; expected: '%s'", FORMAT_JSON) t.Error(err.Error()) t.Logf("%s", outputBuffer.String()) return @@ -185,7 +185,7 @@ func innerValidateErrorBuffered(persistentFlags utils.PersistentCommandFlags, va // Invoke the actual command (API) isValid, document, schemaErrors, err = Validate(outputWriter, persistentFlags, utils.GlobalFlags.ValidateFlags) - getLogger().Tracef("document: `%s`, isValid=`%t`, err=`%T`", document.GetFilename(), isValid, err) + getLogger().Tracef("document: '%s', isValid=`%t`, err=`%T`", document.GetFilename(), isValid, err) return } @@ -254,13 +254,13 @@ func innerTestSchemaErrorAndErrorResults(t *testing.T, vti := NewValidateTestInfo(filename, FORMAT_TEXT, variant, &InvalidSBOMError{}) document, results, _ := innerTestValidate(t, *vti) - getLogger().Debugf("filename: `%s`, results:\n%v", document.GetFilename(), results) + getLogger().Debugf("filename: '%s', results:\n%v", document.GetFilename(), results) // See ResultType struct fields (and values) in the `gojsonschema` package exists := schemaErrorExists(results, schemaErrorType, schemaErrorField, schemaErrorValue) if !exists { - t.Errorf("expected schema error: Type=`%s`, Field=`%s`, Value=`%s`", + t.Errorf("expected schema error: Type='%s', Field='%s', Value='%s'", schemaErrorType, schemaErrorField, schemaErrorValue) @@ -287,18 +287,18 @@ func schemaErrorExists(schemaErrors []gojsonschema.ResultError, // we have matched on the type (key) field, continue to match other fields if expectedField != "" && actualField != expectedField { - getLogger().Tracef("expected Field: `%s`; actual Field: `%s`", expectedField, actualField) + getLogger().Tracef("expected Field: '%s'; actual Field: '%s'", expectedField, actualField) return false } if expectedValue != "" && actualValue != expectedValue { - getLogger().Tracef("expected Value: `%s`; actual Value: `%s`", actualValue, expectedValue) + getLogger().Tracef("expected Value: '%s'; actual Value: '%s'", actualValue, expectedValue) return false } return true } else { - getLogger().Debugf("Skipping result[%d]: expected Type: `%s`; actual Type: `%s`", i, expectedType, actualType) + getLogger().Debugf("Skipping result[%d]: expected Type: '%s'; actual Type: '%s'", i, expectedType, actualType) } } return false @@ -401,11 +401,11 @@ func TestValidateCdx14ErrorResultsUniqueComponentsJson(t *testing.T) { _, schemaErrors, _ := innerTestValidate(t, *vti) if len(schemaErrors) != EXPECTED_ERROR_NUM { - t.Errorf("invalid schema error count: expected `%v`; actual: `%v`)", EXPECTED_ERROR_NUM, len(schemaErrors)) + t.Errorf("invalid schema error count: expected '%v'; actual: '%v')", EXPECTED_ERROR_NUM, len(schemaErrors)) } if schemaErrors[0].Context().String() != EXPECTED_ERROR_CONTEXT { - t.Errorf("invalid schema error context: expected `%v`; actual: `%v`)", EXPECTED_ERROR_CONTEXT, schemaErrors[0].Context().String()) + t.Errorf("invalid schema error context: expected '%v'; actual: '%v')", EXPECTED_ERROR_CONTEXT, schemaErrors[0].Context().String()) } } @@ -418,11 +418,11 @@ func TestValidateCdx14ErrorResultsFormatIriReferencesJson(t *testing.T) { _, schemaErrors, _ := innerTestValidate(t, *vti) if len(schemaErrors) != EXPECTED_ERROR_NUM { - t.Errorf("invalid schema error count: expected `%v`; actual: `%v`)", EXPECTED_ERROR_NUM, len(schemaErrors)) + t.Errorf("invalid schema error count: expected '%v'; actual: '%v')", EXPECTED_ERROR_NUM, len(schemaErrors)) } if schemaErrors[0].Context().String() != EXPECTED_ERROR_CONTEXT { - t.Errorf("invalid schema error context: expected `%v`; actual: `%v`)", EXPECTED_ERROR_CONTEXT, schemaErrors[0].Context().String()) + t.Errorf("invalid schema error context: expected '%v'; actual: '%v')", EXPECTED_ERROR_CONTEXT, schemaErrors[0].Context().String()) } } diff --git a/cmd/vulnerability.go b/cmd/vulnerability.go index d26ebc88..31683aa0 100644 --- a/cmd/vulnerability.go +++ b/cmd/vulnerability.go @@ -125,7 +125,7 @@ func NewCommandVulnerability() *cobra.Command { // Make sure subcommand is known if !preRunTestForSubcommand(VALID_SUBCOMMANDS_VULNERABILITY, args[0]) { - return getLogger().Errorf("Subcommand provided is not valid: `%v`", args[0]) + return getLogger().Errorf("Subcommand provided is not valid: '%v'", args[0]) } // Test for required flags (parameters) @@ -144,14 +144,14 @@ func vulnerabilityCmdImpl(cmd *cobra.Command, args []string) (err error) { // Create output writer outputFilename := utils.GlobalFlags.PersistentFlags.OutputFile outputFile, writer, err := createOutputFile(outputFilename) - getLogger().Tracef("outputFile: `%v`; writer: `%v`", outputFile, writer) + getLogger().Tracef("outputFile: '%v'; writer: '%v'", outputFile, writer) // use function closure to assure consistent error output based upon error type defer func() { // always close the output file if outputFile != nil { err = outputFile.Close() - getLogger().Infof("Closed output file: `%s`", outputFilename) + getLogger().Infof("Closed output file: '%s'", outputFilename) } }() @@ -215,7 +215,7 @@ func ListVulnerabilities(writer io.Writer, persistentFlags utils.PersistentComma } format := persistentFlags.OutputFormat - getLogger().Infof("Outputting listing (`%s` format)...", format) + getLogger().Infof("Outputting listing ('%s' format)...", format) switch format { case FORMAT_TEXT: err = DisplayVulnListText(document, writer, flags) @@ -227,7 +227,7 @@ func ListVulnerabilities(writer io.Writer, persistentFlags utils.PersistentComma err = DisplayVulnListJson(document, writer, flags) default: // Default to Text output for anything else (set as flag default) - getLogger().Warningf("Listing not supported for `%s` format; defaulting to `%s` format...", + getLogger().Warningf("Listing not supported for '%s' format; defaulting to '%s' format...", format, FORMAT_JSON) err = DisplayVulnListText(document, writer, flags) } diff --git a/common/query_types.go b/common/query_types.go index 52369e6c..c9acd2f1 100644 --- a/common/query_types.go +++ b/common/query_types.go @@ -204,7 +204,7 @@ func ParseWhereFilter(rawExpression string) (pWhereSelector *WhereFilter) { var errCompile error whereFilter.ValueRegEx, errCompile = utils.CompileRegex(whereFilter.Value) - //getLogger().Debugf(">> Regular expression: `%v`...", whereFilter.ValueRegEx) + //getLogger().Debugf(">> Regular expression: '%v'...", whereFilter.ValueRegEx) if errCompile != nil { return // nil diff --git a/log/log.go b/log/log.go index 2615f0a5..18fd1769 100644 --- a/log/log.go +++ b/log/log.go @@ -383,7 +383,7 @@ func (log MiniLogger) DumpStruct(structName string, field interface{}) error { } if structName != "" { - sb.WriteString(fmt.Sprintf("`%s` (%T) = %s", structName, reflect.TypeOf(field), formattedStruct)) + sb.WriteString(fmt.Sprintf("'%s' (%T) = %s", structName, reflect.TypeOf(field), formattedStruct)) } else { sb.WriteString(formattedStruct) } @@ -399,7 +399,7 @@ func (log MiniLogger) DumpArgs() { for i, a := range args { // TODO: print to output stream fmt.Print(log.indentRunes) - fmt.Printf("os.Arg[%d]: `%v`\n", i, a) + fmt.Printf("os.Arg[%d]: '%v'\n", i, a) } } diff --git a/main.go b/main.go index 4f9d6f7c..5d9b293f 100644 --- a/main.go +++ b/main.go @@ -56,7 +56,7 @@ func init() { Logger.InitLogLevelAndModeFromFlags() // Emit log level used from this point forward - Logger.Tracef("Logger (%T) created: with Level=`%v`", Logger, Logger.GetLevelName()) + Logger.Tracef("Logger (%T) created: with Level='%v'", Logger, Logger.GetLevelName()) // Provide access to project logger to other modules cmd.ProjectLogger = Logger @@ -80,7 +80,7 @@ func init() { func printWelcome() { if !Logger.QuietModeOn() { goos := fmt.Sprintf("(%s/%s)", runtime.GOOS, runtime.GOARCH) - echo := fmt.Sprintf("Welcome to the %s! Version `%s` (%s) %s\n", Project, Version, Binary, goos) + echo := fmt.Sprintf("Welcome to the %s! Version '%s' (%s) %s\n", Project, Version, Binary, goos) // Logger will only print the welcome if log level requested indicates INFO level (or higher) Logger.DumpString(echo) // Show intent to not check for error returns as there is no recovery diff --git a/schema/bom.go b/schema/bom.go index aeb02217..be680b61 100644 --- a/schema/bom.go +++ b/schema/bom.go @@ -238,7 +238,7 @@ func (bom *BOM) GetKeyValueAsString(key string) (sValue string, err error) { getLogger().Enter() defer getLogger().Exit() - getLogger().Tracef("key: `%s`", key) + getLogger().Tracef("key: '%s'", key) if (bom.JsonMap) == nil { err := fmt.Errorf("document object does not have a Map allocated") @@ -248,18 +248,18 @@ func (bom *BOM) GetKeyValueAsString(key string) (sValue string, err error) { value := bom.JsonMap[key] if value == nil { - getLogger().Tracef("key: `%s` not found in document map", key) + getLogger().Tracef("key: '%s' not found in document map", key) return "", nil } - getLogger().Tracef("value: `%v` (%T)", value, value) + getLogger().Tracef("value: '%v' (%T)", value, value) return value.(string), nil } func (bom *BOM) ReadRawBytes() (err error) { // validate filename if len(bom.filename) == 0 { - return fmt.Errorf("schema: invalid filename: `%s`", bom.filename) + return fmt.Errorf("schema: invalid filename: '%s'", bom.filename) } // Check to see of stdin is the BOM source data @@ -290,7 +290,7 @@ func (bom *BOM) ReadRawBytes() (err error) { } } - getLogger().Tracef("read data from: `%s`", bom.filename) + getLogger().Tracef("read data from: '%s'", bom.filename) getLogger().Tracef("\n >> rawBytes[:100]=[%s]", bom.rawBytes[:100]) return } diff --git a/schema/bom_hash.go b/schema/bom_hash.go index d95c882d..84d6271d 100644 --- a/schema/bom_hash.go +++ b/schema/bom_hash.go @@ -92,11 +92,11 @@ func (bom *BOM) HashmapComponent(cdxComponent CDXComponent, whereFilters []commo } if cdxComponent.Version == "" { - getLogger().Warningf("component named `%s` missing `version`", cdxComponent.Name) + getLogger().Warningf("component named '%s' missing `version`", cdxComponent.Name) } if cdxComponent.BOMRef == nil || *cdxComponent.BOMRef == "" { - getLogger().Warningf("component named `%s` missing `bom-ref`", cdxComponent.Name) + getLogger().Warningf("component named '%s' missing `bom-ref`", cdxComponent.Name) } // Map CDX data struct to our internal structure used for reporting/stats gathering @@ -174,11 +174,11 @@ func (bom *BOM) HashmapService(cdxService CDXService, whereFilters []common.Wher } if cdxService.Version == "" { - getLogger().Warningf("service named `%s` missing `version`", cdxService.Name) + getLogger().Warningf("service named '%s' missing `version`", cdxService.Name) } if cdxService.BOMRef == nil || *cdxService.BOMRef == "" { - getLogger().Warningf("service named `%s` missing `bom-ref`", cdxService.Name) + getLogger().Warningf("service named '%s' missing `bom-ref`", cdxService.Name) } // Map CDX data struct to our internal structure used for reporting/stats gathering @@ -334,15 +334,15 @@ func (bom *BOM) HashmapVulnerability(cdxVulnerability CDXVulnerability, whereFil } if cdxVulnerability.Published == "" { - getLogger().Warningf("vulnerability (`%s`) missing `published` date", cdxVulnerability.Id) + getLogger().Warningf("vulnerability ('%s') missing `published` date", cdxVulnerability.Id) } if cdxVulnerability.Created == "" { - getLogger().Warningf("vulnerability (`%s`) missing `created` date", cdxVulnerability.Id) + getLogger().Warningf("vulnerability ('%s') missing `created` date", cdxVulnerability.Id) } if cdxVulnerability.Ratings == nil || len(*cdxVulnerability.Ratings) == 0 { - getLogger().Warningf("vulnerability (`%s`) missing `ratings`", cdxVulnerability.Id) + getLogger().Warningf("vulnerability ('%s') missing `ratings`", cdxVulnerability.Id) } // hash any component w/o a license using special key name diff --git a/schema/bom_hash_test.go b/schema/bom_hash_test.go index cbb8b317..86fd6c59 100644 --- a/schema/bom_hash_test.go +++ b/schema/bom_hash_test.go @@ -106,7 +106,7 @@ func TestMain(m *testing.M) { // Run test exitCode := m.Run() - getLogger().Tracef("exit code: `%v`", exitCode) + getLogger().Tracef("exit code: '%v'", exitCode) // Exit with exit value from tests os.Exit(exitCode) @@ -157,7 +157,7 @@ func initTestApplicationDirectories() (err error) { // Need 'workingDir' to prepend to relative test files utils.GlobalFlags.WorkingDir, _ = os.Getwd() - getLogger().Infof("Set `utils.GlobalFlags.WorkingDir`: `%s`", utils.GlobalFlags.WorkingDir) + getLogger().Infof("Set `utils.GlobalFlags.WorkingDir`: '%s'", utils.GlobalFlags.WorkingDir) } return @@ -169,7 +169,7 @@ func loadBOMFile(inputFile string) (document *BOM, err error) { // check for required fields on command if inputFile == "" { - return nil, fmt.Errorf("invalid input file: `%s` ", inputFile) + return nil, fmt.Errorf("invalid input file: '%s' ", inputFile) } // Construct a BOM document object around the input file @@ -177,12 +177,12 @@ func loadBOMFile(inputFile string) (document *BOM, err error) { document.filename = inputFile // Load the raw, candidate BOM (file) as JSON data - getLogger().Infof("Attempting to load and unmarshal data from: `%s`...", document.GetFilenameInterpolated()) + getLogger().Infof("Attempting to load and unmarshal data from: '%s'...", document.GetFilenameInterpolated()) err = document.UnmarshalBOMAsJSONMap() // i.e., utils.Flags.InputFile if err != nil { return } - getLogger().Infof("Successfully unmarshalled data from: `%s`", document.GetFilenameInterpolated()) + getLogger().Infof("Successfully unmarshalled data from: '%s'", document.GetFilenameInterpolated()) // Search the document keys/values for known BOM formats and schema in the config. file getLogger().Infof("Determining file's BOM format and version...") @@ -192,7 +192,7 @@ func loadBOMFile(inputFile string) (document *BOM, err error) { } // Display detected format, version with (optional) schema variant (i.e., if requested on command line) - getLogger().Infof("Determined BOM format, version (variant): `%s`, `%s` %s", + getLogger().Infof("Determined BOM format, version (variant): '%s', '%s' %s", document.FormatInfo.CanonicalName, document.SchemaInfo.Version, FormatSchemaVariant(document.SchemaInfo.Variant)) diff --git a/schema/bom_query.go b/schema/bom_query.go index 956cf951..f3b719b5 100644 --- a/schema/bom_query.go +++ b/schema/bom_query.go @@ -40,11 +40,11 @@ func whereFilterMatch(mapObject map[string]interface{}, whereFilters []common.Wh key = filter.Key value, present := mapObject[key] - getLogger().Debugf("testing object map[%s]: `%v`", key, value) + getLogger().Debugf("testing object map[%s]: '%v'", key, value) if !present { match = false - err = getLogger().Errorf("key `%s` not found ib object map", key) + err = getLogger().Errorf("key '%s' not found ib object map", key) break } @@ -69,13 +69,13 @@ func whereFilterMatch(mapObject map[string]interface{}, whereFilters []common.Wh // NOTE: JSON Unmarshal() always decodes JSON Numbers as "float64" type value = strconv.FormatFloat(data, 'f', -1, 64) default: - getLogger().Errorf("unhandled datatype. key=%s, value=`%v`, type=`%T`", key, data, data) + getLogger().Errorf("unhandled datatype. key=%s, value='%v', type=`%T`", key, data, data) } err = enc.Encode(value) if err != nil { - err = getLogger().Errorf("Unable to convert value: `%v`, to []byte", value) + err = getLogger().Errorf("Unable to convert value: '%v', to []byte", value) return } diff --git a/schema/license_expression.go b/schema/license_expression.go index 5987a3cc..2481d24b 100644 --- a/schema/license_expression.go +++ b/schema/license_expression.go @@ -109,7 +109,7 @@ func parseCompoundExpression(policyConfig *LicensePolicyConfig, expression *Comp token = tokens[index] switch token { case LEFT_PARENS: - getLogger().Debugf("[%v] LEFT_PARENS: `%v`", index, token) + getLogger().Debugf("[%v] LEFT_PARENS: '%v'", index, token) childExpression := NewCompoundExpression() // if we have no conjunction, this compound expression represents the "left" operand @@ -135,17 +135,17 @@ func parseCompoundExpression(policyConfig *LicensePolicyConfig, expression *Comp } case RIGHT_PARENS: - getLogger().Debugf("[%v] RIGHT_PARENS: `%v`", index, token) + getLogger().Debugf("[%v] RIGHT_PARENS: '%v'", index, token) err = FinalizeCompoundPolicy(expression) return index, err // Do NOT Increment, parent caller will do that case AND: - getLogger().Debugf("[%v] AND (Conjunction): `%v`", index, token) + getLogger().Debugf("[%v] AND (Conjunction): '%v'", index, token) expression.Conjunction = token case OR: - getLogger().Debugf("[%v] OR (Conjunction): `%v`", index, token) + getLogger().Debugf("[%v] OR (Conjunction): '%v'", index, token) expression.Conjunction = token case WITH: - getLogger().Debugf("[%v] WITH (Preposition): `%v`", index, token) + getLogger().Debugf("[%v] WITH (Preposition): '%v'", index, token) if expression.Conjunction == "" { expression.PrepLeft = token } else { @@ -153,7 +153,7 @@ func parseCompoundExpression(policyConfig *LicensePolicyConfig, expression *Comp expression.PrepRight = token } default: - getLogger().Debugf("[%v] Simple Expression: `%v`", index, token) + getLogger().Debugf("[%v] Simple Expression: '%v'", index, token) // if we have no conjunction, this compound expression represents the "left" operand if expression.Conjunction == CONJUNCTION_UNDEFINED { if expression.PrepLeft == "" { @@ -202,7 +202,7 @@ func FinalizeCompoundPolicy(expression *CompoundExpression) (err error) { return getLogger().Errorf("Expression is nil") } - getLogger().Debugf("Evaluating policy: (`%s` `%s` `%s`)", + getLogger().Debugf("Evaluating policy: ('%s' '%s' '%s')", expression.LeftUsagePolicy, expression.Conjunction, expression.RightUsagePolicy) @@ -298,7 +298,7 @@ func FinalizeCompoundPolicy(expression *CompoundExpression) (err error) { } // else default expression.CompoundUsagePolicy is UNDEFINED default: expression.CompoundUsagePolicy = POLICY_UNDEFINED - return getLogger().Errorf("%s: %s: `%s`", + return getLogger().Errorf("%s: %s: '%s'", MSG_LICENSE_INVALID_EXPRESSION, MSG_LICENSE_EXPRESSION_INVALID_CONJUNCTION, expression.Conjunction) diff --git a/schema/license_expression_test.go b/schema/license_expression_test.go index 7078cdf3..2eacc78e 100644 --- a/schema/license_expression_test.go +++ b/schema/license_expression_test.go @@ -60,42 +60,42 @@ func TestLicenseExpressionTokenizerWhitespaceNewlineTabRemoval(t *testing.T) { func TestLicenseSpdxIdSimple(t *testing.T) { ID := "MIT" if !IsValidSpdxId(ID) { - t.Errorf("IsValidSpdxId(`%s`) == `false`: Expected `true`.", ID) + t.Errorf("IsValidSpdxId('%s') == `false`: Expected `true`.", ID) } } func TestLicenseSpdxIdComplex(t *testing.T) { ID := "AGPL-3.0-or-later" if !IsValidSpdxId(ID) { - t.Errorf("IsValidSpdxId(`%s`) == `false`: Expected `true`.", ID) + t.Errorf("IsValidSpdxId('%s') == `false`: Expected `true`.", ID) } } func TestLicenseSpdxIdFailEmptyString(t *testing.T) { ID := "" if IsValidSpdxId(ID) { - t.Errorf("IsValidSpdxId(`%s`) == `true`: Expected `false`.", ID) + t.Errorf("IsValidSpdxId('%s') == `true`: Expected `false`.", ID) } } func TestLicenseSpdxIdFailBadCharacter1(t *testing.T) { ID := "?" if IsValidSpdxId(ID) { - t.Errorf("IsValidSpdxId(`%s`) == `true`: Expected `false`.", ID) + t.Errorf("IsValidSpdxId('%s') == `true`: Expected `false`.", ID) } } func TestLicenseSpdxIdFailBadCharacter2(t *testing.T) { ID := "MIT+Apache-2.0" if IsValidSpdxId(ID) { - t.Errorf("IsValidSpdxId(`%s`) == `true`: Expected `false`.", ID) + t.Errorf("IsValidSpdxId('%s') == `true`: Expected `false`.", ID) } } func TestLicenseSpdxIdFailWhiteSpace(t *testing.T) { ID := "Apache 2.0" if IsValidSpdxId(ID) { - t.Errorf("IsValidSpdxId(`%s`) == `true`: Expected `false`.", ID) + t.Errorf("IsValidSpdxId('%s') == `true`: Expected `false`.", ID) } } diff --git a/schema/license_policy_config.go b/schema/license_policy_config.go index ccd52bb3..02f2da7d 100644 --- a/schema/license_policy_config.go +++ b/schema/license_policy_config.go @@ -114,8 +114,8 @@ func (config *LicensePolicyConfig) GetLicenseIdMap() (hashmap *slicemultimap.Mul } func (config *LicensePolicyConfig) GetFilteredFamilyNameMap(whereFilters []common.WhereFilter) (hashmap *slicemultimap.MultiMap, err error) { - // NOTE: This call is necessary as this will cause all `licensePolicyConfig.PolicyList` - // entries to have alternative field names to be mapped (e.g., `usagePolicy` -> `usage-policy`) + // NOTE: This call is necessary as this will cause all 'licensePolicyConfig.PolicyList' + // entries to have alternative field names to be mapped (e.g., 'usagePolicy' -> 'usage-policy') config.filteredFamilyNameMap, err = config.GetFamilyNameMap() if err != nil { @@ -161,21 +161,21 @@ func (config *LicensePolicyConfig) innerLoadLicensePolicies(policyFile string, d config.policyConfigFile, err = utils.FindVerifyConfigFileAbsPath(getLogger(), policyFile) if err != nil { - return fmt.Errorf("unable to find license policy file: `%s`", policyFile) + return fmt.Errorf("unable to find license policy file: '%s'", policyFile) } // attempt to read in contents of the policy config. - getLogger().Infof("Loading license policy file: `%s`...", config.policyConfigFile) + getLogger().Infof("Loading license policy file: '%s'...", config.policyConfigFile) buffer, err = os.ReadFile(config.policyConfigFile) if err != nil { - return fmt.Errorf("unable to `ReadFile`: `%s`", config.policyConfigFile) + return fmt.Errorf("unable to 'ReadFile': '%s'", config.policyConfigFile) } } else { // Attempt to load the default config file from embedded file resources - getLogger().Infof("Loading (embedded) default license policy file: `%s`...", defaultPolicyFile) + getLogger().Infof("Loading (embedded) default license policy file: '%s'...", defaultPolicyFile) buffer, err = resources.LoadConfigFile(defaultPolicyFile) if err != nil { - return fmt.Errorf("unable to read schema config file: `%s` from embedded resources: `%s`", + return fmt.Errorf("unable to read schema config file: '%s' from embedded resources: '%s'", defaultPolicyFile, resources.RESOURCES_CONFIG_DIR) } } @@ -183,7 +183,7 @@ func (config *LicensePolicyConfig) innerLoadLicensePolicies(policyFile string, d // NOTE: this cleverly unmarshals into the current config instance this function is associated with errUnmarshal := json.Unmarshal(buffer, config) if errUnmarshal != nil { - err = fmt.Errorf("cannot `Unmarshal`: `%s`", config.policyConfigFile) + err = fmt.Errorf("cannot 'Unmarshal': '%s'", config.policyConfigFile) return } @@ -214,11 +214,11 @@ func (config *LicensePolicyConfig) innerHashLicensePolicies() (err error) { // Map old JSON key names to new key names (as they appear as titles in report columns) // Update the original entries in the []PolicyList stored in the global LicenseComplianceConfig - getLogger().Debugf("Mapping: `Id`: `%s` to `spdx-id`: `%s`\n", policy.Id, policy.AltSPDXId) + getLogger().Debugf("Mapping: 'Id': '%s' to 'spdx-id': '%s'\n", policy.Id, policy.AltSPDXId) config.PolicyList[i].AltSPDXId = policy.Id - getLogger().Debugf("Mapping: `UsagePolicy`: `%s` to `usage-policy`: `%s`\n", policy.Id, policy.AltSPDXId) + getLogger().Debugf("Mapping: 'UsagePolicy': '%s' to 'usage-policy': '%s'\n", policy.Id, policy.AltSPDXId) config.PolicyList[i].AltUsagePolicy = policy.UsagePolicy - getLogger().Debugf("Mapping: `AnnotationRefs`: `%s` to `annotations`: `%s`\n", policy.Id, policy.AltSPDXId) + getLogger().Debugf("Mapping: 'AnnotationRefs': '%s' to 'annotations': '%s'\n", policy.Id, policy.AltSPDXId) config.PolicyList[i].AltAnnotationRefs = strings.Join(policy.AnnotationRefs, ",") // Actually hash the policy @@ -243,14 +243,14 @@ func (config *LicensePolicyConfig) hashPolicy(policy LicensePolicy) (err error) // ONLY hash valid policy records. if !IsValidPolicyEntry(policy) { // Do not add it to any hash table - getLogger().Tracef("WARNING: invalid policy entry (id: `%s`, name: `%s`). Skipping...", policy.Id, policy.Name) + getLogger().Tracef("WARNING: invalid policy entry (id: '%s', name: '%s'). Skipping...", policy.Id, policy.Name) return } // Only add to "id" hashmap if "Id" value is valid // NOTE: do NOT hash entries with "" (empty) Id values; however, they may represent a "family" entry if policy.Id != "" { - getLogger().Debugf("ID Hashmap: Adding policy Id=`%s`, Name=`%s`, Family=`%s`", policy.Id, policy.Name, policy.Family) + getLogger().Debugf("ID Hashmap: Adding policy Id='%s', Name='%s', Family='%s'", policy.Id, policy.Name, policy.Family) config.licenseIdMap.Put(policy.Id, policy) } else { getLogger().Debugf("WARNING: Skipping policy with no SPDX ID (empty)...") @@ -263,11 +263,11 @@ func (config *LicensePolicyConfig) hashPolicy(policy LicensePolicy) (err error) // If a hashmap entry exists, see if current policy matches those // already added for that key if match { - getLogger().Debugf("Family Hashmap: Entries exist for policy Id=`%s`, Name=`%s`, Family=`%s`", policy.Id, policy.Name, policy.Family) + getLogger().Debugf("Family Hashmap: Entries exist for policy Id='%s', Name='%s', Family='%s'", policy.Id, policy.Name, policy.Family) consistent := VerifyPoliciesMatch(policy, values) if !consistent { - err = getLogger().Errorf("Multiple (possibly conflicting) policies declared for ID `%s`,family: `%s`, policy: `%s`", + err = getLogger().Errorf("Multiple (possibly conflicting) policies declared for ID '%s',family: '%s', policy: '%s'", policy.Id, policy.Family, policy.UsagePolicy) @@ -276,11 +276,11 @@ func (config *LicensePolicyConfig) hashPolicy(policy LicensePolicy) (err error) } // NOTE: validation of policy struct (including "family" value) is done above - getLogger().Debugf("Family Hashmap: Adding policy Id=`%s`, Name=`%s`, Family=`%s`", policy.Id, policy.Name, policy.Family) + getLogger().Debugf("Family Hashmap: Adding policy Id='%s', Name='%s', Family='%s'", policy.Id, policy.Name, policy.Family) // Do NOT hash entries with and empty "Family" (name) value if policy.Family != "" { - getLogger().Debugf("ID Hashmap: Adding policy Id=`%s`, Name=`%s`, Family=`%s`", policy.Id, policy.Name, policy.Family) + getLogger().Debugf("ID Hashmap: Adding policy Id='%s', Name='%s', Family='%s'", policy.Id, policy.Name, policy.Family) config.licenseFamilyNameMap.Put(policy.Family, policy) } else { err = getLogger().Errorf("invalid policy: Family: \"\" (empty)") @@ -407,7 +407,7 @@ func (config *LicensePolicyConfig) FindPolicyBySpdxId(id string) (policyValue st // Note: this will cause all policy hashmaps to be initialized (created), if it has not bee licensePolicyIdMap, err := config.GetLicenseIdMap() if err != nil { - err = getLogger().Errorf("license policy map error: `%w`", err) + err = getLogger().Errorf("license policy map error: '%w'", err) return } @@ -416,7 +416,7 @@ func (config *LicensePolicyConfig) FindPolicyBySpdxId(id string) (policyValue st // There MUST be ONLY one policy per (discrete) license ID if len(arrPolicies) > 1 { - err = getLogger().Errorf("Multiple (possibly conflicting) policies declared for SPDX ID=`%s`", id) + err = getLogger().Errorf("Multiple (possibly conflicting) policies declared for SPDX ID='%s'", id) return } @@ -425,7 +425,7 @@ func (config *LicensePolicyConfig) FindPolicyBySpdxId(id string) (policyValue st matchedPolicy = arrPolicies[0].(LicensePolicy) policyValue = matchedPolicy.UsagePolicy } else { - getLogger().Tracef("No policy match found for SPDX ID=`%s` ", id) + getLogger().Tracef("No policy match found for SPDX ID='%s' ", id) policyValue = POLICY_UNDEFINED } @@ -446,7 +446,7 @@ func (config *LicensePolicyConfig) FindPolicyByFamilyName(name string) (policyVa // within the "name" field. This prevents us from assigning policy // return if hasLogicalConjunctionOrPreposition(name) { - getLogger().Warningf("policy name contains logical conjunctions or preposition: `%s`", name) + getLogger().Warningf("policy name contains logical conjunctions or preposition: '%s'", name) policyValue = POLICY_UNDEFINED return } @@ -464,7 +464,7 @@ func (config *LicensePolicyConfig) FindPolicyByFamilyName(name string) (policyVa arrPolicies, _ = familyNameMap.Get(key) if len(arrPolicies) == 0 { - err = getLogger().Errorf("No policy match found in hashmap for family name key: `%s`", key) + err = getLogger().Errorf("No policy match found in hashmap for family name key: '%s'", key) return } @@ -478,12 +478,12 @@ func (config *LicensePolicyConfig) FindPolicyByFamilyName(name string) (policyVa if len(arrPolicies) > 1 { conflict := policyConflictExists(arrPolicies) if conflict { - getLogger().Tracef("Usage policy conflict for license family name=`%s` ", name) + getLogger().Tracef("Usage policy conflict for license family name='%s' ", name) policyValue = POLICY_CONFLICT } } } else { - getLogger().Tracef("No policy match found for license family name=`%s` ", name) + getLogger().Tracef("No policy match found for license family name='%s' ", name) policyValue = POLICY_UNDEFINED } @@ -535,32 +535,32 @@ func IsValidUsagePolicy(usagePolicy string) bool { func IsValidPolicyEntry(policy LicensePolicy) bool { if policy.Id != "" && !IsValidSpdxId(policy.Id) { - getLogger().Warningf("invalid SPDX ID: `%s` (Name=`%s`). Skipping...", policy.Id, policy.Name) + getLogger().Warningf("invalid SPDX ID: '%s' (Name='%s'). Skipping...", policy.Id, policy.Name) return false } if strings.TrimSpace(policy.Name) == "" { - getLogger().Warningf("invalid Name: `%s` (Id=`%s`).", policy.Name, policy.Id) + getLogger().Warningf("invalid Name: '%s' (Id='%s').", policy.Name, policy.Id) } if !IsValidUsagePolicy(policy.UsagePolicy) { - getLogger().Warningf("invalid Usage Policy: `%s` (Id=`%s`, Name=`%s`). Skipping...", policy.UsagePolicy, policy.Id, policy.Name) + getLogger().Warningf("invalid Usage Policy: '%s' (Id='%s', Name='%s'). Skipping...", policy.UsagePolicy, policy.Id, policy.Name) return false } if !IsValidFamilyKey(policy.Family) { - getLogger().Warningf("invalid Family: `%s` (Id=`%s`, Name=`%s`). Skipping...", policy.Family, policy.Id, policy.Name) + getLogger().Warningf("invalid Family: '%s' (Id='%s', Name='%s'). Skipping...", policy.Family, policy.Id, policy.Name) return false } if policy.Id == "" { if len(policy.Children) < 1 { - getLogger().Debugf("Family (policy): `%s`. Has no children (SPDX IDs) listed.", policy.Family) + getLogger().Debugf("Family (policy): '%s'. Has no children (SPDX IDs) listed.", policy.Family) } // Test to make sure "family" entries (i.e. policy.Id == "") have valid "children" (SPDX IDs) for _, childId := range policy.Children { if !IsValidSpdxId(childId) { - getLogger().Warningf("invalid Id: `%s` for Family: `%s`. Skipping...", childId, policy.Family) + getLogger().Warningf("invalid Id: '%s' for Family: '%s'. Skipping...", childId, policy.Family) } } } diff --git a/schema/schema_custom_validation.go b/schema/schema_custom_validation.go index 733ee908..75b51d09 100644 --- a/schema/schema_custom_validation.go +++ b/schema/schema_custom_validation.go @@ -40,21 +40,21 @@ func LoadCustomValidationConfig(filename string) (err error) { cfgFilename, err := utils.FindVerifyConfigFileAbsPath(getLogger(), filename) if err != nil { - return fmt.Errorf("unable to find custom validation config file: `%s`", filename) + return fmt.Errorf("unable to find custom validation config file: '%s'", filename) } // Note we actively supply informative error messages to help user // understand exactly how the load failed - getLogger().Infof("Loading custom validation config file: `%s`...", cfgFilename) + getLogger().Infof("Loading custom validation config file: '%s'...", cfgFilename) // #nosec G304 (suppress warning) buffer, err := os.ReadFile(cfgFilename) if err != nil { - return fmt.Errorf("unable to `ReadFile`: `%s`", cfgFilename) + return fmt.Errorf("unable to `ReadFile`: '%s'", cfgFilename) } err = json.Unmarshal(buffer, &CustomValidationChecks) if err != nil { - return fmt.Errorf("cannot `Unmarshal`: `%s`", cfgFilename) + return fmt.Errorf("cannot `Unmarshal`: '%s'", cfgFilename) } return diff --git a/schema/schema_errors.go b/schema/schema_errors.go index 3bd80fe2..b5ed0172 100644 --- a/schema/schema_errors.go +++ b/schema/schema_errors.go @@ -77,9 +77,9 @@ func NewUnknownFormatError(f string) *UnsupportedFormatError { } func (err UnsupportedFormatError) Error() string { - baseMessage := fmt.Sprintf("%s: %s (`%s`)", err.Type, err.Message, err.InputFile) + baseMessage := fmt.Sprintf("%s: %s ('%s')", err.Type, err.Message, err.InputFile) if err.Format != "" { - return fmt.Sprintf("%s: format: `%s`, command: `%s`, flags: `%s`", + return fmt.Sprintf("%s: format: '%s', command: '%s', flags: '%s'", baseMessage, err.Format, err.Command, @@ -89,7 +89,7 @@ func (err UnsupportedFormatError) Error() string { } func (err UnsupportedSchemaError) Error() string { - return fmt.Sprintf("%s: %s: Schema Format: `%s`, Version: `%s`, Variant: `%s` ", + return fmt.Sprintf("%s: %s: Schema Format: '%s', Version: '%s', Variant: '%s' ", err.Type, err.Message, err.Format, diff --git a/schema/schema_formats.go b/schema/schema_formats.go index 819faa5e..2a71369f 100644 --- a/schema/schema_formats.go +++ b/schema/schema_formats.go @@ -64,7 +64,7 @@ func getLogger() *log.MiniLogger { // ONLY if needed to debug init() methods in the "cmd" package ProjectLogger = log.NewLogger(log.ERROR) - // Attempt to read in `--args` values such as `--trace` + // Attempt to read in '--args' values such as '--trace' // Note: if they exist, quiet mode will be overridden // Default to ERROR level and, turn on "Quiet mode" for tests // This simplifies the test output to simply RUN/PASS|FAIL messages. @@ -140,21 +140,21 @@ func (config *BOMFormatAndSchemaConfig) InnerLoadSchemaConfigFile(filename strin absFilename, err = utils.FindVerifyConfigFileAbsPath(getLogger(), filename) if err != nil { - return fmt.Errorf("unable to find schema config file: `%s`", filename) + return fmt.Errorf("unable to find schema config file: '%s'", filename) } // Attempt to load user-provided config file - getLogger().Infof("Loading schema config file: `%s`...", absFilename) + getLogger().Infof("Loading schema config file: '%s'...", absFilename) buffer, err = os.ReadFile(absFilename) if err != nil { - return fmt.Errorf("unable to read schema config file: `%s`", absFilename) + return fmt.Errorf("unable to read schema config file: '%s'", absFilename) } } else { // Attempt to load the default config file from embedded file resources - getLogger().Infof("Loading (embedded) default schema config file: `%s`...", defaultFilename) + getLogger().Infof("Loading (embedded) default schema config file: '%s'...", defaultFilename) buffer, err = resources.LoadConfigFile(defaultFilename) if err != nil { - return fmt.Errorf("unable to read schema config file: `%s` from embedded resources: `%s`", + return fmt.Errorf("unable to read schema config file: '%s' from embedded resources: '%s'", defaultFilename, resources.RESOURCES_CONFIG_DIR) } } @@ -162,7 +162,7 @@ func (config *BOMFormatAndSchemaConfig) InnerLoadSchemaConfigFile(filename strin //err = json.Unmarshal(buffer, &SupportedFormatConfig) err = json.Unmarshal(buffer, config) if err != nil { - return fmt.Errorf("cannot `Unmarshal`: `%s`", absFilename) + return fmt.Errorf("cannot 'Unmarshal': '%s'", absFilename) } return @@ -210,17 +210,17 @@ func (bom *BOM) findSchemaVersionWithVariant(format FormatSchema, version string // Iterate over known schema versions to see if SBOM's version is supported for _, schema := range format.Schemas { // Compare requested version to current schema version AND make sure variant matches - getLogger().Tracef("Comparing SBOM version: `%s` to schema.version: `%s`...", version, schema.Version) + getLogger().Tracef("Comparing SBOM version: '%s' to schema.version: '%s'...", version, schema.Version) if version == schema.Version { // Make note that we did find a viable matching schema and version - getLogger().Tracef("Match found for SBOM version: `%s`", version) + getLogger().Tracef("Match found for SBOM version: '%s'", version) versionExists = true // If a variant is also requested, see if we can find one for that criteria // Note: the default value for "variant" is an empty string if utils.GlobalFlags.ValidateFlags.SchemaVariant == schema.Variant { - getLogger().Tracef("Match found for requested schema variant: `%s`", + getLogger().Tracef("Match found for requested schema variant: '%s'", FormatSchemaVariant(utils.GlobalFlags.ValidateFlags.SchemaVariant)) bom.SchemaInfo = schema return diff --git a/utils/config.go b/utils/config.go index d890bb71..1259038f 100644 --- a/utils/config.go +++ b/utils/config.go @@ -33,7 +33,7 @@ func FindVerifyConfigFileAbsPath(logger *log.MiniLogger, filename string) (absFi logger.Tracef("filename: %s", filename) if len(filename) == 0 { - err = fmt.Errorf("invalid config filename: `%s`", filename) + err = fmt.Errorf("invalid config filename: '%s'", filename) return } @@ -41,7 +41,7 @@ func FindVerifyConfigFileAbsPath(logger *log.MiniLogger, filename string) (absFi // that may have been provided via the command line argument if _, err = os.Stat(filename); err == nil { absFilename = filename - logger.Tracef("found config file `%s` at location provided.", absFilename) + logger.Tracef("found config file '%s' at location provided.", absFilename) return } @@ -50,24 +50,24 @@ func FindVerifyConfigFileAbsPath(logger *log.MiniLogger, filename string) (absFi if !filepath.IsAbs(filename) { // first, attempt to find file relative to the executable tmpFilename := filepath.Join(GlobalFlags.ExecDir, filename) - logger.Tracef("Checking for config relative to executable: `%s`...", tmpFilename) + logger.Tracef("Checking for config relative to executable: '%s'...", tmpFilename) if _, err = os.Stat(tmpFilename); err == nil { absFilename = tmpFilename - logger.Tracef("found config file relative to executable: `%s`", absFilename) + logger.Tracef("found config file relative to executable: '%s'", absFilename) return } // Last, attempt to find the config file in the current working directory // Note: this is sometimes needed in IDE/test environments tmpFilename = filepath.Join(GlobalFlags.WorkingDir, filename) - logger.Tracef("Checking for config relative to working directory: `%s`...", tmpFilename) + logger.Tracef("Checking for config relative to working directory: '%s'...", tmpFilename) if _, err = os.Stat(tmpFilename); err == nil { absFilename = tmpFilename - logger.Tracef("found config file relative to working directory: `%s`", absFilename) + logger.Tracef("found config file relative to working directory: '%s'", absFilename) return } } - logger.Tracef("returning config absolute filename: `%s`", absFilename) + logger.Tracef("returning config absolute filename: '%s'", absFilename) return } diff --git a/utils/regex.go b/utils/regex.go index 9c1a9bae..b5613ae9 100644 --- a/utils/regex.go +++ b/utils/regex.go @@ -27,7 +27,7 @@ func CompileRegex(test string) (expression *regexp.Regexp, err error) { if test != "" { expression, err = regexp.Compile(test) if err != nil { - err = fmt.Errorf("invalid regular expression: `%s`", test) + err = fmt.Errorf("invalid regular expression: '%s'", test) } } return diff --git a/utils/timestamps.go b/utils/timestamps.go index 1ab719be..c3e5ca42 100644 --- a/utils/timestamps.go +++ b/utils/timestamps.go @@ -40,7 +40,7 @@ func TruncateTimeStampISO8601Date(fullTimestamp string) (date string, err error) // return the (now validated) value passed in return } else { - err = fmt.Errorf("invalid ISO 8601 timestamp: `%s`", fullTimestamp) + err = fmt.Errorf("invalid ISO 8601 timestamp: '%s'", fullTimestamp) // return what we were given return } @@ -50,7 +50,7 @@ func TruncateTimeStampISO8601Date(fullTimestamp string) (date string, err error) iSep := strings.IndexByte(fullTimestamp, ISO8601_TIME_SEPARATOR) if iSep == -1 { - err = fmt.Errorf("invalid ISO 8601 timestamp: `%s`", fullTimestamp) + err = fmt.Errorf("invalid ISO 8601 timestamp: '%s'", fullTimestamp) // return what we were given return } @@ -59,7 +59,7 @@ func TruncateTimeStampISO8601Date(fullTimestamp string) (date string, err error) date = fullTimestamp[:iSep] if !ValidateISO8601TimestampISO8601DateTime(date, REGEX_ISO_8601_DATE) { - err = fmt.Errorf("invalid ISO 8601 timestamp: `%s`", fullTimestamp) + err = fmt.Errorf("invalid ISO 8601 timestamp: '%s'", fullTimestamp) // return what we were given date = fullTimestamp return