paths.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package watch
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "github.com/pkg/errors"
  7. "github.com/tilt-dev/tilt/internal/ospath"
  8. )
  9. func greatestExistingAncestor(path string) (string, error) {
  10. if path == string(filepath.Separator) ||
  11. path == fmt.Sprintf("%s%s", filepath.VolumeName(path), string(filepath.Separator)) {
  12. return "", fmt.Errorf("cannot watch root directory")
  13. }
  14. _, err := os.Stat(path)
  15. if err != nil && !os.IsNotExist(err) {
  16. return "", errors.Wrapf(err, "os.Stat(%q)", path)
  17. }
  18. if os.IsNotExist(err) {
  19. return greatestExistingAncestor(filepath.Dir(path))
  20. }
  21. return path, nil
  22. }
  23. // If we're recursively watching a path, it doesn't
  24. // make sense to watch any of its descendants.
  25. func dedupePathsForRecursiveWatcher(paths []string) []string {
  26. result := []string{}
  27. for _, current := range paths {
  28. isCovered := false
  29. hasRemovals := false
  30. for i, existing := range result {
  31. if ospath.IsChild(existing, current) {
  32. // The path is already covered, so there's no need to include it
  33. isCovered = true
  34. break
  35. }
  36. if ospath.IsChild(current, existing) {
  37. // Mark the element empty fo removal.
  38. result[i] = ""
  39. hasRemovals = true
  40. }
  41. }
  42. if !isCovered {
  43. result = append(result, current)
  44. }
  45. if hasRemovals {
  46. // Remove all the empties
  47. newResult := []string{}
  48. for _, r := range result {
  49. if r != "" {
  50. newResult = append(newResult, r)
  51. }
  52. }
  53. result = newResult
  54. }
  55. }
  56. return result
  57. }