diff --git a/modules/file/file.go b/modules/file/file.go index 73ae6052..60c5230d 100644 --- a/modules/file/file.go +++ b/modules/file/file.go @@ -64,16 +64,17 @@ type run struct { // parameters describes the parameters the file module uses as input upon // invocation type parameters struct { - Searches map[string]search `json:"searches,omitempty"` + Searches map[string]Search `json:"searches,omitempty"` } func newParameters() *parameters { var p parameters - p.Searches = make(map[string]search) + p.Searches = make(map[string]Search) return &p } -type search struct { +// Search contains the fields used to execute an individual search +type Search struct { Description string `json:"description,omitempty"` Paths []string `json:"paths"` Contents []string `json:"contents,omitempty"` @@ -141,7 +142,7 @@ type check struct { // pretty much infinity when it comes to file searches const unlimited float64 = 1125899906842624 -func (s *search) makeChecks() (err error) { +func (s *Search) makeChecks() (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("makeChecks() -> %v", e) @@ -287,7 +288,7 @@ func (s *search) makeChecks() (err error) { return } -func (s *search) hasMismatch(filter string) bool { +func (s *Search) hasMismatch(filter string) bool { for _, fi := range s.Options.Mismatch { if fi == filter { return true @@ -379,32 +380,32 @@ func parseMtime(mtime string) (minmtime, maxmtime time.Time, err error) { return } -func (s *search) activate() { +func (s *Search) activate() { s.isactive = true return } -func (s *search) deactivate() { +func (s *Search) deactivate() { s.isactive = false return } -func (s *search) increasedepth() { +func (s *Search) increasedepth() { s.currentdepth++ return } -func (s *search) decreasedepth() { +func (s *Search) decreasedepth() { s.currentdepth-- return } -func (s *search) markcurrent() { +func (s *Search) markcurrent() { s.iscurrent = true return } -func (s *search) unmarkcurrent() { +func (s *Search) unmarkcurrent() { s.iscurrent = false return } @@ -1123,7 +1124,7 @@ func (c check) wantThis(match bool) bool { return false } -func (s search) checkName(file string, fi os.FileInfo) (matchedall bool) { +func (s Search) checkName(file string, fi os.FileInfo) (matchedall bool) { matchedall = true if (s.checkmask & checkName) != 0 { for i, c := range s.checks { @@ -1145,7 +1146,7 @@ func (s search) checkName(file string, fi os.FileInfo) (matchedall bool) { return } -func (s search) checkMode(file string, fi os.FileInfo) (matchedall bool) { +func (s Search) checkMode(file string, fi os.FileInfo) (matchedall bool) { matchedall = true if (s.checkmask & checkMode) != 0 { for i, c := range s.checks { @@ -1168,7 +1169,7 @@ func (s search) checkMode(file string, fi os.FileInfo) (matchedall bool) { return } -func (s search) checkSize(file string, fi os.FileInfo) (matchedall bool) { +func (s Search) checkSize(file string, fi os.FileInfo) (matchedall bool) { matchedall = true if (s.checkmask & checkSize) != 0 { for i, c := range s.checks { @@ -1192,7 +1193,7 @@ func (s search) checkSize(file string, fi os.FileInfo) (matchedall bool) { return } -func (s search) checkMtime(file string, fi os.FileInfo) (matchedall bool) { +func (s Search) checkMtime(file string, fi os.FileInfo) (matchedall bool) { matchedall = true if (s.checkmask & checkMtime) != 0 { for i, c := range s.checks { @@ -1521,17 +1522,22 @@ func getHash(f fileEntry, hashType checkType) (hexhash string, err error) { } // SearchResults is the search result element for an invocation of the file module -type SearchResults map[string]searchresult +type SearchResults map[string]SearchResult -type searchresult []matchedfile +// SearchResult is the results of a single search the file module has executed. It contains +// a list of the files which were matched as a result of the search. +type SearchResult []MatchedFile -type matchedfile struct { - File string `json:"file"` - Search search `json:"search"` - FileInfo fileinfo `json:"fileinfo"` +// MatchedFile describes a single file matched as a result of a search. +type MatchedFile struct { + File string `json:"file"` + Search Search `json:"search"` + FileInfo Info `json:"fileinfo"` } -type fileinfo struct { +// Info describes the metadata associated with a file matched as a result of a +// search. +type Info struct { Size float64 `json:"size"` Mode string `json:"mode"` Mtime string `json:"lastmodified"` @@ -1553,7 +1559,7 @@ func (r *run) buildResults(t0 time.Time) (resStr string, err error) { elements := res.Elements.(SearchResults) var maxerrors int for label, search := range r.Parameters.Searches { - var sr searchresult + var sr SearchResult // first pass on the results: if matchall is set, verify that all // the checks matched on all the files if search.Options.MatchAll { @@ -1599,7 +1605,7 @@ func (r *run) buildResults(t0 time.Time) (resStr string, err error) { } // now that we have a clean list of files that matched all checks, store it for _, matchedFile := range matchedFiles { - var mf matchedfile + var mf MatchedFile mf.File = matchedFile if mf.File != "" { stats.Totalhits++ @@ -1642,7 +1648,7 @@ func (r *run) buildResults(t0 time.Time) (resStr string, err error) { c.matchedfiles = append(c.matchedfiles, "") } for _, file := range c.matchedfiles { - var mf matchedfile + var mf MatchedFile mf.File = file if mf.File != "" { stats.Totalhits++ diff --git a/modules/file/file_test.go b/modules/file/file_test.go index f1d72e47..d1007ac3 100644 --- a/modules/file/file_test.go +++ b/modules/file/file_test.go @@ -40,7 +40,7 @@ func TestNameSearch(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -73,7 +73,7 @@ func TestContentSearch(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -106,7 +106,7 @@ func TestDecompressedContentSearch(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -148,7 +148,7 @@ func TestSize(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -179,7 +179,7 @@ func TestMTime(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -212,7 +212,7 @@ func TestMode(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -246,7 +246,7 @@ func TestHashes(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -287,7 +287,7 @@ func TestDecompressedHash(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -327,7 +327,7 @@ func TestAllHashes(t *testing.T) { for _, tp := range TESTDATA { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + tp.name, @@ -361,7 +361,7 @@ func TestAllHashes(t *testing.T) { func TestMaxDepth(t *testing.T) { var ( r run - s search + s Search ) var expectedfiles = []string{ basedir + "/" + TESTDATA[0].name, @@ -435,7 +435,7 @@ func TestMacroal(t *testing.T) { for _, mt := range MacroalTestCases { t.Log(mt.desc) var r run - var s search + var s Search r.Parameters = *newParameters() s.Paths = append(s.Paths, basedir) s.Names = append(s.Names, mt.name) @@ -462,7 +462,7 @@ func TestMacroal(t *testing.T) { type mismatchtest struct { desc string - search search + search Search expectedfiles []string } @@ -470,7 +470,7 @@ func TestMismatch(t *testing.T) { var MismatchTestCases = []mismatchtest{ mismatchtest{ desc: "want files that don't match name '^testfile0' with maxdepth=1, should find testfile1, 2, 3, 4, 5, 6, 7 & 8", - search: search{ + search: Search{ Paths: []string{basedir}, Names: []string{"^" + TESTDATA[0].name + "$"}, Options: options{ @@ -490,7 +490,7 @@ func TestMismatch(t *testing.T) { }, mismatchtest{ desc: "want files that don't have a size of 190 bytes or larger than 10{k,m,g,t} or smaller than 10 bytes, should find testfile1, 2, 3, 4, 5, 6, 7 & 8", - search: search{ + search: Search{ Paths: []string{basedir}, Sizes: []string{"190", ">10k", ">10m", ">10g", ">10t", "<10"}, Options: options{ @@ -511,7 +511,7 @@ func TestMismatch(t *testing.T) { }, mismatchtest{ desc: "want files that have not been modified in the last hour ago, should find nothing", - search: search{ + search: Search{ Paths: []string{basedir + subdirs, basedir}, Mtimes: []string{"<1h"}, Options: options{ @@ -522,7 +522,7 @@ func TestMismatch(t *testing.T) { }, mismatchtest{ desc: "want files that don't have 644 permissions, should find nothing", - search: search{ + search: Search{ Paths: []string{basedir}, Modes: []string{"-rw-r--r--"}, Options: options{ @@ -533,7 +533,7 @@ func TestMismatch(t *testing.T) { }, mismatchtest{ desc: "want files that don't have a name different than testfile0, should find testfile0", - search: search{ + search: Search{ Paths: []string{basedir}, Names: []string{"!^testfile0$"}, Options: options{ @@ -546,7 +546,7 @@ func TestMismatch(t *testing.T) { }, mismatchtest{ desc: "test matchall+macroal+mismatch: want file where at least one line fails to match the regex on testfile0, should find testfile1 that has the extra line 'some other other text'", - search: search{ + search: Search{ Paths: []string{basedir}, Names: []string{"^testfile(0|1)$"}, Contents: []string{`^((---.+)|(#.+)|(\s+)|(some (other )?text))?$`}, @@ -562,7 +562,7 @@ func TestMismatch(t *testing.T) { }, mismatchtest{ desc: "want files that don't match the hashes of testfile2, should find testfile0, 1, 3, 4, 5, 6, 7 & 8", - search: search{ + search: Search{ Paths: []string{basedir}, MD5: []string{TESTDATA[2].md5}, SHA1: []string{TESTDATA[2].sha1}, diff --git a/modules/file/paramscreator.go b/modules/file/paramscreator.go index 79232797..6b44d6c2 100644 --- a/modules/file/paramscreator.go +++ b/modules/file/paramscreator.go @@ -109,7 +109,7 @@ func (r *run) ParamsCreator() (interface{}, error) { scanner := bufio.NewScanner(os.Stdin) for { var label string - var search search + var search Search // sane defaults search.Options.MatchAll = true search.Options.MaxDepth = 1000 @@ -441,7 +441,7 @@ func (r *run) ParamsParser(args []string) (interface{}, error) { if err != nil { return nil, err } - var s search + var s Search s.Paths = paths s.Names = names s.Sizes = sizes