The signature of the package will include a context, the root folder, the search term, and a couple of optional parameters:
- Search in contents: Will look for the string in the file's contents instead of the name
- Exclude list: Will not search the files with the selected name/names
The function would look something like this:
type Options struct {
Contents bool
Exclude []string
}
func FileSearch(ctx context.Context, root, term string, o *Options)
Since it should be a concurrent function, the return type could be a channel of result, which could be either an error or a series of matches in a file. Since we can search for the names of content, the latter could have more than one match:
type Result struct {
Err error
File string
Matches []Match
}
type Match struct {
Line int
Text string
}
The previous function will return a receive-only channel of the Result type:
func FileSearch(ctx context.Context, root, term string, o *Options) <-chan Result
Here, this function would keep receiving values from the channel until it gets closed:
for r := range FileSearch(ctx, directory, searchTerm, options) {
if r.Err != nil {
fmt.Printf("%s - error: %s\n", r.File, r.Err)
continue
}
if !options.Contents {
fmt.Printf("%s - match\n", r.File)
continue
}
fmt.Printf("%s - matches:\n", r.File)
for _, m := range r.Matches {
fmt.Printf("\t%d:%s\n", m.Line, m.Text)
}
}