aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDolceTriade <hmodi@aviatrix.com>2022-12-03 08:02:32 -0800
committerGitHub <noreply@github.com>2022-12-03 08:02:32 -0800
commitfe4715a6d959159cb58397aadd7b9fed22fa19c4 (patch)
tree137dcae45f718ed937d4bc3ee3349a057d332492
parent60cd1e428a1cbbe386943fac1cfadd183f4d6898 (diff)
downloadbazelbuild-rules_go-fe4715a6d959159cb58397aadd7b9fed22fa19c4.tar.gz
nogo: Add a _base key to be a default config for all Analyzers. (#3351)
This is useful for situations where you want to exclude/include the same directories for all the analyzers. Specifying a config for a particular analyzer will cause the _base config, if it exists, to be underlayed for that analyzer (ie, if the analyzer doesn't set an option, it will use the options specified by the _base config). You can use it like so: { "_base": { "exclude_files": { "external/": "third_party", "proto/": "generated protobuf" } }, "override": "description": "oops, I actually don't want to exclude any files here...", "exclude_files": {} } }
-rw-r--r--go/nogo.rst9
-rw-r--r--go/tools/builders/nogo_main.go34
-rw-r--r--tests/core/nogo/custom/custom_test.go30
3 files changed, 65 insertions, 8 deletions
diff --git a/go/nogo.rst b/go/nogo.rst
index 212d55ee..222d967b 100644
--- a/go/nogo.rst
+++ b/go/nogo.rst
@@ -204,6 +204,9 @@ contain the following key-value pairs:
| ``flag.Value`` specified by the analyzer. |
+----------------------------+---------------------------------------------------------------------+
+``nogo`` also supports a special key to specify the same config for all analyzers, even if they are
+not explicitly specified called ``_base``. See below for an example of its usage.
+
Example
^^^^^^^
@@ -216,6 +219,12 @@ on a command line driver.
.. code:: json
{
+ "_base": {
+ "description": "Base config that all subsequent analyzers, even unspecified will inherit.",
+ "exclude_files": {
+ "third_party/": "exclude all third_party code for all analyzers"
+ }
+ },
"importunsafe": {
"exclude_files": {
"src/foo\\.go": "manually verified that behavior is working-as-intended",
diff --git a/go/tools/builders/nogo_main.go b/go/tools/builders/nogo_main.go
index e33b4902..5d488ffd 100644
--- a/go/tools/builders/nogo_main.go
+++ b/go/tools/builders/nogo_main.go
@@ -43,6 +43,8 @@ import (
"golang.org/x/tools/go/gcexportdata"
)
+const nogoBaseConfigName = "_base"
+
func init() {
if err := analysis.Validate(analyzers); err != nil {
log.Fatal(err)
@@ -89,7 +91,7 @@ func run(args []string) error {
return fmt.Errorf("errors found by nogo during build-time code analysis:\n%s\n", diagnostics)
}
if *xPath != "" {
- if err := ioutil.WriteFile(abs(*xPath), facts, 0666); err != nil {
+ if err := ioutil.WriteFile(abs(*xPath), facts, 0o666); err != nil {
return fmt.Errorf("error writing facts: %v", err)
}
}
@@ -399,10 +401,26 @@ func checkAnalysisResults(actions []*action, pkg *goPackage) string {
if len(act.diagnostics) == 0 {
continue
}
- config, ok := configs[act.a.Name]
- if !ok {
- // If the analyzer is not explicitly configured, it emits diagnostics for
- // all files.
+ var currentConfig config
+ // Use the base config if it exists.
+ if baseConfig, ok := configs[nogoBaseConfigName]; ok {
+ currentConfig = baseConfig
+ }
+ // Overwrite the config with the desired config. Any unset fields
+ // in the config will default to the base config.
+ if actionConfig, ok := configs[act.a.Name]; ok {
+ if actionConfig.analyzerFlags != nil {
+ currentConfig.analyzerFlags = actionConfig.analyzerFlags
+ }
+ if actionConfig.onlyFiles != nil {
+ currentConfig.onlyFiles = actionConfig.onlyFiles
+ }
+ if actionConfig.excludeFiles != nil {
+ currentConfig.excludeFiles = actionConfig.excludeFiles
+ }
+ }
+
+ if currentConfig.onlyFiles == nil && currentConfig.excludeFiles == nil {
for _, diag := range act.diagnostics {
diagnostics = append(diagnostics, entry{Diagnostic: diag, Analyzer: act.a})
}
@@ -418,10 +436,10 @@ func checkAnalysisResults(actions []*action, pkg *goPackage) string {
filename = p.Filename
}
include := true
- if len(config.onlyFiles) > 0 {
+ if len(currentConfig.onlyFiles) > 0 {
// This analyzer emits diagnostics for only a set of files.
include = false
- for _, pattern := range config.onlyFiles {
+ for _, pattern := range currentConfig.onlyFiles {
if pattern.MatchString(filename) {
include = true
break
@@ -429,7 +447,7 @@ func checkAnalysisResults(actions []*action, pkg *goPackage) string {
}
}
if include {
- for _, pattern := range config.excludeFiles {
+ for _, pattern := range currentConfig.excludeFiles {
if pattern.MatchString(filename) {
include = false
break
diff --git a/tests/core/nogo/custom/custom_test.go b/tests/core/nogo/custom/custom_test.go
index 72f3a373..27624431 100644
--- a/tests/core/nogo/custom/custom_test.go
+++ b/tests/core/nogo/custom/custom_test.go
@@ -297,6 +297,24 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
}
+-- baseconfig.json --
+{
+ "_base": {
+ "exclude_files": {
+ "has_.*\\.go": "Visibility analyzer not specified. Still inherits this special exception."
+ }
+ },
+ "importfmt": {
+ "only_files": {
+ "has_errors\\.go": ""
+ }
+ },
+ "foofuncname": {
+ "description": "no exemptions since we know this check is 100% accurate, so override base config",
+ "exclude_files": {}
+ }
+}
+
-- has_errors.go --
package haserrors
@@ -419,6 +437,18 @@ func Test(t *testing.T) {
`importfmt`,
},
}, {
+ desc: "custom_config_with_base_linedirective",
+ config: "baseconfig.json",
+ target: "//:has_errors_linedirective",
+ wantSuccess: false,
+ includes: []string{
+ `linedirective_foofuncname.go:.*function must not be named Foo \(foofuncname\)`,
+ `linedirective_visibility.go:.*function D is not visible in this package \(visibility\)`,
+ },
+ excludes: []string{
+ `importfmt`,
+ },
+ }, {
desc: "uses_cgo_with_errors",
config: "config.json",
target: "//:uses_cgo_with_errors",