Skip to content

Commit 04e70c5

Browse files
committed
Updated documentation
1 parent 46eeee2 commit 04e70c5

File tree

2 files changed

+266
-3
lines changed

2 files changed

+266
-3
lines changed

Diff for: arduino/cores/packagemanager/package_manager.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,8 @@ func (pm *PackageManager) NewBuilder() (builder *Builder, commit func()) {
117117

118118
// NewExplorer creates an Explorer for this PackageManager.
119119
// The Explorer will keep a read-lock on the underlying PackageManager,
120-
// and a "release" callback function to release the lock is returned.
121-
// The "release" function must be called when the Explorer is no more
122-
// to correctly dispose it.
120+
// the user must call the "release" callback function to release the lock
121+
// when the Explorer is no more needed.
123122
func (pm *PackageManager) NewExplorer() (explorer *Explorer, release func()) {
124123
pm.packagesLock.RLock()
125124
return &Explorer{

Diff for: docs/UPGRADING.md

+264
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,270 @@
22

33
Here you can find a list of migration guides to handle breaking changes between releases of the CLI.
44

5+
## 0.27.0
6+
7+
### Breaking changes in golang API `github.com/arduino/arduino-cli/arduino/cores/packagemanager.PackageManager`
8+
9+
The `PackageManager` API has been heavily refactored to correctly handle multitasking and concurrency. Many fields in
10+
the PackageManager object are now private. All the `PackageManager` methods have been moved into other objects. In
11+
particular:
12+
13+
- the methods that query the `PackageManager` without changing its internal state, have been moved into the new
14+
`Explorer` object
15+
- the methods that change the `PackageManager` internal state, have been moved into the new `Builder` object.
16+
17+
The `Builder` object must be used to create a new `PackageManager`. Previously the function `NewPackageManager` was used
18+
to get a clean `PackageManager` object and then use the `LoadHardware*` methods to build it. Now the function
19+
`NewBuilder` must be used to create a `Builder`, run the `LoadHardware*` methods to load platforms, and finally call the
20+
`Builder.Build()` method to obtain the final `PackageManager`.
21+
22+
Previously we did:
23+
24+
```go
25+
pm := packagemanager.NewPackageManager(...)
26+
err = pm.LoadHardware()
27+
err = pm.LoadHardwareFromDirectories(...)
28+
err = pm.LoadHardwareFromDirectory(...)
29+
err = pm.LoadToolsFromPackageDir(...)
30+
err = pm.LoadToolsFromBundleDirectories(...)
31+
err = pm.LoadToolsFromBundleDirectory(...)
32+
pack = pm.GetOrCreatePackage("packagername")
33+
// ...use `pack` to tweak or load more hardware...
34+
err = pm.LoadPackageIndex(...)
35+
err = pm.LoadPackageIndexFromFile(...)
36+
err = pm.LoadHardwareForProfile(...)
37+
38+
// ...use `pm` to implement business logic...
39+
```
40+
41+
Now we must do:
42+
43+
```go
44+
var pm *packagemanager.PackageManager
45+
46+
{
47+
pmb := packagemanager.Newbuilder(...)
48+
err = pmb.LoadHardware()
49+
err = pmb.LoadHardwareFromDirectories(...)
50+
err = pmb.LoadHardwareFromDirectory(...)
51+
err = pmb.LoadToolsFromPackageDir(...)
52+
err = pmb.LoadToolsFromBundleDirectories(...)
53+
err = pmb.LoadToolsFromBundleDirectory(...)
54+
pack = pmb.GetOrCreatePackage("packagername")
55+
// ...use `pack` to tweak or load more hardware...
56+
err = pmb.LoadPackageIndex(...)
57+
err = pmb.LoadPackageIndexFromFile(...)
58+
err = pmb.LoadHardwareForProfile(...)
59+
pm = pmb.Build()
60+
}
61+
62+
// ...use `pm` to implement business logic...
63+
```
64+
65+
It's not mandatory but highly recommended, to drop the `Builder` object once it has built the `PackageManager` (that's
66+
why in the example the `pmb` builder is created in a limited scope between braces).
67+
68+
To query the `PackagerManager` now it is required to obtain an `Explorer` object through the
69+
`PackageManager.NewExplorer()` method.
70+
71+
Previously we did:
72+
73+
```go
74+
func DoStuff(pm *packagemanager.PackageManager, ...) {
75+
// ...implement business logic through PackageManager methods...
76+
... := pm.Packages
77+
... := pm.CustomGlobalProperties
78+
... := pm.FindPlatform(...)
79+
... := pm.FindPlatformRelease(...)
80+
... := pm.FindPlatformReleaseDependencies(...)
81+
... := pm.DownloadToolRelease(...)
82+
... := pm.DownloadPlatformRelease(...)
83+
... := pm.IdentifyBoard(...)
84+
... := pm.DownloadAndInstallPlatformUpgrades(...)
85+
... := pm.DownloadAndInstallPlatformAndTools(...)
86+
... := pm.InstallPlatform(...)
87+
... := pm.InstallPlatformInDirectory(...)
88+
... := pm.RunPostInstallScript(...)
89+
... := pm.IsManagedPlatformRelease(...)
90+
... := pm.UninstallPlatform(...)
91+
... := pm.InstallTool(...)
92+
... := pm.IsManagedToolRelease(...)
93+
... := pm.UninstallTool(...)
94+
... := pm.IsToolRequired(...)
95+
... := pm.LoadDiscoveries(...)
96+
... := pm.GetProfile(...)
97+
... := pm.GetEnvVarsForSpawnedProcess(...)
98+
... := pm.DiscoveryManager(...)
99+
... := pm.FindPlatformReleaseProvidingBoardsWithVidPid(...)
100+
... := pm.FindBoardsWithVidPid(...)
101+
... := pm.FindBoardsWithID(...)
102+
... := pm.FindBoardWithFQBN(...)
103+
... := pm.ResolveFQBN(...)
104+
... := pm.Package(...)
105+
... := pm.GetInstalledPlatformRelease(...)
106+
... := pm.GetAllInstalledToolsReleases(...)
107+
... := pm.InstalledPlatformReleases(...)
108+
... := pm.InstalledBoards(...)
109+
... := pm.FindToolsRequiredFromPlatformRelease(...)
110+
... := pm.GetTool(...)
111+
... := pm.FindToolsRequiredForBoard(...)
112+
... := pm.FindToolDependency(...)
113+
... := pm.FindDiscoveryDependency(...)
114+
... := pm.FindMonitorDependency(...)
115+
}
116+
```
117+
118+
Now we must obtain the `Explorer` object to access the same methods, moreover, we must call the `release` callback
119+
function once we complete the task:
120+
121+
```go
122+
func DoStuff(pm *packagemanager.PackageManager, ...) {
123+
pme, release := pm.NewExplorer()
124+
defer release()
125+
126+
... := pme.GetPackages()
127+
... := pme.GetCustomGlobalProperties()
128+
... := pme.FindPlatform(...)
129+
... := pme.FindPlatformRelease(...)
130+
... := pme.FindPlatformReleaseDependencies(...)
131+
... := pme.DownloadToolRelease(...)
132+
... := pme.DownloadPlatformRelease(...)
133+
... := pme.IdentifyBoard(...)
134+
... := pme.DownloadAndInstallPlatformUpgrades(...)
135+
... := pme.DownloadAndInstallPlatformAndTools(...)
136+
... := pme.InstallPlatform(...)
137+
... := pme.InstallPlatformInDirectory(...)
138+
... := pme.RunPostInstallScript(...)
139+
... := pme.IsManagedPlatformRelease(...)
140+
... := pme.UninstallPlatform(...)
141+
... := pme.InstallTool(...)
142+
... := pme.IsManagedToolRelease(...)
143+
... := pme.UninstallTool(...)
144+
... := pme.IsToolRequired(...)
145+
... := pme.LoadDiscoveries(...)
146+
... := pme.GetProfile(...)
147+
... := pme.GetEnvVarsForSpawnedProcess(...)
148+
... := pme.DiscoveryManager(...)
149+
... := pme.FindPlatformReleaseProvidingBoardsWithVidPid(...)
150+
... := pme.FindBoardsWithVidPid(...)
151+
... := pme.FindBoardsWithID(...)
152+
... := pme.FindBoardWithFQBN(...)
153+
... := pme.ResolveFQBN(...)
154+
... := pme.Package(...)
155+
... := pme.GetInstalledPlatformRelease(...)
156+
... := pme.GetAllInstalledToolsReleases(...)
157+
... := pme.InstalledPlatformReleases(...)
158+
... := pme.InstalledBoards(...)
159+
... := pme.FindToolsRequiredFromPlatformRelease(...)
160+
... := pme.GetTool(...)
161+
... := pme.FindToolsRequiredForBoard(...)
162+
... := pme.FindToolDependency(...)
163+
... := pme.FindDiscoveryDependency(...)
164+
... := pme.FindMonitorDependency(...)
165+
}
166+
```
167+
168+
The `Explorer` object keeps a read-lock on the underlying `PackageManager` that must be released once the task is done
169+
by calling the `release` callback function. This ensures that no other task will change the status of the
170+
`PackageManager` while the current task is in progress.
171+
172+
The `PackageManager.Clean()` method has been removed and replaced by the methods:
173+
174+
- `PackageManager.NewBuilder() (*Builder, commit func())`
175+
- `Builder.BuildIntoExistingPackageManager(target *PackageManager)`
176+
177+
Previously, to update a `PackageManager` instance we did:
178+
179+
```go
180+
func Reload(pm *packagemanager.PackageManager) {
181+
pm.Clear()
182+
... = pm.LoadHardware(...)
183+
// ...other pm.Load* calls...
184+
}
185+
```
186+
187+
now we have two options:
188+
189+
```go
190+
func Reload(pm *packagemanager.PackageManager) {
191+
// Create a new builder and build a package manager
192+
pmb := packagemanager.NewBuilder(.../* config params */)
193+
... = pmb.LoadHardware(...)
194+
// ...other pmb.Load* calls...
195+
196+
// apply the changes to the original pm
197+
pmb.BuildIntoExistingPackageManager(pm)
198+
}
199+
```
200+
201+
in this case, we create a new `Builder` with the given config params and once the package manager is built we apply the
202+
changes atomically with `BuildIntoExistingPackageManager`. This procedure may be even more simplified with:
203+
204+
```go
205+
func Reload(pm *packagemanager.PackageManager) {
206+
// Create a new builder using the same config params
207+
// as the original package manager
208+
pmb, commit := pm.NewBuilder()
209+
210+
// build the new package manager
211+
... = pmb.LoadHardware(...)
212+
// ...other pmb.Load* calls...
213+
214+
// apply the changes to the original pm
215+
commit()
216+
}
217+
```
218+
219+
In this case, we don't even need to bother to provide the configuration parameters because they are taken from the
220+
previous `PackageManager` instance.
221+
222+
### Some gRPC-mapped methods now accepts the gRPC request instead of the instance ID as parameter
223+
224+
The following methods in subpackages of `github.com/arduino/arduino-cli/commands/*`:
225+
226+
```go
227+
func Watch(instanceID int32) (<-chan *rpc.BoardListWatchResponse, func(), error) { ... }
228+
func LibraryUpgradeAll(instanceID int32, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { ... }
229+
func LibraryUpgrade(instanceID int32, libraryNames []string, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { ... }
230+
```
231+
232+
have been changed to:
233+
234+
```go
235+
func Watch(req *rpc.BoardListWatchRequest) (<-chan *rpc.BoardListWatchResponse, func(), error) { ... ]
236+
func LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { ... }
237+
func LibraryUpgrade(ctx context.Context, req *rpc.LibraryUpgradeRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { ... }
238+
```
239+
240+
The following methods in package `github.com/arduino/arduino-cli/commands`
241+
242+
```go
243+
func GetInstance(id int32) *CoreInstance { ... }
244+
func GetPackageManager(id int32) *packagemanager.PackageManager { ... }
245+
func GetLibraryManager(instanceID int32) *librariesmanager.LibrariesManager { ... }
246+
```
247+
248+
have been changed to:
249+
250+
```go
251+
func GetPackageManager(instance rpc.InstanceCommand) *packagemanager.PackageManager { ... } // Deprecated
252+
func GetPackageManagerExplorer(req rpc.InstanceCommand) (explorer *packagemanager.Explorer, release func()) { ... ]
253+
func GetLibraryManager(req rpc.InstanceCommand) *librariesmanager.LibrariesManager { ... }
254+
```
255+
256+
Old code using passing the `instanceID` inside the gRPC request must be changed to pass directly the whole gRPC request,
257+
for example:
258+
259+
```go
260+
eventsChan, closeWatcher, err := board.Watch(req.Instance.Id)
261+
```
262+
263+
must be changed to:
264+
265+
```go
266+
eventsChan, closeWatcher, err := board.Watch(req)
267+
```
268+
5269
## 0.26.0
6270
7271
### `github.com/arduino/arduino-cli/commands.DownloadToolRelease`, and `InstallToolRelease` functions have been removed

0 commit comments

Comments
 (0)