directory.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. package sources
  2. import (
  3. "github.com/rs/zerolog/log"
  4. "io/fs"
  5. "os"
  6. "path/filepath"
  7. "github.com/fatih/semgroup"
  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 {
  35. if !followSymlinks {
  36. log.Debug().Str("path", path).Msg("Skipping symlink")
  37. return nil
  38. }
  39. realPath, err := filepath.EvalSymlinks(path)
  40. if err != nil {
  41. return err
  42. }
  43. realPathFileInfo, _ := os.Stat(realPath)
  44. if realPathFileInfo.IsDir() {
  45. log.Debug().Msgf("found symlinked directory: %s -> %s [skipping]", path, realPath)
  46. return nil
  47. }
  48. paths <- ScanTarget{
  49. Path: realPath,
  50. Symlink: path,
  51. }
  52. }
  53. return nil
  54. })
  55. })
  56. return paths, nil
  57. }