directory.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. package sources
  2. import (
  3. "io/fs"
  4. "os"
  5. "path/filepath"
  6. "github.com/fatih/semgroup"
  7. "github.com/rs/zerolog/log"
  8. )
  9. type ScanTarget struct {
  10. Path string
  11. Symlink string
  12. }
  13. func DirectoryTargets(source string, s *semgroup.Group, followSymlinks bool) (<-chan ScanTarget, error) {
  14. paths := make(chan ScanTarget)
  15. s.Go(func() error {
  16. defer close(paths)
  17. return filepath.Walk(source,
  18. func(path string, fInfo os.FileInfo, err error) error {
  19. if err != nil {
  20. return err
  21. }
  22. if fInfo.Name() == ".git" && fInfo.IsDir() {
  23. return filepath.SkipDir
  24. }
  25. if fInfo.Size() == 0 {
  26. return nil
  27. }
  28. if fInfo.Mode().IsRegular() {
  29. paths <- ScanTarget{
  30. Path: path,
  31. Symlink: "",
  32. }
  33. }
  34. if fInfo.Mode().Type() == fs.ModeSymlink && followSymlinks {
  35. realPath, err := filepath.EvalSymlinks(path)
  36. if err != nil {
  37. return err
  38. }
  39. realPathFileInfo, _ := os.Stat(realPath)
  40. if realPathFileInfo.IsDir() {
  41. log.Debug().Msgf("found symlinked directory: %s -> %s [skipping]", path, realPath)
  42. return nil
  43. }
  44. paths <- ScanTarget{
  45. Path: realPath,
  46. Symlink: path,
  47. }
  48. }
  49. return nil
  50. })
  51. })
  52. return paths, nil
  53. }