filetracker.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Package filetracker tracks file read/write times to prevent editing files
  2. // that haven't been read, and to detect external modifications.
  3. //
  4. // TODO: Consider moving this to persistent storage (e.g., the database) to
  5. // preserve file access history across sessions.
  6. // We would need to make sure to handle the case where we reload a session and the underlying files did change.
  7. package filetracker
  8. import (
  9. "sync"
  10. "time"
  11. )
  12. // record tracks when a file was read/written.
  13. type record struct {
  14. path string
  15. readTime time.Time
  16. writeTime time.Time
  17. }
  18. var (
  19. records = make(map[string]record)
  20. recordMutex sync.RWMutex
  21. )
  22. // RecordRead records when a file was read.
  23. func RecordRead(path string) {
  24. recordMutex.Lock()
  25. defer recordMutex.Unlock()
  26. rec, exists := records[path]
  27. if !exists {
  28. rec = record{path: path}
  29. }
  30. rec.readTime = time.Now()
  31. records[path] = rec
  32. }
  33. // LastReadTime returns when a file was last read. Returns zero time if never
  34. // read.
  35. func LastReadTime(path string) time.Time {
  36. recordMutex.RLock()
  37. defer recordMutex.RUnlock()
  38. rec, exists := records[path]
  39. if !exists {
  40. return time.Time{}
  41. }
  42. return rec.readTime
  43. }
  44. // RecordWrite records when a file was written.
  45. func RecordWrite(path string) {
  46. recordMutex.Lock()
  47. defer recordMutex.Unlock()
  48. rec, exists := records[path]
  49. if !exists {
  50. rec = record{path: path}
  51. }
  52. rec.writeTime = time.Now()
  53. records[path] = rec
  54. }
  55. // Reset clears all file tracking records. Useful for testing.
  56. func Reset() {
  57. recordMutex.Lock()
  58. defer recordMutex.Unlock()
  59. records = make(map[string]record)
  60. }