Skip to content

Commit a66fea9

Browse files
silvanocerzaper1234cmaglie
authored
[breaking] Refactor initialization steps (#1274)
* [breaking] Split rpc Init and remove Rescan function * [breaking] Refactored commands package to reflect gRPC changes * [breaking] Refactored cli package to reflect commands changes * Fix instance creation for CLI commands that update indexes * Fix unit tests * Change update indexes commands to not reload instance after * Fix installation of builtin tools * Fix integration tests * Fix code for linting * Update i18n files * Update UPGRADING.md with breaking changes * Update comment with correct information Co-authored-by: per1234 <[email protected]> * Using callback instead of channel+goroutine for Init * Enhance platform loading step * Update client_example to reflect new gRPC changes * Enhance Init docstring * Enhance builtin tools installation during Init * Fix unit test * Fix integration tests * [skip changelog] Fix after botched rebase * Fix issue when using Init to rescan installed core on already initialized instance * Update generated file from .proto Co-authored-by: per1234 <[email protected]> Co-authored-by: Cristian Maglie <[email protected]>
1 parent 3ae63cf commit a66fea9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+1771
-1462
lines changed

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

+174-136
Large diffs are not rendered by default.

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

+6
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ func NewPackageManager(indexDir, packagesDir, downloadDir, tempDir *paths.Path)
5858
}
5959
}
6060

