Skip to content

Commit fe1ca8a

Browse files
committed
Added LibrariesManager.Clone() / Auto-scan libraries on LibrariesManager.Build()
1 parent 95753fc commit fe1ca8a

File tree

5 files changed

+61
-43
lines changed

5 files changed

+61
-43
lines changed

Diff for: commands/instances.go

+4-9
Original file line numberDiff line numberDiff line change
@@ -389,16 +389,11 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro
389389
}
390390
}
391391

392-
lm := lmb.Build()
392+
lm, libsLoadingWarnings := lmb.Build()
393393
_ = instances.SetLibraryManager(instance, lm) // should never fail
394-
395-
{
396-
lmi, release := lm.NewInstaller()
397-
for _, status := range lmi.RescanLibraries() {
398-
logrus.WithError(status.Err()).Warnf("Error loading library")
399-
// TODO: report as warning: responseError(err)
400-
}
401-
release()
394+
for _, status := range libsLoadingWarnings {
395+
logrus.WithError(status.Err()).Warnf("Error loading library")
396+
// TODO: report as warning: responseError(err)
402397
}
403398

404399
// Refreshes the locale used, this will change the

Diff for: commands/internal/instances/instances.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,12 @@ func Create(dataDir, packagesDir, downloadsDir *paths.Path, extraUserAgent ...st
126126
}
127127
tempDir := dataDir.Join("tmp")
128128

129+
pm := packagemanager.NewBuilder(dataDir, packagesDir, downloadsDir, tempDir, userAgent).Build()
130+
lm, _ := librariesmanager.NewBuilder().Build()
131+
129132
instance := &coreInstance{
130-
pm: packagemanager.NewBuilder(dataDir, packagesDir, downloadsDir, tempDir, userAgent).Build(),
131-
lm: librariesmanager.NewBuilder().Build(),
133+
pm: pm,
134+
lm: lm,
132135
li: librariesindex.EmptyIndex,
133136
}
134137

Diff for: internal/arduino/builder/internal/detector/detector.go

+11-15
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ func LibrariesLoader(
598598
if useCachedLibrariesResolution {
599599
// Since we are using the cached libraries resolution
600600
// the library manager is not needed.
601-
lm = librariesmanager.NewBuilder().Build()
601+
lm, _ = librariesmanager.NewBuilder().Build()
602602
}
603603
if librariesManager == nil {
604604
lmb := librariesmanager.NewBuilder()
@@ -646,21 +646,17 @@ func LibrariesLoader(
646646
})
647647
}
648648

649-
lm = lmb.Build()
650-
651-
{
652-
lmi, release := lm.NewInstaller()
653-
for _, status := range lmi.RescanLibraries() {
654-
// With the refactoring of the initialization step of the CLI we changed how
655-
// errors are returned when loading platforms and libraries, that meant returning a list of
656-
// errors instead of a single one to enhance the experience for the user.
657-
// I have no intention right now to start a refactoring of the legacy package too, so
658-
// here's this shitty solution for now.
659-
// When we're gonna refactor the legacy package this will be gone.
660-
verboseOut.Write([]byte(status.Message()))
661-
}
662-
release()
649+
newLm, libsLoadingWarnings := lmb.Build()
650+
for _, status := range libsLoadingWarnings {
651+
// With the refactoring of the initialization step of the CLI we changed how
652+
// errors are returned when loading platforms and libraries, that meant returning a list of
653+
// errors instead of a single one to enhance the experience for the user.
654+
// I have no intention right now to start a refactoring of the legacy package too, so
655+
// here's this shitty solution for now.
656+
// When we're gonna refactor the legacy package this will be gone.
657+
verboseOut.Write([]byte(status.Message()))
663658
}
659+
lm = newLm
664660
}
665661

666662
allLibs := lm.FindAllInstalled()

Diff for: internal/arduino/libraries/librariesmanager/librariesmanager.go

+27-11
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ type LibrariesDir struct {
6565
Location libraries.LibraryLocation
6666
PlatformRelease *cores.PlatformRelease
6767
IsSingleLibrary bool // true if Path points directly to a library instad of a dir of libraries
68+
scanned bool
6869
}
6970

7071
var tr = i18n.Tr
@@ -95,14 +96,19 @@ func NewBuilder() *Builder {
9596
}
9697
}
9798

