files.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package detect
  2. import (
  3. "context"
  4. "os"
  5. "path/filepath"
  6. "sync"
  7. "golang.org/x/sync/errgroup"
  8. godocutil "golang.org/x/tools/godoc/util"
  9. "github.com/zricethezav/gitleaks/v8/config"
  10. "github.com/zricethezav/gitleaks/v8/report"
  11. )
  12. // FromFiles opens the directory or file specified in source and checks each file against the rules
  13. // from the configuration. If any secrets are found, they are added to the list of findings.
  14. func FromFiles(source string, cfg config.Config, outputOptions Options) ([]*report.Finding, error) {
  15. var (
  16. findings []*report.Finding
  17. mu sync.Mutex
  18. )
  19. g, _ := errgroup.WithContext(context.Background())
  20. paths := make(chan string)
  21. g.Go(func() error {
  22. defer close(paths)
  23. return filepath.Walk(source,
  24. func(path string, fInfo os.FileInfo, err error) error {
  25. if err != nil {
  26. return err
  27. }
  28. if fInfo.Name() == ".git" {
  29. return filepath.SkipDir
  30. }
  31. if fInfo.Mode().IsRegular() {
  32. paths <- path
  33. }
  34. return nil
  35. })
  36. })
  37. for pa := range paths {
  38. p := pa
  39. g.Go(func() error {
  40. b, err := os.ReadFile(p)
  41. if err != nil {
  42. return err
  43. }
  44. if !godocutil.IsText(b) {
  45. return nil
  46. }
  47. fis := DetectFindings(cfg, b, p, "")
  48. for _, fi := range fis {
  49. fi.File = p
  50. if outputOptions.Redact {
  51. fi.Redact()
  52. }
  53. if outputOptions.Verbose {
  54. printFinding(fi)
  55. }
  56. mu.Lock()
  57. findings = append(findings, &fi)
  58. mu.Unlock()
  59. }
  60. return nil
  61. })
  62. }
  63. if err := g.Wait(); err != nil {
  64. return findings, err
  65. }
  66. return findings, nil
  67. }