@@ -3,19 +3,21 @@ package domain
33import (
44 "errors"
55 "fmt"
6- "github.com/salab/iccheck/pkg/utils/ds"
7- "github.com/salab/iccheck/pkg/utils/files"
8- "gopkg.in/yaml.v3"
96 "os"
107 "path/filepath"
118 "regexp"
129 "sort"
1310 "strings"
11+
12+ "github.com/salab/iccheck/pkg/utils/ds"
13+ "github.com/salab/iccheck/pkg/utils/files"
14+ "github.com/samber/lo"
15+ "gopkg.in/yaml.v3"
1416)
1517
1618// defaultIgnoreConfigs lists rules (that are pretty much safe to assume) for some languages.
1719// To contributors: Feel free to add more to this default config.
18- var defaultIgnoreConfigs = IgnoreConfigs {
20+ var defaultIgnoreConfigs = [] * IgnoreConfig {
1921 {
2022 Files : []string {"\\ .go$" },
2123 Patterns : []string {
@@ -39,10 +41,10 @@ var defaultIgnoreConfigs = IgnoreConfigs{
3941 },
4042}
4143
42- func ReadIgnoreRules (repoDir string , cliOptions [] string , disableDefault bool ) (IgnoreRules , error ) {
43- allConfigs := make ( IgnoreConfigs , 0 )
44+ func ReadMatcherRules (repoDir string , disableDefault bool , ignoreCLIOptions , includeCLIOptions [] string ) (* MatcherRules , error ) {
45+ var matchers MatcherConfigs
4446 if ! disableDefault {
45- allConfigs = append (allConfigs , defaultIgnoreConfigs ... )
47+ matchers . ignores = append (matchers . ignores , defaultIgnoreConfigs ... )
4648 }
4749
4850 // Check if ignore file is present in the following locations:
@@ -59,29 +61,28 @@ func ReadIgnoreRules(repoDir string, cliOptions []string, disableDefault bool) (
5961 }
6062 for _ , path := range paths {
6163 if f , err := os .Open (path ); err == nil {
62- var configs IgnoreConfigs
64+ var configs [] * IgnoreConfig
6365 if err = yaml .NewDecoder (f ).Decode (& configs ); err != nil {
6466 return nil , fmt .Errorf ("decoding %s: %w" , path , err )
6567 }
66- allConfigs = append (allConfigs , configs ... )
68+ matchers . ignores = append (matchers . ignores , configs ... )
6769 }
6870 // Ignore os.Open() error - file might not exist
6971 }
7072
7173 // Parse CLI options, if any
72- for _ , cliOption := range cliOptions {
73- config , err := readIgnoreCLIOption (cliOption )
74+ for _ , ignoreCLIOption := range ignoreCLIOptions {
75+ config , err := readIgnoreCLIOption (ignoreCLIOption )
7476 if err != nil {
7577 return nil , err
7678 }
77- allConfigs = append (allConfigs , config )
79+ matchers . ignores = append (matchers . ignores , config )
7880 }
81+ matchers .includes = includeCLIOptions
7982
80- return allConfigs .Compile ()
83+ return matchers .Compile ()
8184}
8285
83- type IgnoreConfigs []* IgnoreConfig
84-
8586type IgnoreConfig struct {
8687 Files []string `yaml:"files"`
8788 Patterns []string `yaml:"patterns"`
@@ -131,11 +132,30 @@ func (i *IgnoreConfig) Compile() (*IgnoreRule, error) {
131132 return & ret , nil
132133}
133134
134- func (i IgnoreConfigs ) Compile () (IgnoreRules , error ) {
135- return ds .MapError (i , (* IgnoreConfig ).Compile )
135+ type MatcherConfigs struct {
136+ includes []string
137+ ignores []* IgnoreConfig
136138}
137139
138- type IgnoreRules []* IgnoreRule
140+ func (m * MatcherConfigs ) Compile () (* MatcherRules , error ) {
141+ ignoreRules , err := ds .MapError (m .ignores , (* IgnoreConfig ).Compile )
142+ if err != nil {
143+ return nil , err
144+ }
145+ includeFiles , err := ds .MapError (m .includes , regexp .Compile )
146+ if err != nil {
147+ return nil , err
148+ }
149+ return & MatcherRules {
150+ includeFiles : includeFiles ,
151+ ignoreRules : ignoreRules ,
152+ }, nil
153+ }
154+
155+ type MatcherRules struct {
156+ includeFiles []* regexp.Regexp
157+ ignoreRules []* IgnoreRule
158+ }
139159
140160type IgnoreRule struct {
141161 files []* regexp.Regexp
@@ -184,10 +204,20 @@ func (i *IgnoreRule) matchContents(contents []byte) (ignoreLines map[int]struct{
184204// If skipEntireFile is true, callers are expected to skip this entire file (ignoreRule is nil).
185205// Otherwise, callers are expected to call IgnoreLineRule.CanSkip() method according to its doc to
186206// check file ignore pattern.
187- func (i IgnoreRules ) Match (path string , contents []byte ) (skipEntireFile bool , ignoreRule * IgnoreLineRule ) {
207+ func (m * MatcherRules ) Match (path string , contents []byte ) (skipEntireFile bool , ignoreRule * IgnoreLineRule ) {
208+ // Check if we have --include option specified, if so, only consider the matching files
209+ if len (m .includeFiles ) > 0 {
210+ match := lo .SomeBy (m .includeFiles , func (r * regexp.Regexp ) bool {
211+ return r .MatchString (path )
212+ })
213+ if ! match {
214+ return true , nil
215+ }
216+ }
217+
188218 // Check if any patterns match the whole file first
189219 instances := make ([]* IgnoreRule , 0 )
190- for _ , instance := range i {
220+ for _ , instance := range m . ignoreRules {
191221 matchFile := instance .matchFile (path )
192222 if ! matchFile {
193223 continue
0 commit comments