filetracker.go

 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}