package parser import ( "bytes" "encoding/json" "io/ioutil" "os" "path/filepath" "time" "github.com/gobuffalo/packr/v2/plog" "github.com/karrick/godirwalk" ) type RootsOptions struct { IgnoreImports bool Ignores []string } func (r RootsOptions) String() string { x, _ := json.Marshal(r) return string(x) } // NewFromRoots scans the file roots provided and returns a // new Parser containing the prospects func NewFromRoots(roots []string, opts *RootsOptions) (*Parser, error) { if opts == nil { opts = &RootsOptions{} } if len(roots) == 0 { pwd, _ := os.Getwd() roots = append(roots, pwd) } p := New() plog.Debug(p, "NewFromRoots", "roots", roots, "options", opts) callback := func(path string, de *godirwalk.Dirent) error { if IsProspect(path, opts.Ignores...) { if de.IsDir() { return nil } roots = append(roots, path) return nil } if de.IsDir() { return filepath.SkipDir } return nil } wopts := &godirwalk.Options{ FollowSymbolicLinks: true, Callback: callback, } for _, root := range roots { plog.Debug(p, "NewFromRoots", "walking", root) err := godirwalk.Walk(root, wopts) if err != nil { return p, err } } dd := map[string]string{} fd := &finder{id: time.Now()} for _, r := range roots { var names []string if opts.IgnoreImports { names, _ = fd.findAllGoFiles(r) } else { names, _ = fd.findAllGoFilesImports(r) } for _, n := range names { if IsProspect(n) { plog.Debug(p, "NewFromRoots", "mapping", n) dd[n] = n } } } for path := range dd { plog.Debug(p, "NewFromRoots", "reading file", path) b, err := ioutil.ReadFile(path) if err != nil { return nil, err } p.Prospects = append(p.Prospects, NewFile(path, bytes.NewReader(b))) } plog.Debug(p, "NewFromRoots", "found prospects", len(p.Prospects)) return p, nil }