Repository: editorconfig-checker/editorconfig-checker
Pull request #319 (2023-12-28 16:52:07)

feat: add output format option with 'gcc'
Relating to #145, a new command-line option  was added. The current output format is named 'default', and a new format 'gcc' was added that uses an error format similar
to gcc, namely:  `<file>:<lineNo>:<charNo>: <type/severity>: <message>`

This command-line option mirrors that used by the common linting tool shellcheck: https://www.mankier.com/1/shellcheck

Example output:
```
$ ./bin/ec --format=gcc ~/files/dummy.*
../../files/dummy.bat:0:0: error: Wrong line endings or no final newline
../../files/dummy.bat:0:0: error: Not all lines have the correct end of line character
../../files/dummy.d:2:0: error: Line too long (113 instead of 100)
../../files/dummy.d:3:0: error: Wrong amount of left-padding spaces(want multiple of 2)
```

vnayar: I modified the commit description to have the prefix `feat:`, which I believe is what was causing the build to fail, although I'm not 100% sure.  Please approve execution of the workflow.
vnayar: Another force-push due to the subject line of the commit being rejected with the following error:
```
✖   subject must not be sentence-case, start-case, pascal-case, upper-case [subject-case]
```
I am guessing that capitalizing the letters in the subject will resolve this, but I have no way of checking until the workflow is run.
vnayar: I cannot find any documentation regarding the proper case for commit message titles, but all the other examples that are present use lower case. I am making yet another attempt to satisfy this commit linting tool. Please re-run the workflow, because currently only maintainers can do this.
vnayar: Updated `testfiles/generated-config` to include an empty "format" value.
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/editorconfig-checker/editorconfig-checker/pull/319?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=editorconfig-checker) Report
Attention: `8 lines` in your changes are missing coverage. Please review.
> Comparison is base [(`e40e7ac`)](https://app.codecov.io/gh/editorconfig-checker/editorconfig-checker/commit/e40e7aca8824d568afa2e5a9705c60c2692fcfd4?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=editorconfig-checker) 84.58% compared to head [(`6c57cdb`)](https://app.codecov.io/gh/editorconfig-checker/editorconfig-checker/pull/319?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=editorconfig-checker) 83.74%.

| [Files](https://app.codecov.io/gh/editorconfig-checker/editorconfig-checker/pull/319?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=editorconfig-checker) | Patch % | Lines |
|---|---|---|
| [pkg/error/error.go](https://app.codecov.io/gh/editorconfig-checker/editorconfig-checker/pull/319?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=editorconfig-checker#diff-cGtnL2Vycm9yL2Vycm9yLmdv) | 52.94% | [7 Missing and 1 partial :warning: ](https://app.codecov.io/gh/editorconfig-checker/editorconfig-checker/pull/319?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=editorconfig-checker) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #319      +/-   ##
==========================================
- Coverage   84.58%   83.74%   -0.85%     
==========================================
  Files           8        8              
  Lines         681      695      +14     
==========================================
+ Hits          576      582       +6     
- Misses         81       88       +7     
- Partials       24       25       +1     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/editorconfig-checker/editorconfig-checker/pull/319?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=editorconfig-checker).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=editorconfig-checker).

vnayar: When time permits, please take a look. The option to alter the output format is called "--format" and the first added alternative is "gcc". The output format and commnd-line options are inspired from https://www.shellcheck.net/
vnayar: @mstruebing Could you take a moment to look at this PR to add a `--format` option, with one additional format so far, `--format=gcc`, which outputs line-oriented output similar to `gcc`. The option name and value were borrowed from the common linting tool `shellcheck`.

Patch:
diff --git a/README.md b/README.md
index d62db28..a89d4d3 100644
--- a/README.md
+++ b/README.md
@@ -112,6 +112,8 @@ USAGE:
         show which files would be checked
   -exclude string
         a regex which files should be excluded from checking - needs to be a valid regular expression
+  -format
+        specifies the output format, see "Formats" below for more information
   -h    print the help
   -help
         print the help
@@ -132,6 +134,14 @@ If you run this tool from a repository root it will check all files which are ad
 
 If you run this tool from a normal directory it will check all files which are text files. If the tool isn't able to determine a file type it will be added to be checked too.
 
+### Formats
+
+The following output formats are supported:
+
+- **default**: Plain text, human readable output.
+- **gcc**: GCC compatible output. Useful for editors that support compiling and showing syntax errors.
+           <file>:<line>:<column>: <type>: <message>
+
 ## Configuration
 
 The configuration is done via arguments or an `.ecrc` file.
diff --git a/cmd/editorconfig-checker/main.go b/cmd/editorconfig-checker/main.go
index e9f09cb..efe9365 100644
--- a/cmd/editorconfig-checker/main.go
+++ b/cmd/editorconfig-checker/main.go
@@ -39,6 +39,8 @@ func init() {
 	flag.BoolVar(&c.ShowVersion, "version", false, "print the version number")
 	flag.BoolVar(&c.Help, "help", false, "print the help")
 	flag.BoolVar(&c.Help, "h", false, "print the help")
+	flag.StringVar(&c.Format, "format", "default", "specify the output format: default, gcc")
+	flag.StringVar(&c.Format, "f", "default", "specify the output format: default, gcc")
 	flag.BoolVar(&c.Verbose, "verbose", false, "print debugging information")
 	flag.BoolVar(&c.Verbose, "v", false, "print debugging information")
 	flag.BoolVar(&c.Debug, "debug", false, "print debugging information")
diff --git a/pkg/config/config.go b/pkg/config/config.go
index c8d5997..8a37db5 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -82,6 +82,7 @@ type Config struct {
 	// CONFIG FILE
 	Version             string
 	Verbose             bool
+	Format              string
 	Debug               bool
 	IgnoreDefaults      bool
 	SpacesAftertabs     bool
@@ -168,6 +169,10 @@ func (c *Config) Merge(config Config) {
 		c.Verbose = config.Verbose
 	}
 
+	if config.Format != "" {
+		c.Format = config.Format
+	}
+
 	if config.Debug {
 		c.Debug = config.Debug
 	}
@@ -254,6 +259,7 @@ func (c Config) Save(version string) error {
 	type writtenConfig struct {
 		Version             string
 		Verbose             bool
+		Format              string
 		Debug               bool
 		IgnoreDefaults      bool
 		SpacesAftertabs     bool
diff --git a/pkg/error/error.go b/pkg/error/error.go
index fb26c05..80c0601 100644
--- a/pkg/error/error.go
+++ b/pkg/error/error.go
@@ -42,14 +42,25 @@ func PrintErrors(errors []ValidationErrors, config config.Config) {
 				continue
 			}
 
-			config.Logger.Warning(fmt.Sprintf("%s:", relativeFilePath))
-			for _, singleError := range fileErrors.Errors {
-				if singleError.LineNumber != -1 {
-					config.Logger.Error(fmt.Sprintf("\t%d: %s", singleError.LineNumber, singleError.Message))
-				} else {
-					config.Logger.Error(fmt.Sprintf("\t%s", singleError.Message))
+			if config.Format == "gcc" {
+				// gcc: A format mimicking the error format from GCC.
+				for _, singleError := range fileErrors.Errors {
+					var lineNo = 0
+					if singleError.LineNumber > 0 {
+						lineNo = singleError.LineNumber
+					}
+					config.Logger.Error(fmt.Sprintf("%s:%d:%d: %s: %s", relativeFilePath, lineNo, 0, "error", singleError.Message))
+				}
+			} else {
+				// default: A human readable text format.
+				config.Logger.Warning(fmt.Sprintf("%s:", relativeFilePath))
+				for _, singleError := range fileErrors.Errors {
+					if singleError.LineNumber != -1 {
+						config.Logger.Error(fmt.Sprintf("\t%d: %s", singleError.LineNumber, singleError.Message))
+					} else {
+						config.Logger.Error(fmt.Sprintf("\t%s", singleError.Message))
+					}
 				}
-
 			}
 		}
 	}


Test patch:
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index d8564e1..e3f9783 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -88,6 +88,7 @@ func TestMerge(t *testing.T) {
 		DryRun:              true,
 		Path:                "some-other",
 		Verbose:             true,
+		Format:              "default",
 		Debug:               true,
 		NoColor:             true,
 		IgnoreDefaults:      true,
@@ -175,7 +176,7 @@ func TestGetAsString(t *testing.T) {
 	_ = c.Parse()
 
 	actual := c.GetAsString()
-	expected := "Config: {ShowVersion:false Help:false DryRun:false Path:../../.ecrc Version:2.7.2 Verbose:false Debug:false IgnoreDefaults:false SpacesAftertabs:false NoColor:false Exclude:[testfiles testdata] AllowedContentTypes:[text/ application/octet-stream application/ecmascript application/json application/x-ndjson application/xml +json +xml] PassedFiles:[] Disable:{EndOfLine:false Indentation:false InsertFinalNewline:false TrimTrailingWhitespace:false IndentSize:false MaxLineLength:false} Logger:{Verbosee:false Debugg:false NoColor:false} EditorconfigConfig:0x"
+	expected := "Config: {ShowVersion:false Help:false DryRun:false Path:../../.ecrc Version:2.7.2 Verbose:false Format: Debug:false IgnoreDefaults:false SpacesAftertabs:false NoColor:false Exclude:[testfiles testdata] AllowedContentTypes:[text/ application/octet-stream application/ecmascript application/json application/x-ndjson application/xml +json +xml] PassedFiles:[] Disable:{EndOfLine:false Indentation:false InsertFinalNewline:false TrimTrailingWhitespace:false IndentSize:false MaxLineLength:false} Logger:{Verbosee:false Debugg:false NoColor:false} EditorconfigConfig:0x"
 
 	if !strings.HasPrefix(actual, expected) {
 		t.Errorf("Expected: %v, got: %v ", expected, actual)
diff --git a/pkg/error/error_test.go b/pkg/error/error_test.go
index ebc8909..4549629 100644
--- a/pkg/error/error_test.go
+++ b/pkg/error/error_test.go
@@ -152,6 +152,9 @@ func TestPrintErrors(t *testing.T) {
 	}
 
 	// wannabe test
-	config := config.Config{}
-	PrintErrors(input, config)
+	config1 := config.Config{}
+	PrintErrors(input, config1)
+
+	config2 := config.Config{Format: "gcc"}
+	PrintErrors(input, config2)
 }
diff --git a/testfiles/generated-config.json b/testfiles/generated-config.json
index cb76b37..d0d0d35 100644
--- a/testfiles/generated-config.json
+++ b/testfiles/generated-config.json
@@ -1,6 +1,7 @@
 {
   "Version": "2.7.2",
   "Verbose": false,
+  "Format": "",
   "Debug": false,
   "IgnoreDefaults": false,
   "SpacesAftertabs": false,