diff --git a/cli/board/attach.go b/cli/board/attach.go index 76b611d1183..7a097cc77be 100644 --- a/cli/board/attach.go +++ b/cli/board/attach.go @@ -53,7 +53,11 @@ var attachFlags struct { } func runAttachCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + instance, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Attach board error: %v", err) + os.Exit(errorcodes.ErrGeneric) + } var path *paths.Path if len(args) > 1 { @@ -62,13 +66,12 @@ func runAttachCommand(cmd *cobra.Command, args []string) { path = initSketchPath(path) } - _, err := board.Attach(context.Background(), &rpc.BoardAttachReq{ + if _, err = board.Attach(context.Background(), &rpc.BoardAttachReq{ Instance: instance, BoardUri: args[0], SketchPath: path.String(), SearchTimeout: attachFlags.searchTimeout, - }, output.TaskProgress()) - if err != nil { + }, output.TaskProgress()); err != nil { feedback.Errorf("Attach board error: %v", err) os.Exit(errorcodes.ErrGeneric) } diff --git a/cli/board/details.go b/cli/board/details.go index f34e9b7a6db..18696a68eab 100644 --- a/cli/board/details.go +++ b/cli/board/details.go @@ -41,8 +41,14 @@ var detailsCommand = &cobra.Command{ } func runDetailsCommand(cmd *cobra.Command, args []string) { + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error getting board details: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + res, err := board.Details(context.Background(), &rpc.BoardDetailsReq{ - Instance: instance.CreateInstance(), + Instance: inst, Fqbn: args[0], }) diff --git a/cli/board/list.go b/cli/board/list.go index a8f73929cf8..4c38cee869a 100644 --- a/cli/board/list.go +++ b/cli/board/list.go @@ -61,7 +61,13 @@ func runListCommand(cmd *cobra.Command, args []string) { time.Sleep(timeout) } - ports, err := board.List(instance.CreateInstance().GetId()) + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error detecting boards: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + + ports, err := board.List(inst.GetId()) if err != nil { feedback.Errorf("Error detecting boards: %v", err) os.Exit(errorcodes.ErrNetwork) diff --git a/cli/board/listall.go b/cli/board/listall.go index 47472a69cc6..4b1b4886413 100644 --- a/cli/board/listall.go +++ b/cli/board/listall.go @@ -46,10 +46,14 @@ var listAllCommand = &cobra.Command{ // runListAllCommand list all installed boards func runListAllCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error listing boards: %v", err) + os.Exit(errorcodes.ErrGeneric) + } list, err := board.ListAll(context.Background(), &rpc.BoardListAllReq{ - Instance: instance, + Instance: inst, SearchArgs: args, }) if err != nil { diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 311545db64b..84514062e60 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -86,7 +86,11 @@ func NewCommand() *cobra.Command { } func run(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error during build: %v", err) + os.Exit(errorcodes.ErrGeneric) + } var path *paths.Path if len(args) > 0 { @@ -95,8 +99,8 @@ func run(cmd *cobra.Command, args []string) { sketchPath := initSketchPath(path) - _, err := compile.Compile(context.Background(), &rpc.CompileReq{ - Instance: instance, + _, err = compile.Compile(context.Background(), &rpc.CompileReq{ + Instance: inst, Fqbn: fqbn, SketchPath: sketchPath.String(), ShowProperties: showProperties, @@ -118,7 +122,7 @@ func run(cmd *cobra.Command, args []string) { if uploadAfterCompile { _, err := upload.Upload(context.Background(), &rpc.UploadReq{ - Instance: instance, + Instance: inst, Fqbn: fqbn, SketchPath: sketchPath.String(), Port: port, diff --git a/cli/core/download.go b/cli/core/download.go index 22d00875689..becb6df1bca 100644 --- a/cli/core/download.go +++ b/cli/core/download.go @@ -47,7 +47,12 @@ func initDownloadCommand() *cobra.Command { } func runDownloadCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error downloading: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + logrus.Info("Executing `arduino core download`") platformsRefs, err := globals.ParseReferenceArgs(args, true) @@ -58,7 +63,7 @@ func runDownloadCommand(cmd *cobra.Command, args []string) { for i, platformRef := range platformsRefs { platformDownloadreq := &rpc.PlatformDownloadReq{ - Instance: instance, + Instance: inst, PlatformPackage: platformRef.PackageName, Architecture: platformRef.Architecture, Version: platformRef.Version, diff --git a/cli/core/install.go b/cli/core/install.go index cc0135a0fa3..985c445b180 100644 --- a/cli/core/install.go +++ b/cli/core/install.go @@ -48,7 +48,12 @@ func initInstallCommand() *cobra.Command { } func runInstallCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error installing: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + logrus.Info("Executing `arduino core install`") platformsRefs, err := globals.ParseReferenceArgs(args, true) @@ -59,7 +64,7 @@ func runInstallCommand(cmd *cobra.Command, args []string) { for _, platformRef := range platformsRefs { plattformInstallReq := &rpc.PlatformInstallReq{ - Instance: instance, + Instance: inst, PlatformPackage: platformRef.PackageName, Architecture: platformRef.Architecture, Version: platformRef.Version, diff --git a/cli/core/list.go b/cli/core/list.go index c85fa4b290c..117d200a787 100644 --- a/cli/core/list.go +++ b/cli/core/list.go @@ -49,10 +49,15 @@ var listFlags struct { } func runListCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error listing platforms: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + logrus.Info("Executing `arduino core list`") - platforms, err := core.GetPlatforms(instance.Id, listFlags.updatableOnly) + platforms, err := core.GetPlatforms(inst.Id, listFlags.updatableOnly) if err != nil { feedback.Errorf("Error listing platforms: %v", err) os.Exit(errorcodes.ErrGeneric) diff --git a/cli/core/search.go b/cli/core/search.go index f31a7eddb1f..8711a5ac00e 100644 --- a/cli/core/search.go +++ b/cli/core/search.go @@ -51,11 +51,16 @@ func initSearchCommand() *cobra.Command { } func runSearchCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error saerching for platforms: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + logrus.Info("Executing `arduino core search`") arguments := strings.ToLower(strings.Join(args, " ")) - resp, err := core.PlatformSearch(instance.GetId(), arguments, allVersions) + resp, err := core.PlatformSearch(inst.GetId(), arguments, allVersions) if err != nil { feedback.Errorf("Error saerching for platforms: %v", err) os.Exit(errorcodes.ErrGeneric) diff --git a/cli/core/uninstall.go b/cli/core/uninstall.go index 05fcaf60a9e..dcfaa638b62 100644 --- a/cli/core/uninstall.go +++ b/cli/core/uninstall.go @@ -44,7 +44,12 @@ func initUninstallCommand() *cobra.Command { } func runUninstallCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error uninstalling: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + logrus.Info("Executing `arduino core uninstall`") platformsRefs, err := globals.ParseReferenceArgs(args, true) @@ -61,7 +66,7 @@ func runUninstallCommand(cmd *cobra.Command, args []string) { } for _, platformRef := range platformsRefs { _, err := core.PlatformUninstall(context.Background(), &rpc.PlatformUninstallReq{ - Instance: instance, + Instance: inst, PlatformPackage: platformRef.PackageName, Architecture: platformRef.Architecture, }, output.NewTaskProgressCB()) diff --git a/cli/core/update_index.go b/cli/core/update_index.go index cd0f4c80444..11bef2bef4f 100644 --- a/cli/core/update_index.go +++ b/cli/core/update_index.go @@ -44,7 +44,7 @@ func initUpdateIndexCommand() *cobra.Command { } func runUpdateIndexCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() logrus.Info("Executing `arduino core update-index`") _, err := commands.UpdateIndex(context.Background(), &rpc.UpdateIndexReq{ diff --git a/cli/core/upgrade.go b/cli/core/upgrade.go index 5bee93f1441..ef7e9fa804f 100644 --- a/cli/core/upgrade.go +++ b/cli/core/upgrade.go @@ -48,12 +48,17 @@ func initUpgradeCommand() *cobra.Command { } func runUpgradeCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstance() + inst, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error upgrading: %v", err) + os.Exit(errorcodes.ErrGeneric) + } + logrus.Info("Executing `arduino core upgrade`") // if no platform was passed, upgrade allthethings if len(args) == 0 { - targets, err := core.GetPlatforms(instance.Id, true) + targets, err := core.GetPlatforms(inst.Id, true) if err != nil { feedback.Errorf("Error retrieving core list: %v", err) os.Exit(errorcodes.ErrGeneric) @@ -85,7 +90,7 @@ func runUpgradeCommand(cmd *cobra.Command, args []string) { } r := &rpc.PlatformUpgradeReq{ - Instance: instance, + Instance: inst, PlatformPackage: platformRef.PackageName, Architecture: platformRef.Architecture, } diff --git a/cli/instance/instance.go b/cli/instance/instance.go index 422d8bd1e24..37923b1638f 100644 --- a/cli/instance/instance.go +++ b/cli/instance/instance.go @@ -1,77 +1,100 @@ +// This file is part of arduino-cli. +// +// Copyright 2019 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + package instance import ( "context" - "os" - "github.com/arduino/arduino-cli/cli/errorcodes" - "github.com/arduino/arduino-cli/cli/feedback" "github.com/arduino/arduino-cli/cli/globals" "github.com/arduino/arduino-cli/cli/output" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/commands" + "github.com/pkg/errors" "github.com/sirupsen/logrus" - "github.com/spf13/viper" ) -// CreateInstaceIgnorePlatformIndexErrors creates and return an instance of the +// CreateInstanceIgnorePlatformIndexErrors creates and return an instance of the // Arduino Core Engine, but won't stop on platforms index loading errors. -func CreateInstaceIgnorePlatformIndexErrors() *rpc.Instance { - return initInstance().GetInstance() +func CreateInstanceIgnorePlatformIndexErrors() *rpc.Instance { + i, _ := getInitResponse() + return i.GetInstance() } // CreateInstance creates and return an instance of the Arduino Core engine -func CreateInstance() *rpc.Instance { - resp := initInstance() - if resp.GetPlatformsIndexErrors() != nil { - for _, err := range resp.GetPlatformsIndexErrors() { - feedback.Errorf("Error loading index: %v", err) - } - feedback.Errorf("Launch '%s core update-index' to fix or download indexes.", os.Args[0]) - os.Exit(errorcodes.ErrGeneric) +func CreateInstance() (*rpc.Instance, error) { + resp, err := getInitResponse() + if err != nil { + return nil, err } - return resp.GetInstance() + + return resp.GetInstance(), checkPlatformErrors(resp) } -func initInstance() *rpc.InitResp { - logrus.Info("Initializing package manager") - req := packageManagerInitReq() +func getInitResponse() (*rpc.InitResp, error) { + // invoke Init() + resp, err := commands.Init(context.Background(), &rpc.InitReq{}, + output.ProgressBar(), output.TaskProgress(), globals.NewHTTPClientHeader()) - resp, err := commands.Init(context.Background(), req, output.ProgressBar(), output.TaskProgress(), globals.NewHTTPClientHeader()) + // Init() failed if err != nil { - feedback.Errorf("Error initializing package manager: %v", err) - os.Exit(errorcodes.ErrGeneric) + return nil, errors.Wrap(err, "creating instance") } + + // Init() succeeded but there were errors loading library indexes, + // let's rescan and try again if resp.GetLibrariesIndexError() != "" { - commands.UpdateLibrariesIndex(context.Background(), + logrus.Warnf("There were errors loading the library index, trying again...") + + // update all indexes + err := commands.UpdateLibrariesIndex(context.Background(), &rpc.UpdateLibrariesIndexReq{Instance: resp.GetInstance()}, output.ProgressBar()) - rescResp, err := commands.Rescan(resp.GetInstance().GetId()) - if rescResp.GetLibrariesIndexError() != "" { - feedback.Errorf("Error loading library index: %v", rescResp.GetLibrariesIndexError()) - os.Exit(errorcodes.ErrGeneric) + if err != nil { + return nil, errors.Wrap(err, "updating the library index") } + + // rescan libraries + rescanResp, err := commands.Rescan(resp.GetInstance().GetId()) if err != nil { - feedback.Errorf("Error loading library index: %v", err) - os.Exit(errorcodes.ErrGeneric) + return nil, errors.Wrap(err, "during rescan") } - resp.LibrariesIndexError = rescResp.LibrariesIndexError - resp.PlatformsIndexErrors = rescResp.PlatformsIndexErrors - } - return resp -} -func packageManagerInitReq() *rpc.InitReq { - urls := []string{globals.DefaultIndexURL} + // errors persist + if rescanResp.GetLibrariesIndexError() != "" { + return nil, errors.New("still errors after rescan: " + rescanResp.GetLibrariesIndexError()) + } - for _, URL := range viper.GetStringSlice("board_manager.additional_urls") { - urls = append(urls, URL) + // succeeded, copy over PlatformsIndexErrors in case errors occurred + // during rescan + resp.LibrariesIndexError = "" + resp.PlatformsIndexErrors = rescanResp.PlatformsIndexErrors } - conf := &rpc.Configuration{} - conf.DataDir = viper.GetString("directories.Data") - conf.DownloadsDir = viper.GetString("directories.Downloads") - conf.BoardManagerAdditionalUrls = urls - conf.SketchbookDir = viper.GetString("directories.User") + return resp, nil +} + +func checkPlatformErrors(resp *rpc.InitResp) error { + // Init() and/or rescan succeeded, but there were errors loading platform indexes + if resp.GetPlatformsIndexErrors() != nil { + // log each error + for _, err := range resp.GetPlatformsIndexErrors() { + logrus.Errorf("Error loading platform index: %v", err) + } + // return + return errors.New("There were errors loading platform indexes") + } - return &rpc.InitReq{Configuration: conf} + return nil } diff --git a/cli/lib/check_deps.go b/cli/lib/check_deps.go index c0570f36ee3..7e9bf9575c2 100644 --- a/cli/lib/check_deps.go +++ b/cli/lib/check_deps.go @@ -53,7 +53,7 @@ func runDepsCommand(cmd *cobra.Command, args []string) { os.Exit(errorcodes.ErrBadArgument) } - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() deps, err := lib.LibraryResolveDependencies(context.Background(), &rpc.LibraryResolveDependenciesReq{ Instance: instance, Name: libRef.Name, diff --git a/cli/lib/download.go b/cli/lib/download.go index 56cf64ff17a..3e2fb7b8fc6 100644 --- a/cli/lib/download.go +++ b/cli/lib/download.go @@ -46,7 +46,7 @@ func initDownloadCommand() *cobra.Command { } func runDownloadCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() refs, err := globals.ParseLibraryReferenceArgs(args) if err != nil { feedback.Errorf("Invalid argument passed: %v", err) diff --git a/cli/lib/install.go b/cli/lib/install.go index 044ee4425ab..3f41db71cf9 100644 --- a/cli/lib/install.go +++ b/cli/lib/install.go @@ -51,7 +51,7 @@ var installFlags struct { } func runInstallCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() libRefs, err := globals.ParseLibraryReferenceArgs(args) if err != nil { feedback.Errorf("Arguments error: %v", err) diff --git a/cli/lib/list.go b/cli/lib/list.go index 0454d2cd15a..c701ecd6fcf 100644 --- a/cli/lib/list.go +++ b/cli/lib/list.go @@ -51,7 +51,7 @@ var listFlags struct { } func runListCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() logrus.Info("Listing") res, err := lib.LibraryList(context.Background(), &rpc.LibraryListReq{ diff --git a/cli/lib/search.go b/cli/lib/search.go index 5c47df9019d..b3e472b8c64 100644 --- a/cli/lib/search.go +++ b/cli/lib/search.go @@ -52,7 +52,7 @@ var searchFlags struct { } func runSearchCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() logrus.Info("Executing `arduino lib search`") searchResp, err := lib.LibrarySearch(context.Background(), &rpc.LibrarySearchReq{ Instance: instance, diff --git a/cli/lib/uninstall.go b/cli/lib/uninstall.go index cabe9743870..b2f90571277 100644 --- a/cli/lib/uninstall.go +++ b/cli/lib/uninstall.go @@ -47,7 +47,7 @@ func initUninstallCommand() *cobra.Command { func runUninstallCommand(cmd *cobra.Command, args []string) { logrus.Info("Executing `arduino lib uninstall`") - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() refs, err := globals.ParseLibraryReferenceArgs(args) if err != nil { feedback.Errorf("Invalid argument passed: %v", err) diff --git a/cli/lib/update_index.go b/cli/lib/update_index.go index 9301a14db1e..317094e5cd8 100644 --- a/cli/lib/update_index.go +++ b/cli/lib/update_index.go @@ -38,7 +38,7 @@ func initUpdateIndexCommand() *cobra.Command { Example: " " + os.Args[0] + " lib update-index", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() err := commands.UpdateLibrariesIndex(context.Background(), &rpc.UpdateLibrariesIndexReq{ Instance: instance, }, output.ProgressBar()) diff --git a/cli/lib/upgrade.go b/cli/lib/upgrade.go index 06ef2a73abe..743d546b305 100644 --- a/cli/lib/upgrade.go +++ b/cli/lib/upgrade.go @@ -47,7 +47,7 @@ func initUpgradeCommand() *cobra.Command { } func runUpgradeCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateInstaceIgnorePlatformIndexErrors() + instance := instance.CreateInstanceIgnorePlatformIndexErrors() if len(args) == 0 { err := lib.LibraryUpgradeAll(instance.Id, output.ProgressBar(), output.TaskProgress(), globals.NewHTTPClientHeader()) diff --git a/cli/upload/upload.go b/cli/upload/upload.go index f2609111355..9e536deba82 100644 --- a/cli/upload/upload.go +++ b/cli/upload/upload.go @@ -63,7 +63,11 @@ func NewCommand() *cobra.Command { } func run(command *cobra.Command, args []string) { - instance := instance.CreateInstance() + instance, err := instance.CreateInstance() + if err != nil { + feedback.Errorf("Error during Upload: %v", err) + os.Exit(errorcodes.ErrGeneric) + } var path *paths.Path if len(args) > 0 { @@ -71,7 +75,7 @@ func run(command *cobra.Command, args []string) { } sketchPath := initSketchPath(path) - _, err := upload.Upload(context.Background(), &rpc.UploadReq{ + if _, err := upload.Upload(context.Background(), &rpc.UploadReq{ Instance: instance, Fqbn: fqbn, SketchPath: sketchPath.String(), @@ -79,9 +83,7 @@ func run(command *cobra.Command, args []string) { Verbose: verbose, Verify: verify, ImportFile: importFile, - }, os.Stdout, os.Stderr) - - if err != nil { + }, os.Stdout, os.Stderr); err != nil { feedback.Errorf("Error during Upload: %v", err) os.Exit(errorcodes.ErrGeneric) } diff --git a/commands/instances.go b/commands/instances.go index 1ffb035f145..90c4d085beb 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -59,6 +59,13 @@ type InstanceContainer interface { GetInstance() *rpc.Instance } +type createInstanceResult struct { + Pm *packagemanager.PackageManager + Lm *librariesmanager.LibrariesManager + PlatformIndexErrors []string + LibrariesIndexError string +} + // GetInstance returns a CoreInstance for the given ID, or nil if ID // doesn't exist func GetInstance(id int32) *CoreInstance { @@ -125,20 +132,19 @@ func (instance *CoreInstance) checkForBuiltinTools(downloadCB DownloadProgressCB } // Init FIXMEDOC -func Init(ctx context.Context, req *rpc.InitReq, downloadCB DownloadProgressCB, taskCB TaskProgressCB, downloaderHeaders http.Header) (*rpc.InitResp, error) { - inConfig := req.GetConfiguration() - if inConfig == nil { - return nil, fmt.Errorf("invalid request") - } +func Init(ctx context.Context, req *rpc.InitReq, downloadCB DownloadProgressCB, taskCB TaskProgressCB, + downloaderHeaders http.Header) (*rpc.InitResp, error) { - pm, lm, reqPltIndex, reqLibIndex, err := createInstance(ctx, req.GetLibraryManagerOnly()) + res, err := createInstance(ctx, req.GetLibraryManagerOnly()) if err != nil { return nil, fmt.Errorf("cannot initialize package manager: %s", err) } + instance := &CoreInstance{ - PackageManager: pm, - lm: lm, - getLibOnly: req.GetLibraryManagerOnly()} + PackageManager: res.Pm, + lm: res.Lm, + getLibOnly: req.GetLibraryManagerOnly(), + } handle := instancesCount instancesCount++ instances[handle] = instance @@ -150,8 +156,8 @@ func Init(ctx context.Context, req *rpc.InitReq, downloadCB DownloadProgressCB, return &rpc.InitResp{ Instance: &rpc.Instance{Id: handle}, - PlatformsIndexErrors: reqPltIndex, - LibrariesIndexError: reqLibIndex, + PlatformsIndexErrors: res.PlatformIndexErrors, + LibrariesIndexError: res.LibrariesIndexError, }, nil } @@ -252,88 +258,103 @@ func Rescan(instanceID int32) (*rpc.RescanResp, error) { return nil, fmt.Errorf("invalid handle") } - pm, lm, reqPltIndex, reqLibIndex, err := createInstance(context.Background(), coreInstance.getLibOnly) + res, err := createInstance(context.Background(), coreInstance.getLibOnly) if err != nil { return nil, fmt.Errorf("rescanning filesystem: %s", err) } - coreInstance.PackageManager = pm - coreInstance.lm = lm + coreInstance.PackageManager = res.Pm + coreInstance.lm = res.Lm return &rpc.RescanResp{ - PlatformsIndexErrors: reqPltIndex, - LibrariesIndexError: reqLibIndex, + PlatformsIndexErrors: res.PlatformIndexErrors, + LibrariesIndexError: res.LibrariesIndexError, }, nil } -func createInstance(ctx context.Context, getLibOnly bool) ( - *packagemanager.PackageManager, *librariesmanager.LibrariesManager, []string, string, error) { - var pm *packagemanager.PackageManager - platformIndexErrors := []string{} - dataDir := paths.New(viper.GetString("directories.Data")) +func createInstance(ctx context.Context, getLibOnly bool) (*createInstanceResult, error) { + res := &createInstanceResult{} + + // setup downloads directory downloadsDir := paths.New(viper.GetString("directories.Downloads")) + if downloadsDir.NotExist() { + err := downloadsDir.MkdirAll() + if err != nil { + return nil, err + } + } + + // setup data directory + dataDir := paths.New(viper.GetString("directories.Data")) + packagesDir := configuration.PackagesDir() + if packagesDir.NotExist() { + err := packagesDir.MkdirAll() + if err != nil { + return nil, err + } + } + if !getLibOnly { - pm = packagemanager.NewPackageManager( - dataDir, - configuration.PackagesDir(), - downloadsDir, - dataDir.Join("tmp")) + res.Pm = packagemanager.NewPackageManager(dataDir, configuration.PackagesDir(), + downloadsDir, dataDir.Join("tmp")) urls := []string{globals.DefaultIndexURL} urls = append(urls, viper.GetStringSlice("board_manager.additional_urls")...) for _, u := range urls { URL, err := url.Parse(u) if err != nil { - logrus.Warnf("unable to parse additional URL: %s", u) + logrus.Warnf("Unable to parse index URL: %s, skip...", u) continue } - if err := pm.LoadPackageIndex(URL); err != nil { - platformIndexErrors = append(platformIndexErrors, err.Error()) + + if err := res.Pm.LoadPackageIndex(URL); err != nil { + res.PlatformIndexErrors = append(res.PlatformIndexErrors, err.Error()) } } - if err := pm.LoadHardware(); err != nil { - return nil, nil, nil, "", fmt.Errorf("loading hardware packages: %s", err) + if err := res.Pm.LoadHardware(); err != nil { + return res, fmt.Errorf("error loading hardware packages: %s", err) } } - if len(platformIndexErrors) == 0 { - platformIndexErrors = nil + + if len(res.PlatformIndexErrors) == 0 { + res.PlatformIndexErrors = nil } // Initialize library manager // -------------------------- - lm := librariesmanager.NewLibraryManager(dataDir, downloadsDir) + res.Lm = librariesmanager.NewLibraryManager(dataDir, downloadsDir) // Add IDE builtin libraries dir if bundledLibsDir := configuration.IDEBundledLibrariesDir(); bundledLibsDir != nil { - lm.AddLibrariesDir(bundledLibsDir, libraries.IDEBuiltIn) + res.Lm.AddLibrariesDir(bundledLibsDir, libraries.IDEBuiltIn) } // Add user libraries dir libDir := configuration.LibrariesDir() - lm.AddLibrariesDir(libDir, libraries.User) + res.Lm.AddLibrariesDir(libDir, libraries.User) // Add libraries dirs from installed platforms - if pm != nil { - for _, targetPackage := range pm.Packages { + if res.Pm != nil { + for _, targetPackage := range res.Pm.Packages { for _, platform := range targetPackage.Platforms { - if platformRelease := pm.GetInstalledPlatformRelease(platform); platformRelease != nil { - lm.AddPlatformReleaseLibrariesDir(platformRelease, libraries.PlatformBuiltIn) + if platformRelease := res.Pm.GetInstalledPlatformRelease(platform); platformRelease != nil { + res.Lm.AddPlatformReleaseLibrariesDir(platformRelease, libraries.PlatformBuiltIn) } } } } // Load index and auto-update it if needed - librariesIndexError := "" - if err := lm.LoadIndex(); err != nil { - librariesIndexError = err.Error() + if err := res.Lm.LoadIndex(); err != nil { + res.LibrariesIndexError = err.Error() } // Scan for libraries - if err := lm.RescanLibraries(); err != nil { - return nil, nil, nil, "", fmt.Errorf("libraries rescan: %s", err) + if err := res.Lm.RescanLibraries(); err != nil { + return res, fmt.Errorf("libraries rescan: %s", err) } - return pm, lm, platformIndexErrors, librariesIndexError, nil + + return res, nil } // Download FIXMEDOC diff --git a/rpc/commands/commands.proto b/rpc/commands/commands.proto index 628c6626ef5..6dec9bec866 100644 --- a/rpc/commands/commands.proto +++ b/rpc/commands/commands.proto @@ -93,27 +93,17 @@ service ArduinoCore { rpc LibraryList(LibraryListReq) returns (LibraryListResp); } -// Configuration contains information to instantiate an Arduino Platform Service +// DEPRECATED +// Configuration is deprecated, use the Settings Service instead message Configuration { - // dataDir represents the current root of the arduino tree (defaulted to - // `$HOME/.arduino15` on linux). string dataDir = 1; - - // sketchbookDir represents the current root of the sketchbooks tree - // (defaulted to `$HOME/Arduino`). string sketchbookDir = 2; - - // ArduinoIDEDirectory is the directory of the Arduino IDE if the CLI runs - // together with it. string downloadsDir = 3; - - // BoardManagerAdditionalUrls contains the additional URL for 3rd party - // packages repeated string boardManagerAdditionalUrls = 4; } message InitReq { - Configuration configuration = 1; + Configuration configuration = 1; // DEPRECATED this field will be ignored bool library_manager_only = 2; }