16
16
package librariesmanager
17
17
18
18
import (
19
+ "crypto/md5"
20
+ "encoding/hex"
19
21
"errors"
20
22
"fmt"
21
23
"os"
22
24
"slices"
23
25
"strings"
24
26
"sync"
27
+ "time"
25
28
26
29
"github.com/arduino/arduino-cli/internal/arduino/cores"
27
30
"github.com/arduino/arduino-cli/internal/arduino/libraries"
@@ -124,12 +127,12 @@ func (lm *LibrariesManager) NewInstaller() (*Installer, func()) {
124
127
}
125
128
126
129
// Build builds a new LibrariesManager.
127
- func (lmb * Builder ) Build () (* LibrariesManager , []* status.Status ) {
130
+ func (lmb * Builder ) Build (cacheDir * paths. Path ) (* LibrariesManager , []* status.Status ) {
128
131
var statuses []* status.Status
129
132
res := & LibrariesManager {}
130
133
for _ , dir := range lmb .librariesDir {
131
134
if ! dir .scanned {
132
- if errs := lmb .loadLibrariesFromDir (dir ); len (errs ) > 0 {
135
+ if errs := lmb .loadLibrariesFromDir (dir , cacheDir ); len (errs ) > 0 {
133
136
statuses = append (statuses , errs ... )
134
137
}
135
138
}
@@ -167,11 +170,11 @@ func (lmb *Builder) AddLibrariesDir(libDir LibrariesDir) {
167
170
}
168
171
169
172
// RescanLibraries reload all installed libraries in the system.
170
- func (lmi * Installer ) RescanLibraries () []* status.Status {
173
+ func (lmi * Installer ) RescanLibraries (cacheDir * paths. Path ) []* status.Status {
171
174
lmi .libraries = map [string ]libraries.List {}
172
175
statuses := []* status.Status {}
173
176
for _ , dir := range lmi .librariesDir {
174
- if errs := lmi .loadLibrariesFromDir (dir ); len (errs ) > 0 {
177
+ if errs := lmi .loadLibrariesFromDir (dir , cacheDir ); len (errs ) > 0 {
175
178
statuses = append (statuses , errs ... )
176
179
}
177
180
}
@@ -194,15 +197,30 @@ func (lm *LibrariesManager) getLibrariesDir(installLocation libraries.LibraryLoc
194
197
}
195
198
}
196
199
200
+ func (lm * LibrariesManager ) libCacheFile (librariesDir * LibrariesDir , cacheDir * paths.Path ) * paths.Path {
201
+ if cacheDir == nil {
202
+ return nil
203
+ }
204
+ hash := md5 .Sum ([]byte (librariesDir .Path .String ()))
205
+ cache := cacheDir .Join ("libs" , "cache_" + hex .EncodeToString (hash [:]))
206
+ if stat , err := cache .Stat (); err != nil {
207
+ return cache
208
+ } else if time .Since (stat .ModTime ()) < time .Hour * 24 {
209
+ return cache
210
+ }
211
+ cache .Remove ()
212
+ return cache
213
+ }
214
+
197
215
// loadLibrariesFromDir loads all libraries in the given directory. Returns
198
216
// nil if the directory doesn't exists.
199
- func (lm * LibrariesManager ) loadLibrariesFromDir (librariesDir * LibrariesDir ) []* status.Status {
217
+ func (lm * LibrariesManager ) loadLibrariesFromDir (librariesDir * LibrariesDir , cacheDir * paths. Path ) []* status.Status {
200
218
statuses := []* status.Status {}
201
219
202
220
librariesDir .scanned = true
203
221
204
222
var loadedLibs libraries.List
205
- if cacheFilePath := librariesDir . Path . Join ( "libraries-loader-cache" ); cacheFilePath .Exist () {
223
+ if cacheFilePath := lm . libCacheFile ( librariesDir , cacheDir ); cacheFilePath != nil && cacheFilePath .Exist () {
206
224
logrus .WithField ("file" , cacheFilePath ).Info ("Using library cache" )
207
225
208
226
// Load lib cache
@@ -214,6 +232,7 @@ func (lm *LibrariesManager) loadLibrariesFromDir(librariesDir *LibrariesDir) []*
214
232
defer cache .Close ()
215
233
216
234
if err := loadedLibs .UnmarshalBinary (cache ); err != nil {
235
+ cacheFilePath .Remove ()
217
236
s := status .Newf (codes .FailedPrecondition , "reading lib cache %[1]s: %[2]s" , cacheFilePath , err )
218
237
return append (statuses , s )
219
238
}
@@ -246,17 +265,20 @@ func (lm *LibrariesManager) loadLibrariesFromDir(librariesDir *LibrariesDir) []*
246
265
}
247
266
248
267
// Write lib cache
249
- cache , err := cacheFilePath .Create ()
250
- if err != nil {
251
- s := status .Newf (codes .FailedPrecondition , "creating lib cache %[1]s: %[2]s" , cacheFilePath , err )
252
- return append (statuses , s )
253
- }
254
- err = loadedLibs .MarshalBinary (cache )
255
- cache .Close ()
256
- if err != nil {
257
- cacheFilePath .Remove ()
258
- s := status .Newf (codes .FailedPrecondition , "writing lib cache %[1]s: %[2]s" , cacheFilePath , err )
259
- return append (statuses , s )
268
+ if cacheFilePath != nil {
269
+ cacheFilePath .Parent ().MkdirAll ()
270
+ cache , err := cacheFilePath .Create ()
271
+ if err != nil {
272
+ s := status .Newf (codes .FailedPrecondition , "creating lib cache %[1]s: %[2]s" , cacheFilePath , err )
273
+ return append (statuses , s )
274
+ }
275
+ err = loadedLibs .MarshalBinary (cache )
276
+ cache .Close ()
277
+ if err != nil {
278
+ cacheFilePath .Remove ()
279
+ s := status .Newf (codes .FailedPrecondition , "writing lib cache %[1]s: %[2]s" , cacheFilePath , err )
280
+ return append (statuses , s )
281
+ }
260
282
}
261
283
}
262
284
0 commit comments