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.
7package filetracker
8
9import (
10 "sync"
11 "time"
12)
13
14// record tracks when a file was read/written.
15type record struct {
16 path string
17 readTime time.Time
18 writeTime time.Time
19}
20
21var (
22 records = make(map[string]record)
23 recordMutex sync.RWMutex
24)
25
26// RecordRead records when a file was read.
27func RecordRead(path string) {
28 recordMutex.Lock()
29 defer recordMutex.Unlock()
30
31 rec, exists := records[path]
32 if !exists {
33 rec = record{path: path}
34 }
35 rec.readTime = time.Now()
36 records[path] = rec
37}
38
39// LastReadTime returns when a file was last read. Returns zero time if never
40// read.
41func LastReadTime(path string) time.Time {
42 recordMutex.RLock()
43 defer recordMutex.RUnlock()
44
45 rec, exists := records[path]
46 if !exists {
47 return time.Time{}
48 }
49 return rec.readTime
50}
51
52// RecordWrite records when a file was written.
53func RecordWrite(path string) {
54 recordMutex.Lock()
55 defer recordMutex.Unlock()
56
57 rec, exists := records[path]
58 if !exists {
59 rec = record{path: path}
60 }
61 rec.writeTime = time.Now()
62 records[path] = rec
63}
64
65// Reset clears all file tracking records. Useful for testing.
66func Reset() {
67 recordMutex.Lock()
68 defer recordMutex.Unlock()
69 records = make(map[string]record)
70}