files.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. // need to add 1 since line counting starts at 1
  50. fi.StartLine++
  51. fi.EndLine++
  52. if outputOptions.Redact {
  53. fi.Redact()
  54. }
  55. if outputOptions.Verbose {
  56. printFinding(fi)
  57. }
  58. mu.Lock()
  59. findings = append(findings, fi)
  60. mu.Unlock()
  61. }
  62. return nil
  63. })
  64. }
  65. if err := g.Wait(); err != nil {
  66. return findings, err
  67. }
  68. return findings, nil
  69. }