@@ -45,6 +45,7 @@ func NewFSEventHandler(
45
45
genSourceMapVis bool ,
46
46
keepOrphanedFiles bool ,
47
47
fileWriter FileWriterFunc ,
48
+ lazy bool ,
48
49
) * FSEventHandler {
49
50
if ! path .IsAbs (dir ) {
50
51
dir , _ = filepath .Abs (dir )
@@ -63,6 +64,7 @@ func NewFSEventHandler(
63
64
DevMode : devMode ,
64
65
keepOrphanedFiles : keepOrphanedFiles ,
65
66
writer : fileWriter ,
67
+ lazy : lazy ,
66
68
}
67
69
if devMode {
68
70
fseh .genOpts = append (fseh .genOpts , generator .WithExtractStrings ())
@@ -86,6 +88,7 @@ type FSEventHandler struct {
86
88
Errors []error
87
89
keepOrphanedFiles bool
88
90
writer func (string , []byte ) error
91
+ lazy bool
89
92
}
90
93
91
94
func (h * FSEventHandler ) HandleEvent (ctx context.Context , event fsnotify.Event ) (goUpdated , textUpdated bool , err error ) {
@@ -125,10 +128,16 @@ func (h *FSEventHandler) HandleEvent(ctx context.Context, event fsnotify.Event)
125
128
}
126
129
127
130
// If the file hasn't been updated since the last time we processed it, ignore it.
128
- if ! h .UpsertLastModTime (event .Name ) {
131
+ lastModTime , updatedModTime := h .UpsertLastModTime (event .Name )
132
+ if ! updatedModTime {
129
133
h .Log .Debug ("Skipping file because it wasn't updated" , slog .String ("file" , event .Name ))
130
134
return false , false , nil
131
135
}
136
+ // If the go file is newer than the templ file, skip generation, because it's up-to-date.
137
+ if h .lazy && goFileIsUpToDate (event .Name , lastModTime ) {
138
+ h .Log .Debug ("Skipping file because the Go file is up-to-date" , slog .String ("file" , event .Name ))
139
+ return false , false , nil
140
+ }
132
141
133
142
// Start a processor.
134
143
start := time .Now ()
@@ -159,6 +168,15 @@ func (h *FSEventHandler) HandleEvent(ctx context.Context, event fsnotify.Event)
159
168
return goUpdated , textUpdated , nil
160
169
}
161
170
171
+ func goFileIsUpToDate (templFileName string , templFileLastMod time.Time ) (upToDate bool ) {
172
+ goFileName := strings .TrimSuffix (templFileName , ".templ" ) + "_templ.go"
173
+ goFileInfo , err := os .Stat (goFileName )
174
+ if err != nil {
175
+ return false
176
+ }
177
+ return goFileInfo .ModTime ().After (templFileLastMod )
178
+ }
179
+
162
180
func (h * FSEventHandler ) SetError (fileName string , hasError bool ) (previouslyHadError bool , errorCount int ) {
163
181
h .fileNameToErrorMutex .Lock ()
164
182
defer h .fileNameToErrorMutex .Unlock ()
@@ -170,19 +188,20 @@ func (h *FSEventHandler) SetError(fileName string, hasError bool) (previouslyHad
170
188
return previouslyHadError , len (h .fileNameToError )
171
189
}
172
190
173
- func (h * FSEventHandler ) UpsertLastModTime (fileName string ) (updated bool ) {
191
+ func (h * FSEventHandler ) UpsertLastModTime (fileName string ) (modTime time. Time , updated bool ) {
174
192
fileInfo , err := os .Stat (fileName )
175
193
if err != nil {
176
- return false
194
+ return modTime , false
177
195
}
178
196
h .fileNameToLastModTimeMutex .Lock ()
179
197
defer h .fileNameToLastModTimeMutex .Unlock ()
180
- lastModTime := h .fileNameToLastModTime [fileName ]
181
- if ! fileInfo .ModTime ().After (lastModTime ) {
182
- return false
198
+ previousModTime := h .fileNameToLastModTime [fileName ]
199
+ currentModTime := fileInfo .ModTime ()
200
+ if ! currentModTime .After (previousModTime ) {
201
+ return currentModTime , false
183
202
}
184
- h .fileNameToLastModTime [fileName ] = fileInfo . ModTime ()
185
- return true
203
+ h .fileNameToLastModTime [fileName ] = currentModTime
204
+ return currentModTime , true
186
205
}
187
206
188
207
func (h * FSEventHandler ) UpsertHash (fileName string , hash [sha256 .Size ]byte ) (updated bool ) {
0 commit comments