diff options
Diffstat (limited to 'tools/nogo/config.go')
-rw-r--r-- | tools/nogo/config.go | 261 |
1 files changed, 0 insertions, 261 deletions
diff --git a/tools/nogo/config.go b/tools/nogo/config.go deleted file mode 100644 index 2fea5b3e1..000000000 --- a/tools/nogo/config.go +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2019 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package nogo - -import ( - "fmt" - "regexp" -) - -// GroupName is a named group. -type GroupName string - -// AnalyzerName is a named analyzer. -type AnalyzerName string - -// Group represents a named collection of files. -type Group struct { - // Name is the short name for the group. - Name GroupName `yaml:"name"` - - // Regex matches all full paths in the group. - Regex string `yaml:"regex"` - regex *regexp.Regexp `yaml:"-"` - - // Default determines the default group behavior. - // - // If Default is true, all Analyzers are enabled for this - // group. Otherwise, Analyzers must be individually enabled - // by specifying a (possible empty) ItemConfig for the group - // in the AnalyzerConfig. - Default bool `yaml:"default"` -} - -func (g *Group) compile() error { - r, err := regexp.Compile(g.Regex) - if err != nil { - return err - } - g.regex = r - return nil -} - -// ItemConfig is an (Analyzer,Group) configuration. -type ItemConfig struct { - // Exclude are analyzer exclusions. - // - // Exclude is a list of regular expressions. If the corresponding - // Analyzer emits a Finding for which Finding.Position.String() - // matches a regular expression in Exclude, the finding will not - // be reported. - Exclude []string `yaml:"exclude,omitempty"` - exclude []*regexp.Regexp `yaml:"-"` - - // Suppress are analyzer suppressions. - // - // Suppress is a list of regular expressions. If the corresponding - // Analyzer emits a Finding for which Finding.Message matches a regular - // expression in Suppress, the finding will not be reported. - Suppress []string `yaml:"suppress,omitempty"` - suppress []*regexp.Regexp `yaml:"-"` -} - -func compileRegexps(ss []string, rs *[]*regexp.Regexp) error { - *rs = make([]*regexp.Regexp, 0, len(ss)) - for _, s := range ss { - r, err := regexp.Compile(s) - if err != nil { - return err - } - *rs = append(*rs, r) - } - return nil -} - -func (i *ItemConfig) compile() error { - if i == nil { - // This may be nil if nothing is included in the - // item configuration. That's fine, there's nothing - // to compile and nothing to exclude & suppress. - return nil - } - if err := compileRegexps(i.Exclude, &i.exclude); err != nil { - return fmt.Errorf("in exclude: %w", err) - } - if err := compileRegexps(i.Suppress, &i.suppress); err != nil { - return fmt.Errorf("in suppress: %w", err) - } - return nil -} - -func (i *ItemConfig) merge(other *ItemConfig) { - i.Exclude = append(i.Exclude, other.Exclude...) - i.Suppress = append(i.Suppress, other.Suppress...) -} - -func (i *ItemConfig) shouldReport(fullPos, msg string) bool { - if i == nil { - // See above. - return true - } - for _, r := range i.exclude { - if r.MatchString(fullPos) { - return false - } - } - for _, r := range i.suppress { - if r.MatchString(msg) { - return false - } - } - return true -} - -// AnalyzerConfig is the configuration for a single analyzers. -// -// This map is keyed by individual Group names, to allow for different -// configurations depending on what Group the file belongs to. -type AnalyzerConfig map[GroupName]*ItemConfig - -func (a AnalyzerConfig) compile() error { - for name, gc := range a { - if err := gc.compile(); err != nil { - return fmt.Errorf("invalid group %q: %v", name, err) - } - } - return nil -} - -func (a AnalyzerConfig) merge(other AnalyzerConfig) { - // Merge all the groups. - for name, gc := range other { - old, ok := a[name] - if !ok || old == nil { - a[name] = gc // Not configured in a. - continue - } - old.merge(gc) - } -} - -func (a AnalyzerConfig) shouldReport(groupConfig *Group, fullPos, msg string) bool { - gc, ok := a[groupConfig.Name] - if !ok { - return groupConfig.Default - } - - // Note that if a section appears for a particular group - // for a particular analyzer, then it will now be enabled, - // and the group default no longer applies. - return gc.shouldReport(fullPos, msg) -} - -// Config is a nogo configuration. -type Config struct { - // Prefixes defines a set of regular expressions that - // are standard "prefixes", so that files can be grouped - // and specific rules applied to individual groups. - Groups []Group `yaml:"groups"` - - // Global is the global analyzer config. - Global AnalyzerConfig `yaml:"global"` - - // Analyzers are individual analyzer configurations. The - // key for each analyzer is the name of the analyzer. The - // value is either a boolean (enable/disable), or a map to - // the groups above. - Analyzers map[AnalyzerName]AnalyzerConfig `yaml:"analyzers"` -} - -// Merge merges two configurations. -func (c *Config) Merge(other *Config) { - // Merge all groups. - for _, g := range other.Groups { - // Is there a matching group? If yes, we just delete - // it. This will preserve the order provided in the - // overriding file, even if it differs. - for i := 0; i < len(c.Groups); i++ { - if g.Name == c.Groups[i].Name { - copy(c.Groups[i:], c.Groups[i+1:]) - c.Groups = c.Groups[:len(c.Groups)-1] - break - } - } - c.Groups = append(c.Groups, g) - } - - // Merge global configurations. - c.Global.merge(other.Global) - - // Merge all analyzer configurations. - for name, ac := range other.Analyzers { - old, ok := c.Analyzers[name] - if !ok { - c.Analyzers[name] = ac // No analyzer in original config. - continue - } - old.merge(ac) - } -} - -// Compile compiles a configuration to make it useable. -func (c *Config) Compile() error { - for i := 0; i < len(c.Groups); i++ { - if err := c.Groups[i].compile(); err != nil { - return fmt.Errorf("invalid group %q: %w", c.Groups[i].Name, err) - } - } - if err := c.Global.compile(); err != nil { - return fmt.Errorf("invalid global: %w", err) - } - for name, ac := range c.Analyzers { - if err := ac.compile(); err != nil { - return fmt.Errorf("invalid analyzer %q: %w", name, err) - } - } - return nil -} - -// ShouldReport returns true iff the finding should match the Config. -func (c *Config) ShouldReport(finding Finding) bool { - fullPos := finding.Position.String() - - // Find the matching group. - var groupConfig *Group - for i := 0; i < len(c.Groups); i++ { - if c.Groups[i].regex.MatchString(fullPos) { - groupConfig = &c.Groups[i] - break - } - } - - // If there is no group matching this path, then - // we default to accept the finding. - if groupConfig == nil { - return true - } - - // Suppress via global rule? - if !c.Global.shouldReport(groupConfig, fullPos, finding.Message) { - return false - } - - // Try the analyzer config. - ac, ok := c.Analyzers[finding.Category] - if !ok { - return groupConfig.Default - } - return ac.shouldReport(groupConfig, fullPos, finding.Message) -} |