From 0815d00f28dc36e620ca6baf747b70216eaabd73 Mon Sep 17 00:00:00 2001 From: "Pascal S. de Kloe" Date: Fri, 13 Sep 2019 13:42:46 +0200 Subject: [PATCH] File matching options. --- cmd/gocloc/main.go | 14 +++++++++++--- option.go | 2 ++ utils.go | 14 +++++++++++--- utils_test.go | 31 +++++++++++++++++++++++++------ 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/cmd/gocloc/main.go b/cmd/gocloc/main.go index bee6651..ef72d00 100644 --- a/cmd/gocloc/main.go +++ b/cmd/gocloc/main.go @@ -47,6 +47,8 @@ type CmdOptions struct { OutputType string `long:"output-type" default:"default" description:"output type [values: default,cloc-xml,sloccount,json]"` ExcludeExt string `long:"exclude-ext" description:"exclude file name extensions (separated commas)"` IncludeLang string `long:"include-lang" description:"include language name (separated commas)"` + Match string `long:"match" description:"include file name (regex)"` + NotMatch string `long:"not-match" description:"exclude file name (regex)"` MatchDir string `long:"match-d" description:"include dir name (regex)"` NotMatchDir string `long:"not-match-d" description:"exclude dir name (regex)"` Debug bool `long:"debug" description:"dump debug log for developer"` @@ -239,13 +241,19 @@ func main() { } } - // setup option for not match directory - if opts.NotMatchDir != "" { - clocOpts.ReNotMatchDir = regexp.MustCompile(opts.NotMatchDir) + // directory and file matching options + if opts.Match != "" { + clocOpts.ReMatch = regexp.MustCompile(opts.Match) + } + if opts.NotMatch != "" { + clocOpts.ReNotMatch = regexp.MustCompile(opts.NotMatch) } if opts.MatchDir != "" { clocOpts.ReMatchDir = regexp.MustCompile(opts.MatchDir) } + if opts.NotMatchDir != "" { + clocOpts.ReNotMatchDir = regexp.MustCompile(opts.NotMatchDir) + } // setup option for include languages for _, lang := range strings.Split(opts.IncludeLang, ",") { diff --git a/option.go b/option.go index 619a033..a46ea7a 100644 --- a/option.go +++ b/option.go @@ -8,6 +8,8 @@ type ClocOptions struct { SkipDuplicated bool ExcludeExts map[string]struct{} IncludeLangs map[string]struct{} + ReNotMatch *regexp.Regexp + ReMatch *regexp.Regexp ReNotMatchDir *regexp.Regexp ReMatchDir *regexp.Regexp diff --git a/utils.go b/utils.go index b588a4c..bd78f8c 100644 --- a/utils.go +++ b/utils.go @@ -81,7 +81,15 @@ func checkDefaultIgnore(path string, info os.FileInfo, isVCS bool) bool { return false } -func checkOptionMatch(path string, opts *ClocOptions) bool { +func checkOptionMatch(path string, info os.FileInfo, opts *ClocOptions) bool { + // check match directory & file options + if opts.ReNotMatch != nil && opts.ReNotMatch.MatchString(info.Name()) { + return false + } + if opts.ReMatch != nil && !opts.ReMatch.MatchString(info.Name()) { + return false + } + dir := filepath.Dir(path) if opts.ReNotMatchDir != nil && opts.ReNotMatchDir.MatchString(dir) { return false @@ -109,8 +117,8 @@ func getAllFiles(paths []string, languages *DefinedLanguages, opts *ClocOptions) return nil } - // check not-match directory - if match := checkOptionMatch(path, opts); !match { + // check match & not-match directory + if match := checkOptionMatch(path, info, opts); !match { return nil } diff --git a/utils_test.go b/utils_test.go index 65e4112..958ec4e 100644 --- a/utils_test.go +++ b/utils_test.go @@ -4,6 +4,7 @@ import ( "os" "regexp" "testing" + "time" "github.com/spf13/afero" ) @@ -51,37 +52,55 @@ func TestCheckDefaultIgnore(t *testing.T) { } } +type MockFileInfo struct { + FileName string + IsDirectory bool +} + +func (mfi MockFileInfo) Name() string { return mfi.FileName } +func (mfi MockFileInfo) Size() int64 { return int64(8) } +func (mfi MockFileInfo) Mode() os.FileMode { return os.ModePerm } +func (mfi MockFileInfo) ModTime() time.Time { return time.Now() } +func (mfi MockFileInfo) IsDir() bool { return mfi.IsDirectory } +func (mfi MockFileInfo) Sys() interface{} { return nil } + func TestCheckOptionMatch(t *testing.T) { opts := &ClocOptions{} - if !checkOptionMatch("/", opts) { + fi := MockFileInfo{FileName: "/", IsDirectory: true} + if !checkOptionMatch("/", fi, opts) { t.Errorf("invalid logic: renotmatchdir is nil") } opts.ReNotMatchDir = regexp.MustCompile("thisisdir-not-match") - if !checkOptionMatch("/thisisdir/one.go", opts) { + fi = MockFileInfo{FileName: "one.go", IsDirectory: false} + if !checkOptionMatch("/thisisdir/one.go", fi, opts) { t.Errorf("invalid logic: renotmatchdir is nil") } opts.ReNotMatchDir = regexp.MustCompile("thisisdir") - if checkOptionMatch("/thisisdir/one.go", opts) { + fi = MockFileInfo{FileName: "one.go", IsDirectory: false} + if checkOptionMatch("/thisisdir/one.go", fi, opts) { t.Errorf("invalid logic: renotmatchdir is ignore") } opts = &ClocOptions{} opts.ReMatchDir = regexp.MustCompile("thisisdir") - if !checkOptionMatch("/thisisdir/one.go", opts) { + fi = MockFileInfo{FileName: "one.go", IsDirectory: false} + if !checkOptionMatch("/thisisdir/one.go", fi, opts) { t.Errorf("invalid logic: renotmatchdir is not ignore") } opts.ReMatchDir = regexp.MustCompile("thisisdir-not-match") - if checkOptionMatch("/thisisdir/one.go", opts) { + fi = MockFileInfo{FileName: "one.go", IsDirectory: false} + if checkOptionMatch("/thisisdir/one.go", fi, opts) { t.Errorf("invalid logic: renotmatchdir is ignore") } opts = &ClocOptions{} opts.ReNotMatchDir = regexp.MustCompile("thisisdir-not-match") opts.ReMatchDir = regexp.MustCompile("thisisdir") - if !checkOptionMatch("/thisisdir/one.go", opts) { + fi = MockFileInfo{FileName: "one.go", IsDirectory: false} + if !checkOptionMatch("/thisisdir/one.go", fi, opts) { t.Errorf("invalid logic: renotmatchdir is not ignore") } }