Skip to content

Commit 3001ca5

Browse files
committed
Removed state-altering methods from PackageManager
They have been moved into a Builder object that has the ability to build a new PackageManager. This allows to clearly separate subrotuines that actually change the status of the PackageManager from subroutines that just need to query it.
1 parent 3768793 commit 3001ca5

File tree

10 files changed

+191
-137
lines changed

10 files changed

+191
-137
lines changed

arduino/cores/packagemanager/loader.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import (
3434
)
3535

3636
// LoadHardware read all plaforms from the configured paths
37-
func (pm *PackageManager) LoadHardware() []error {
37+
func (pm *Builder) LoadHardware() []error {
3838
hardwareDirs := configuration.HardwareDirectories(configuration.Settings)
3939
merr := pm.LoadHardwareFromDirectories(hardwareDirs)
4040

@@ -45,7 +45,7 @@ func (pm *PackageManager) LoadHardware() []error {
4545
}
4646

4747
// LoadHardwareFromDirectories load plaforms from a set of directories
48-
func (pm *PackageManager) LoadHardwareFromDirectories(hardwarePaths paths.PathList) []error {
48+
func (pm *Builder) LoadHardwareFromDirectories(hardwarePaths paths.PathList) []error {
4949
var merr []error
5050
for _, path := range hardwarePaths {
5151
merr = append(merr, pm.LoadHardwareFromDirectory(path)...)
@@ -54,7 +54,7 @@ func (pm *PackageManager) LoadHardwareFromDirectories(hardwarePaths paths.PathLi
5454
}
5555

5656
// LoadHardwareFromDirectory read a plaform from the path passed as parameter
57-
func (pm *PackageManager) LoadHardwareFromDirectory(path *paths.Path) []error {
57+
func (pm *Builder) LoadHardwareFromDirectory(path *paths.Path) []error {
5858
var merr []error
5959
pm.log.Infof("Loading hardware from: %s", path)
6060
if err := path.ToAbs(); err != nil {
@@ -143,7 +143,7 @@ func (pm *PackageManager) LoadHardwareFromDirectory(path *paths.Path) []error {
143143
// loadPlatforms load plaftorms from the specified directory assuming that they belongs
144144
// to the targetPackage object passed as parameter.
145145
// A list of gRPC Status error is returned for each Platform failed to load.
146-
func (pm *PackageManager) loadPlatforms(targetPackage *cores.Package, packageDir *paths.Path) []error {
146+
func (pm *Builder) loadPlatforms(targetPackage *cores.Package, packageDir *paths.Path) []error {
147147
pm.log.Infof("Loading package %s from: %s", targetPackage.Name, packageDir)
148148

149149
var merr []error
@@ -175,7 +175,7 @@ func (pm *PackageManager) loadPlatforms(targetPackage *cores.Package, packageDir
175175
// loadPlatform loads a single platform and all its installed releases given a platformPath.
176176
// platformPath must be a directory.
177177
// Returns a gRPC Status error in case of failures.
178-
func (pm *PackageManager) loadPlatform(targetPackage *cores.Package, architecture string, platformPath *paths.Path) error {
178+
func (pm *Builder) loadPlatform(targetPackage *cores.Package, architecture string, platformPath *paths.Path) error {
179179
// This is not a platform
180180
if platformPath.IsNotDir() {
181181
return errors.New(tr("path is not a platform directory: %s", platformPath))
@@ -284,7 +284,7 @@ func (pm *PackageManager) loadPlatform(targetPackage *cores.Package, architectur
284284
return nil
285285
}
286286

287-
func (pm *PackageManager) loadPlatformRelease(platform *cores.PlatformRelease, path *paths.Path) error {
287+
func (pm *Builder) loadPlatformRelease(platform *cores.PlatformRelease, path *paths.Path) error {
288288
platform.InstallDir = path
289289

290290
// Some useful paths
@@ -445,14 +445,14 @@ func convertLegacyNetworkPatternToPluggableDiscovery(props *properties.Map, newT
445445
return res
446446
}
447447

448-
func (pm *PackageManager) loadProgrammer(programmerProperties *properties.Map) *cores.Programmer {
448+
func (pm *Builder) loadProgrammer(programmerProperties *properties.Map) *cores.Programmer {
449449
return &cores.Programmer{
450450
Name: programmerProperties.Get("name"),
451451
Properties: programmerProperties,
452452
}
453453
}
454454

455-
func (pm *PackageManager) loadBoards(platform *cores.PlatformRelease) error {
455+
func (pm *Builder) loadBoards(platform *cores.PlatformRelease) error {
456456
if platform.InstallDir == nil {
457457
return fmt.Errorf(tr("platform not installed"))
458458
}
@@ -596,7 +596,7 @@ func convertUploadToolsToPluggableDiscovery(props *properties.Map) {
596596

597597
// LoadToolsFromPackageDir loads a set of tools from the given toolsPath. The tools will be loaded
598598
// in the given *Package.
599-
func (pm *PackageManager) LoadToolsFromPackageDir(targetPackage *cores.Package, toolsPath *paths.Path) []error {
599+
func (pm *Builder) LoadToolsFromPackageDir(targetPackage *cores.Package, toolsPath *paths.Path) []error {
600600
pm.log.Infof("Loading tools from dir: %s", toolsPath)
601601

602602
var merr []error
@@ -617,7 +617,7 @@ func (pm *PackageManager) LoadToolsFromPackageDir(targetPackage *cores.Package,
617617
return merr
618618
}
619619

620-
func (pm *PackageManager) loadToolReleasesFromTool(tool *cores.Tool, toolPath *paths.Path) error {
620+
func (pm *Builder) loadToolReleasesFromTool(tool *cores.Tool, toolPath *paths.Path) error {
621621
toolVersions, err := toolPath.ReadDir()
622622
if err != nil {
623623
return err
@@ -634,7 +634,7 @@ func (pm *PackageManager) loadToolReleasesFromTool(tool *cores.Tool, toolPath *p
634634
return nil
635635
}
636636

637-
func (pm *PackageManager) loadToolReleaseFromDirectory(tool *cores.Tool, version *semver.RelaxedVersion, toolReleasePath *paths.Path) error {
637+
func (pm *Builder) loadToolReleaseFromDirectory(tool *cores.Tool, version *semver.RelaxedVersion, toolReleasePath *paths.Path) error {
638638
if absToolReleasePath, err := toolReleasePath.Abs(); err != nil {
639639
return errors.New(tr("error opening %s", absToolReleasePath))
640640
} else if !absToolReleasePath.IsDir() {
@@ -648,7 +648,7 @@ func (pm *PackageManager) loadToolReleaseFromDirectory(tool *cores.Tool, version
648648
}
649649

650650
// LoadToolsFromBundleDirectories FIXMEDOC
651-
func (pm *PackageManager) LoadToolsFromBundleDirectories(dirs paths.PathList) []error {
651+
func (pm *Builder) LoadToolsFromBundleDirectories(dirs paths.PathList) []error {
652652
var merr []error
653653
for _, dir := range dirs {
654654
if err := pm.LoadToolsFromBundleDirectory(dir); err != nil {
@@ -659,7 +659,7 @@ func (pm *PackageManager) LoadToolsFromBundleDirectories(dirs paths.PathList) []
659659
}
660660

661661
// LoadToolsFromBundleDirectory FIXMEDOC
662-
func (pm *PackageManager) LoadToolsFromBundleDirectory(toolsPath *paths.Path) error {
662+
func (pm *Builder) LoadToolsFromBundleDirectory(toolsPath *paths.Path) error {
663663
pm.log.Infof("Loading tools from bundle dir: %s", toolsPath)
664664

665665
// We scan toolsPath content to find a "builtin_tools_versions.txt", if such file exists

arduino/cores/packagemanager/loader_test.go

+19-19
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ func TestLoadDiscoveries(t *testing.T) {
111111
fakePath := paths.New("fake-path")
112112

113113
createTestPackageManager := func() *PackageManager {
114-
packageManager := NewPackageManager(fakePath, fakePath, fakePath, fakePath, "test")
115-
pack := packageManager.Packages.GetOrCreatePackage("arduino")
114+
pmb := NewBuilder(fakePath, fakePath, fakePath, fakePath, "test")
115+
pack := pmb.Packages.GetOrCreatePackage("arduino")
116116
// ble-discovery tool
117117
tool := pack.GetOrCreateTool("ble-discovery")
118118
toolRelease := tool.GetOrCreateRelease(semver.ParseRelaxed("1.0.0"))
@@ -131,71 +131,71 @@ func TestLoadDiscoveries(t *testing.T) {
131131
release := platform.GetOrCreateRelease(semver.MustParse("1.0.0"))
132132
release.InstallDir = fakePath
133133

134-
return packageManager
134+
return pmb.Build()
135135
}
136136

137-
packageManager := createTestPackageManager()
138-
release := packageManager.Packages["arduino"].Platforms["avr"].Releases["1.0.0"]
137+
pm := createTestPackageManager()
138+
release := pm.Packages["arduino"].Platforms["avr"].Releases["1.0.0"]
139139
release.Properties = properties.NewFromHashmap(map[string]string{
140140
"pluggable_discovery.required": "arduino:ble-discovery",
141141
})
142142

143-
err := packageManager.LoadDiscoveries()
143+
err := pm.LoadDiscoveries()
144144
require.Len(t, err, 2)
145145
require.Equal(t, err[0].Error(), "discovery builtin:serial-discovery not found")
146146
require.Equal(t, err[1].Error(), "discovery builtin:mdns-discovery not found")
147-
discoveries := packageManager.DiscoveryManager().IDs()
147+
discoveries := pm.DiscoveryManager().IDs()
148148
require.Len(t, discoveries, 1)
149149
require.Contains(t, discoveries, "arduino:ble-discovery")
150150

151-
packageManager = createTestPackageManager()
152-
release = packageManager.Packages["arduino"].Platforms["avr"].Releases["1.0.0"]
151+
pm = createTestPackageManager()
152+
release = pm.Packages["arduino"].Platforms["avr"].Releases["1.0.0"]
153153
release.Properties = properties.NewFromHashmap(map[string]string{
154154
"pluggable_discovery.required.0": "arduino:ble-discovery",
155155
"pluggable_discovery.required.1": "arduino:serial-discovery",
156156
})
157157

158-
err = packageManager.LoadDiscoveries()
158+
err = pm.LoadDiscoveries()
159159
require.Len(t, err, 2)
160160
require.Equal(t, err[0].Error(), "discovery builtin:serial-discovery not found")
161161
require.Equal(t, err[1].Error(), "discovery builtin:mdns-discovery not found")
162-
discoveries = packageManager.DiscoveryManager().IDs()
162+
discoveries = pm.DiscoveryManager().IDs()
163163
require.Len(t, discoveries, 2)
164164
require.Contains(t, discoveries, "arduino:ble-discovery")
165165
require.Contains(t, discoveries, "arduino:serial-discovery")
166166

167-
packageManager = createTestPackageManager()
168-
release = packageManager.Packages["arduino"].Platforms["avr"].Releases["1.0.0"]
167+
pm = createTestPackageManager()
168+
release = pm.Packages["arduino"].Platforms["avr"].Releases["1.0.0"]
169169
release.Properties = properties.NewFromHashmap(map[string]string{
170170
"pluggable_discovery.required.0": "arduino:ble-discovery",
171171
"pluggable_discovery.required.1": "arduino:serial-discovery",
172172
"pluggable_discovery.teensy.pattern": "\"{runtime.tools.teensy_ports.path}/hardware/tools/teensy_ports\" -J2",
173173
})
174174

175-
err = packageManager.LoadDiscoveries()
175+
err = pm.LoadDiscoveries()
176176
require.Len(t, err, 2)
177177
require.Equal(t, err[0].Error(), "discovery builtin:serial-discovery not found")
178178
require.Equal(t, err[1].Error(), "discovery builtin:mdns-discovery not found")
179-
discoveries = packageManager.DiscoveryManager().IDs()
179+
discoveries = pm.DiscoveryManager().IDs()
180180
require.Len(t, discoveries, 3)
181181
require.Contains(t, discoveries, "arduino:ble-discovery")
182182
require.Contains(t, discoveries, "arduino:serial-discovery")
183183
require.Contains(t, discoveries, "teensy")
184184

185-
packageManager = createTestPackageManager()
186-
release = packageManager.Packages["arduino"].Platforms["avr"].Releases["1.0.0"]
185+
pm = createTestPackageManager()
186+
release = pm.Packages["arduino"].Platforms["avr"].Releases["1.0.0"]
187187
release.Properties = properties.NewFromHashmap(map[string]string{
188188
"pluggable_discovery.required": "arduino:some-discovery",
189189
"pluggable_discovery.required.0": "arduino:ble-discovery",
190190
"pluggable_discovery.required.1": "arduino:serial-discovery",
191191
"pluggable_discovery.teensy.pattern": "\"{runtime.tools.teensy_ports.path}/hardware/tools/teensy_ports\" -J2",
192192
})
193193

194-
err = packageManager.LoadDiscoveries()
194+
err = pm.LoadDiscoveries()
195195
require.Len(t, err, 2)
196196
require.Equal(t, err[0].Error(), "discovery builtin:serial-discovery not found")
197197
require.Equal(t, err[1].Error(), "discovery builtin:mdns-discovery not found")
198-
discoveries = packageManager.DiscoveryManager().IDs()
198+
discoveries = pm.DiscoveryManager().IDs()
199199
require.Len(t, discoveries, 3)
200200
require.Contains(t, discoveries, "arduino:ble-discovery")
201201
require.Contains(t, discoveries, "arduino:serial-discovery")

arduino/cores/packagemanager/package_manager.go

+59-24
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,62 @@ type PackageManager struct {
5050
userAgent string
5151
}
5252

53+
// Builder is used to create a new PackageManager. The builder
54+
// has methods to load patforms and tools to actually build the PackageManager.
55+
// Once the PackageManager is built, it cannot be changed anymore.
56+
type Builder struct {
57+
*PackageManager
58+
}
59+
5360
var tr = i18n.Tr
5461

55-
// NewPackageManager returns a new instance of the PackageManager
56-
func NewPackageManager(indexDir, packagesDir, downloadDir, tempDir *paths.Path, userAgent string) *PackageManager {
57-
return &PackageManager{
58-
log: logrus.StandardLogger(),
59-
Packages: cores.NewPackages(),
60-
IndexDir: indexDir,
61-
PackagesDir: packagesDir,
62-
DownloadDir: downloadDir,
63-
tempDir: tempDir,
64-
CustomGlobalProperties: properties.NewMap(),
65-
discoveryManager: discoverymanager.New(),
66-
userAgent: userAgent,
62+
// NewBuilder returns a new Builder
63+
func NewBuilder(indexDir, packagesDir, downloadDir, tempDir *paths.Path, userAgent string) *Builder {
64+
return &Builder{
65+
PackageManager: &PackageManager{
66+
log: logrus.StandardLogger(),
67+
Packages: cores.NewPackages(),
68+
IndexDir: indexDir,
69+
PackagesDir: packagesDir,
70+
DownloadDir: downloadDir,
71+
tempDir: tempDir,
72+
CustomGlobalProperties: properties.NewMap(),
73+
discoveryManager: discoverymanager.New(),
74+
userAgent: userAgent,
75+
},
76+
}
77+
}
78+
79+
// BuildIntoExistingPackageManager will overwrite the give PackageManager instead
80+
// of building a new one.
81+
func (pmb *Builder) BuildIntoExistingPackageManager(old *PackageManager) {
82+
old.log = pmb.log
83+
old.Packages = pmb.Packages
84+
old.IndexDir = pmb.IndexDir
85+
old.PackagesDir = pmb.PackagesDir
86+
old.DownloadDir = pmb.DownloadDir
87+
old.tempDir = pmb.tempDir
88+
old.CustomGlobalProperties = pmb.CustomGlobalProperties
89+
old.profile = pmb.profile
90+
old.discoveryManager = pmb.discoveryManager
91+
old.userAgent = pmb.userAgent
92+
}
93+
94+
// Build builds a new PackageManager.
95+
func (pmb *Builder) Build() *PackageManager {
96+
res := &PackageManager{}
97+
pmb.BuildIntoExistingPackageManager(res)
98+
return res
99+
}
100+
101+
// NewBuilder creates a Builder with the same configuration
102+
// of this PackageManager. A "commit" function callback is returned: calling
103+
// this function will make the builder write the new configuration into this
104+
// PackageManager.
105+
func (pm *PackageManager) NewBuilder() (*Builder, func()) {
106+
pmb := NewBuilder(pm.IndexDir, pm.PackagesDir, pm.DownloadDir, pm.tempDir, pm.userAgent)
107+
return pmb, func() {
108+
pmb.BuildIntoExistingPackageManager(pm)
67109
}
68110
}
69111

@@ -83,13 +125,6 @@ func (pm *PackageManager) GetEnvVarsForSpawnedProcess() []string {
83125
}
84126
}
85127

86-
// Clear resets the PackageManager to its initial state
87-
func (pm *PackageManager) Clear() {
88-
pm.Packages = cores.NewPackages()
89-
pm.CustomGlobalProperties = properties.NewMap()
90-
pm.discoveryManager.Clear()
91-
}
92-
93128
// DiscoveryManager returns the DiscoveryManager in use by this PackageManager
94129
func (pm *PackageManager) DiscoveryManager() *discoverymanager.DiscoveryManager {
95130
return pm.discoveryManager
@@ -243,12 +278,12 @@ func (pm *PackageManager) ResolveFQBN(fqbn *cores.FQBN) (
243278
}
244279

245280
// LoadPackageIndex loads a package index by looking up the local cached file from the specified URL
246-
func (pm *PackageManager) LoadPackageIndex(URL *url.URL) error {
281+
func (pmb *Builder) LoadPackageIndex(URL *url.URL) error {
247282
indexFileName := path.Base(URL.Path)
248283
if strings.HasSuffix(indexFileName, ".tar.bz2") {
249284
indexFileName = strings.TrimSuffix(indexFileName, ".tar.bz2") + ".json"
250285
}
251-
indexPath := pm.IndexDir.Join(indexFileName)
286+
indexPath := pmb.IndexDir.Join(indexFileName)
252287
index, err := packageindex.LoadIndex(indexPath)
253288
if err != nil {
254289
return fmt.Errorf(tr("loading json index file %[1]s: %[2]s"), indexPath, err)
@@ -258,18 +293,18 @@ func (pm *PackageManager) LoadPackageIndex(URL *url.URL) error {
258293
p.URL = URL.String()
259294
}
260295

261-
index.MergeIntoPackages(pm.Packages)
296+
index.MergeIntoPackages(pmb.Packages)
262297
return nil
263298
}
264299

265300
// LoadPackageIndexFromFile load a package index from the specified file
266-
func (pm *PackageManager) LoadPackageIndexFromFile(indexPath *paths.Path) (*packageindex.Index, error) {
301+
func (pmb *Builder) LoadPackageIndexFromFile(indexPath *paths.Path) (*packageindex.Index, error) {
267302
index, err := packageindex.LoadIndex(indexPath)
268303
if err != nil {
269304
return nil, fmt.Errorf(tr("loading json index file %[1]s: %[2]s"), indexPath, err)
270305
}
271306

272-
index.MergeIntoPackages(pm.Packages)
307+
index.MergeIntoPackages(pmb.Packages)
273308
return index, nil
274309
}
275310

0 commit comments

Comments
 (0)