98-
// NewBuilder creates a Builder with the same configuration of this
99-
// LibrariesManager. A "commit" function callback is returned: calling
100-
// this function will write the new configuration into this LibrariesManager.
101-
func (lm *LibrariesManager) NewBuilder() (*Builder, func()) {
99+
// Clone creates a Builder starting with a copy of the same configuration
100+
// of this LibrariesManager. At the moment of the Build() only the added
101+
// libraries directories will be scanned, keeping the exising directories
102+
// "cached" to optimize scan. If you need to do a full rescan you must use
103+
// the RescanLibraries method of the Installer.
104+
func (lm *LibrariesManager) Clone() *Builder {
102105
lmb := NewBuilder()
103-
return lmb, func() {
104-
lmb.BuildIntoExistingLibrariesManager(lm)
106+
lmb.librariesDir = append(lmb.librariesDir, lm.librariesDir...)
107+
for libName, libAlternatives := range lm.libraries {
108+
// TODO: Maybe we should deep clone libAlternatives...
109+
lmb.libraries[libName] = append(lmb.libraries[libName], libAlternatives...)
105110
}
111+
return lmb
106112
}
107113

108114
// NewExplorer returns a new Explorer. The returned function must be called
@@ -120,10 +126,18 @@ func (lm *LibrariesManager) NewInstaller() (*Installer, func()) {
120126
}
121127

122128
// Build builds a new LibrariesManager.
123-
func (lmb *Builder) Build() *LibrariesManager {
129+
func (lmb *Builder) Build() (*LibrariesManager, []*status.Status) {
130+
var statuses []*status.Status
124131
res := &LibrariesManager{}
132+
for _, dir := range res.librariesDir {
133+
if !dir.scanned {
134+
if errs := lmb.loadLibrariesFromDir(dir); len(errs) > 0 {
135+
statuses = append(statuses, errs...)
136+
}
137+
}
138+
}
125139
lmb.BuildIntoExistingLibrariesManager(res)
126-
return res
140+
return res, statuses
127141
}
128142

129143
// BuildIntoExistingLibrariesManager will overwrite the given LibrariesManager instead
@@ -184,9 +198,11 @@ func (lm *LibrariesManager) getLibrariesDir(installLocation libraries.LibraryLoc
184198

185199
// loadLibrariesFromDir loads all libraries in the given directory. Returns
186200
// nil if the directory doesn't exists.
187-
func (lmi *Installer) loadLibrariesFromDir(librariesDir *LibrariesDir) []*status.Status {
201+
func (lm *LibrariesManager) loadLibrariesFromDir(librariesDir *LibrariesDir) []*status.Status {
188202
statuses := []*status.Status{}
189203

204+
librariesDir.scanned = true
205+
190206
var libDirs paths.PathList
191207
if librariesDir.IsSingleLibrary {
192208
libDirs.Add(librariesDir.Path)
@@ -212,9 +228,9 @@ func (lmi *Installer) loadLibrariesFromDir(librariesDir *LibrariesDir) []*status
212228
continue
213229
}
214230
library.ContainerPlatform = librariesDir.PlatformRelease
215-
alternatives := lmi.libraries[library.Name]
231+
alternatives := lm.libraries[library.Name]
216232
alternatives.Add(library)
217-
lmi.libraries[library.Name] = alternatives
233+
lm.libraries[library.Name] = alternatives
218234
}
219235

220236
return statuses

Diff for: internal/arduino/libraries/librariesmanager/librariesmanager_test.go

+14-6
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,25 @@ import (
2121
"github.com/stretchr/testify/require"
2222
)
2323

24-
func Test_RescanLibrariesCallClear(t *testing.T) {
24+
func TestLibrariesBuilderScanCloneRescan(t *testing.T) {
2525
lmb := NewBuilder()
2626
lmb.libraries["testLibA"] = libraries.List{}
2727
lmb.libraries["testLibB"] = libraries.List{}
28-
lm := lmb.Build()
28+
lm, warns := lmb.Build()
29+
require.Empty(t, warns)
30+
require.Len(t, lm.libraries, 2)
2931

32+
// Cloning should keep existing libraries
33+
lm2, warns2 := lm.Clone().Build()
34+
require.Empty(t, warns2)
35+
require.Len(t, lm2.libraries, 2)
36+
37+
// Full rescan should update libs
3038
{
31-
lmi, release := lm.NewInstaller()
32-
lmi.RescanLibraries()
39+
lmi2, release := lm2.NewInstaller()
40+
lmi2.RescanLibraries()
3341
release()
3442
}
35-
36-
require.Len(t, lm.libraries, 0)
43+
require.Len(t, lm.libraries, 2) // Ensure deep-coping worked as expected...
44+
require.Len(t, lm2.libraries, 0)
3745
}

0 commit comments

Comments
 (0)