61+
// Clear resets the PackageManager to its initial state
62+
func (pm *PackageManager) Clear() {
63+
pm.Packages = cores.NewPackages()
64+
pm.CustomGlobalProperties = properties.NewMap()
65+
}
66+
6167
// FindPlatformReleaseProvidingBoardsWithVidPid FIXMEDOC
6268
func (pm *PackageManager) FindPlatformReleaseProvidingBoardsWithVidPid(vid, pid string) []*cores.PlatformRelease {
6369
res := []*cores.PlatformRelease{}

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

+19-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,8 @@ func TestFindToolsRequiredForBoard(t *testing.T) {
228228
loadIndex("https://dl.espressif.com/dl/package_esp32_index.json")
229229
loadIndex("http://arduino.esp8266.com/stable/package_esp8266com_index.json")
230230
loadIndex("https://adafruit.github.io/arduino-board-index/package_adafruit_index.json")
231-
require.NoError(t, pm.LoadHardware())
231+
errs := pm.LoadHardware()
232+
require.Len(t, errs, 0)
232233
esp32, err := pm.FindBoardWithFQBN("esp32:esp32:esp32")
233234
require.NoError(t, err)
234235
esptool231 := pm.FindToolDependency(&cores.ToolDependency{
@@ -319,3 +320,20 @@ func TestIdentifyBoard(t *testing.T) {
319320
require.Equal(t, "[test:avr:e]", fmt.Sprintf("%v", identify("0xAB00", "0xcd00")))
320321
require.Equal(t, "[test:avr:e]", fmt.Sprintf("%v", identify("0xab00", "0xCD00")))
321322
}
323+
324+
func TestPackageManagerClear(t *testing.T) {
325+
// Create a PackageManager and load the harware
326+
packageManager := packagemanager.NewPackageManager(customHardware, customHardware, customHardware, customHardware)
327+
packageManager.LoadHardwareFromDirectory(customHardware)
328+
329+
// Creates another PackageManager but don't load the hardware
330+
emptyPackageManager := packagemanager.NewPackageManager(customHardware, customHardware, customHardware, customHardware)
331+
332+
// Verifies they're not equal
333+
require.NotEqual(t, &packageManager, &emptyPackageManager)
334+
335+
// Clear the first PackageManager that contains loaded hardware
336+
packageManager.Clear()
337+
// Verifies both PackageManagers are now equal
338+
require.Equal(t, &packageManager, &emptyPackageManager)
339+
}

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

+17-9
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727
"github.com/pmylund/sortutil"
2828
"github.com/sirupsen/logrus"
2929
semver "go.bug.st/relaxed-semver"
30+
"google.golang.org/grpc/codes"
31+
"google.golang.org/grpc/status"
3032
)
3133

3234
// LibrariesManager keeps the current status of the libraries in the system
@@ -160,13 +162,14 @@ func (lm *LibrariesManager) AddPlatformReleaseLibrariesDir(plaftormRelease *core
160162
}
161163

162164
// RescanLibraries reload all installed libraries in the system.
163-
func (lm *LibrariesManager) RescanLibraries() error {
165+
func (lm *LibrariesManager) RescanLibraries() []*status.Status {
166+
statuses := []*status.Status{}
164167
for _, dir := range lm.LibrariesDir {
165-
if err := lm.LoadLibrariesFromDir(dir); err != nil {
166-
return fmt.Errorf("loading libs from %s: %s", dir.Path, err)
168+
if errs := lm.LoadLibrariesFromDir(dir); len(errs) > 0 {
169+
statuses = append(statuses, errs...)
167170
}
168171
}
169-
return nil
172+
return statuses
170173
}
171174

172175
func (lm *LibrariesManager) getUserLibrariesDir() *paths.Path {
@@ -180,21 +183,25 @@ func (lm *LibrariesManager) getUserLibrariesDir() *paths.Path {
180183

181184
// LoadLibrariesFromDir loads all libraries in the given directory. Returns
182185
// nil if the directory doesn't exists.
183-
func (lm *LibrariesManager) LoadLibrariesFromDir(librariesDir *LibrariesDir) error {
186+
func (lm *LibrariesManager) LoadLibrariesFromDir(librariesDir *LibrariesDir) []*status.Status {
187+
statuses := []*status.Status{}
184188
subDirs, err := librariesDir.Path.ReadDir()
185189
if os.IsNotExist(err) {
186-
return nil
190+
return statuses
187191
}
188192
if err != nil {
189-
return fmt.Errorf("reading dir %s: %s", librariesDir.Path, err)
193+
s := status.Newf(codes.FailedPrecondition, "reading dir %s: %s", librariesDir.Path, err)
194+
return append(statuses, s)
190195
}
191196
subDirs.FilterDirs()
192197
subDirs.FilterOutHiddenFiles()
193198

194199
for _, subDir := range subDirs {
195200
library, err := libraries.Load(subDir, librariesDir.Location)
196201
if err != nil {
197-
return fmt.Errorf("loading library from %s: %s", subDir, err)
202+
s := status.Newf(codes.Internal, "loading library from %s: %s", subDir, err)
203+
statuses = append(statuses, s)
204+
continue
198205
}
199206
library.ContainerPlatform = librariesDir.PlatformRelease
200207
alternatives, ok := lm.Libraries[library.Name]
@@ -204,7 +211,8 @@ func (lm *LibrariesManager) LoadLibrariesFromDir(librariesDir *LibrariesDir) err
204211
}
205212
alternatives.Add(library)
206213
}
207-
return nil
214+
215+
return statuses
208216
}
209217

210218
// LoadLibraryFromDir loads one single library from the libRootDir.

Diff for: cli/board/attach.go

+2-6
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,7 @@ var attachFlags struct {
5151
}
5252

5353
func runAttachCommand(cmd *cobra.Command, args []string) {
54-
instance, err := instance.CreateInstance()
55-
if err != nil {
56-
feedback.Errorf("Attach board error: %v", err)
57-
os.Exit(errorcodes.ErrGeneric)
58-
}
54+
instance := instance.CreateAndInit()
5955

6056
var path *paths.Path
6157
if len(args) > 1 {
@@ -64,7 +60,7 @@ func runAttachCommand(cmd *cobra.Command, args []string) {
6460
path = initSketchPath(path)
6561
}
6662

67-
if _, err = board.Attach(context.Background(), &rpc.BoardAttachRequest{
63+
if _, err := board.Attach(context.Background(), &rpc.BoardAttachRequest{
6864
Instance: instance,
6965
BoardUri: args[0],
7066
SketchPath: path.String(),

Diff for: cli/board/details.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,7 @@ func initDetailsCommand() *cobra.Command {
5555
}
5656

5757
func runDetailsCommand(cmd *cobra.Command, args []string) {
58-
inst, err := instance.CreateInstance()
59-
if err != nil {
60-
feedback.Errorf(tr("Error getting board details: %v"), err)
61-
os.Exit(errorcodes.ErrGeneric)
62-
}
58+
inst := instance.CreateAndInit()
6359

6460
// remove once `board details <fqbn>` is removed
6561
if fqbn == "" && len(args) > 0 {

Diff for: cli/board/list.go

+2-11
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,7 @@ var listFlags struct {
5757
// runListCommand detects and lists the connected arduino boards
5858
func runListCommand(cmd *cobra.Command, args []string) {
5959
if listFlags.watch {
60-
inst, err := instance.CreateInstance()
61-
if err != nil {
62-
feedback.Errorf("Error detecting boards: %v", err)
63-
os.Exit(errorcodes.ErrGeneric)
64-
}
60+
inst := instance.CreateAndInit()
6561
watchList(cmd, inst)
6662
os.Exit(0)
6763
}
@@ -73,12 +69,7 @@ func runListCommand(cmd *cobra.Command, args []string) {
7369
time.Sleep(timeout)
7470
}
7571

76-
inst, err := instance.CreateInstance()
77-
if err != nil {
78-
feedback.Errorf("Error detecting boards: %v", err)
79-
os.Exit(errorcodes.ErrGeneric)
80-
}
81-
72+
inst := instance.CreateAndInit()
8273
ports, err := board.List(inst.GetId())
8374
if err != nil {
8475
feedback.Errorf("Error detecting boards: %v", err)

Diff for: cli/board/listall.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,7 @@ var showHiddenBoard bool
5050

5151
// runListAllCommand list all installed boards
5252
func runListAllCommand(cmd *cobra.Command, args []string) {
53-
inst, err := instance.CreateInstance()
54-
if err != nil {
55-
feedback.Errorf("Error listing boards: %v", err)
56-
os.Exit(errorcodes.ErrGeneric)
57-
}
53+
inst := instance.CreateAndInit()
5854

5955
list, err := board.ListAll(context.Background(), &rpc.BoardListAllRequest{
6056
Instance: inst,

Diff for: cli/board/search.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ var searchFlags struct {
5252
}
5353

5454
func runSearchCommand(cmd *cobra.Command, args []string) {
55-
inst, err := instance.CreateInstance()
56-
if err != nil {
57-
feedback.Errorf("Error searching boards: %v", err)
58-
os.Exit(errorcodes.ErrGeneric)
59-
}
55+
inst := instance.CreateAndInit()
6056

6157
res, err := board.Search(context.Background(), &rpc.BoardSearchRequest{
6258
Instance: inst,

Diff for: cli/burnbootloader/burnbootloader.go

+6-29
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,15 @@ import (
2424
"github.com/arduino/arduino-cli/cli/instance"
2525
"github.com/arduino/arduino-cli/commands/upload"
2626
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
27-
"github.com/arduino/go-paths-helper"
28-
"github.com/sirupsen/logrus"
2927
"github.com/spf13/cobra"
3028
)
3129

3230
var (
33-
fqbn string
34-
port string
35-
verbose bool
36-
verify bool
37-
importDir string
38-
programmer string
39-
burnBootloader bool
31+
fqbn string
32+
port string
33+
verbose bool
34+
verify bool
35+
programmer string
4036
)
4137

4238
// NewCommand created a new `burn-bootloader` command
@@ -60,11 +56,7 @@ func NewCommand() *cobra.Command {
6056
}
6157

6258
func run(command *cobra.Command, args []string) {
63-
instance, err := instance.CreateInstance()
64-
if err != nil {
65-
feedback.Errorf("Error during Upload: %v", err)
66-
os.Exit(errorcodes.ErrGeneric)
67-
}
59+
instance := instance.CreateAndInit()
6860

6961
if _, err := upload.BurnBootloader(context.Background(), &rpc.BurnBootloaderRequest{
7062
Instance: instance,
@@ -79,18 +71,3 @@ func run(command *cobra.Command, args []string) {
7971
}
8072
os.Exit(0)
8173
}
82-
83-
// initSketchPath returns the current working directory
84-
func initSketchPath(sketchPath *paths.Path) *paths.Path {
85-
if sketchPath != nil {
86-
return sketchPath
87-
}
88-
89-
wd, err := paths.Getwd()
90-
if err != nil {
91-
feedback.Errorf("Couldn't get current working directory: %v", err)
92-
os.Exit(errorcodes.ErrGeneric)
93-
}
94-
logrus.Infof("Reading sketch from dir: %s", wd)
95-
return wd
96-
}

Diff for: cli/compile/compile.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,7 @@ func NewCommand() *cobra.Command {
120120
}
121121

122122
func run(cmd *cobra.Command, args []string) {
123-
inst, err := instance.CreateInstance()
124-
if err != nil {
125-
feedback.Errorf("Error creating instance: %v", err)
126-
os.Exit(errorcodes.ErrGeneric)
127-
}
123+
inst := instance.CreateAndInit()
128124

129125
var path *paths.Path
130126
if len(args) > 0 {
@@ -183,6 +179,7 @@ func run(cmd *cobra.Command, args []string) {
183179
compileErr := new(bytes.Buffer)
184180
verboseCompile := configuration.Settings.GetString("logging.level") == "debug"
185181
var compileRes *rpc.CompileResponse
182+
var err error
186183
if output.OutputFormat == "json" {
187184
compileRes, err = compile.Compile(context.Background(), compileRequest, compileOut, compileErr, verboseCompile)
188185
} else {

Diff for: cli/core/download.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,7 @@ func initDownloadCommand() *cobra.Command {
4545
}
4646

4747
func runDownloadCommand(cmd *cobra.Command, args []string) {
48-
inst, err := instance.CreateInstance()
49-
if err != nil {
50-
feedback.Errorf("Error downloading: %v", err)
51-
os.Exit(errorcodes.ErrGeneric)
52-
}
48+
inst := instance.CreateAndInit()
5349

5450
logrus.Info("Executing `arduino core download`")
5551

Diff for: cli/core/install.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,7 @@ func DetectSkipPostInstallValue() bool {
8383
}
8484

8585
func runInstallCommand(cmd *cobra.Command, args []string) {
86-
inst, err := instance.CreateInstance()
87-
if err != nil {
88-
feedback.Errorf("Error installing: %v", err)
89-
os.Exit(errorcodes.ErrGeneric)
90-
}
91-
86+
inst := instance.CreateAndInit()
9287
logrus.Info("Executing `arduino core install`")
9388

9489
platformsRefs, err := globals.ParseReferenceArgs(args, true)

Diff for: cli/core/list.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,7 @@ var listFlags struct {
4949
}
5050

5151
func runListCommand(cmd *cobra.Command, args []string) {
52-
inst, err := instance.CreateInstance()
53-
if err != nil {
54-
feedback.Errorf("Error listing platforms: %v", err)
55-
os.Exit(errorcodes.ErrGeneric)
56-
}
57-
52+
inst := instance.CreateAndInit()
5853
logrus.Info("Executing `arduino core list`")
5954

6055
platforms, err := core.GetPlatforms(&rpc.PlatformListRequest{

Diff for: cli/core/search.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ func initSearchCommand() *cobra.Command {
6161
const indexUpdateInterval = "24h"
6262

6363
func runSearchCommand(cmd *cobra.Command, args []string) {
64-
inst, err := instance.CreateInstance()
65-
if err != nil {
66-
feedback.Errorf("Error searching for platforms: %v", err)
64+
inst, status := instance.Create()
65+
if status != nil {
66+
feedback.Errorf("Error creating instance: %v", status)
6767
os.Exit(errorcodes.ErrGeneric)
6868
}
6969

7070
if indexesNeedUpdating(indexUpdateInterval) {
71-
_, err = commands.UpdateIndex(context.Background(), &rpc.UpdateIndexRequest{
71+
_, err := commands.UpdateIndex(context.Background(), &rpc.UpdateIndexRequest{
7272
Instance: inst,
7373
}, output.ProgressBar())
7474
if err != nil {
@@ -77,6 +77,10 @@ func runSearchCommand(cmd *cobra.Command, args []string) {
7777
}
7878
}
7979

80+
for _, err := range instance.Init(inst) {
81+
feedback.Errorf("Error initializing instance: %v", err)
82+
}
83+
8084
arguments := strings.ToLower(strings.Join(args, " "))
8185
logrus.Infof("Executing `arduino core search` with args: '%s'", arguments)
8286

Diff for: cli/core/uninstall.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,7 @@ func initUninstallCommand() *cobra.Command {
4242
}
4343

4444
func runUninstallCommand(cmd *cobra.Command, args []string) {
45-
inst, err := instance.CreateInstance()
46-
if err != nil {
47-
feedback.Errorf("Error uninstalling: %v", err)
48-
os.Exit(errorcodes.ErrGeneric)
49-
}
50-
45+
inst := instance.CreateAndInit()
5146
logrus.Info("Executing `arduino core uninstall`")
5247

5348
platformsRefs, err := globals.ParseReferenceArgs(args, true)

Diff for: cli/core/update_index.go

+19-2
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,28 @@ func initUpdateIndexCommand() *cobra.Command {
4242
}
4343

4444
func runUpdateIndexCommand(cmd *cobra.Command, args []string) {
45-
instance := instance.CreateInstanceIgnorePlatformIndexErrors()
4645
logrus.Info("Executing `arduino core update-index`")
46+
// We don't initialize any CoreInstance when updating indexes since we don't need to.
47+
// Also meaningless errors might be returned when calling this command with --additional-urls
48+
// since the CLI would be searching for a corresponding file for the additional urls set
49+
// as argument but none would be obviously found.
50+
inst, status := instance.Create()
51+
if status != nil {
52+
feedback.Errorf("Error creating instance: %v", status)
53+
os.Exit(errorcodes.ErrGeneric)
54+
}
55+
56+
// In case this is the first time the CLI is run we need to update indexes
57+
// to make it work correctly, we must do this explicitly in this command since
58+
// we must use instance.Create instead of instance.CreateAndInit for the
59+
// reason stated above.
60+
if err := instance.FirstUpdate(inst); err != nil {
61+
feedback.Errorf("Error updating indexes: %v", status)
62+
os.Exit(errorcodes.ErrGeneric)
63+
}
4764

4865
_, err := commands.UpdateIndex(context.Background(), &rpc.UpdateIndexRequest{
49-
Instance: instance,
66+
Instance: inst,
5067
}, output.ProgressBar())
5168
if err != nil {
5269
feedback.Errorf("Error updating index: %v", err)

0 commit comments

Comments
 (0)