From b7e8ff44770d3490796fa1b8eccf6a7a93da477a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 10 Feb 2021 16:28:58 +0100 Subject: [PATCH 01/19] Proper gRPC error handling --- cli/compile/compile.go | 10 +- commands/daemon/daemon.go | 6 +- commands/upload/burnbootloader.go | 3 +- commands/upload/upload.go | 65 +-- commands/upload/upload_test.go | 6 +- rpc/cc/arduino/cli/commands/v1/board.pb.go | 2 +- rpc/cc/arduino/cli/commands/v1/commands.pb.go | 2 +- .../cli/commands/v1/commands_grpc.pb.go | 52 +-- rpc/cc/arduino/cli/commands/v1/common.pb.go | 2 +- rpc/cc/arduino/cli/commands/v1/compile.pb.go | 2 +- rpc/cc/arduino/cli/commands/v1/core.pb.go | 2 +- rpc/cc/arduino/cli/commands/v1/lib.pb.go | 2 +- rpc/cc/arduino/cli/commands/v1/port.pb.go | 2 +- rpc/cc/arduino/cli/commands/v1/upload.pb.go | 405 ++++++++++-------- rpc/cc/arduino/cli/commands/v1/upload.proto | 2 + rpc/cc/arduino/cli/debug/v1/debug.pb.go | 2 +- rpc/cc/arduino/cli/debug/v1/debug_grpc.pb.go | 12 +- rpc/cc/arduino/cli/monitor/v1/monitor.pb.go | 2 +- .../arduino/cli/monitor/v1/monitor_grpc.pb.go | 12 +- rpc/cc/arduino/cli/settings/v1/settings.pb.go | 2 +- .../cli/settings/v1/settings_grpc.pb.go | 10 +- 21 files changed, 339 insertions(+), 264 deletions(-) diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 19c3b16ca26..7214bbce32e 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -29,6 +29,7 @@ import ( "github.com/arduino/arduino-cli/cli/output" "github.com/arduino/arduino-cli/configuration" "github.com/arduino/arduino-cli/i18n" + "google.golang.org/grpc/status" "github.com/arduino/arduino-cli/cli/errorcodes" "github.com/arduino/arduino-cli/cli/instance" @@ -230,16 +231,17 @@ func run(cmd *cobra.Command, args []string) { Programmer: programmer, UserFields: fields, } + var st *status.Status if output.OutputFormat == "json" { // TODO: do not print upload output in json mode uploadOut := new(bytes.Buffer) uploadErr := new(bytes.Buffer) - _, err = upload.Upload(context.Background(), uploadRequest, uploadOut, uploadErr) + _, st = upload.Upload(context.Background(), uploadRequest, uploadOut, uploadErr) } else { - _, err = upload.Upload(context.Background(), uploadRequest, os.Stdout, os.Stderr) + _, st = upload.Upload(context.Background(), uploadRequest, os.Stdout, os.Stderr) } - if err != nil { - feedback.Errorf(tr("Error during Upload: %v"), err) + if st != nil { + feedback.Errorf(tr("Error during Upload: %v"), st.Message()) os.Exit(errorcodes.ErrGeneric) } } diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index bf4aabcc0e6..d81103b8680 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -317,7 +317,7 @@ func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.Arduin utils.FeedStreamTo(func(data []byte) { stream.Send(&rpc.UploadResponse{ErrStream: data}) }), ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } @@ -330,7 +330,7 @@ func (s *ArduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgra utils.FeedStreamTo(func(data []byte) { stream.Send(&rpc.UploadUsingProgrammerResponse{ErrStream: data}) }), ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } @@ -343,7 +343,7 @@ func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, s utils.FeedStreamTo(func(data []byte) { stream.Send(&rpc.BurnBootloaderResponse{ErrStream: data}) }), ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } diff --git a/commands/upload/burnbootloader.go b/commands/upload/burnbootloader.go index 8866bbdb837..d9a0559c68a 100644 --- a/commands/upload/burnbootloader.go +++ b/commands/upload/burnbootloader.go @@ -22,10 +22,11 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" + "google.golang.org/grpc/status" ) // BurnBootloader FIXMEDOC -func BurnBootloader(ctx context.Context, req *rpc.BurnBootloaderRequest, outStream io.Writer, errStream io.Writer) (*rpc.BurnBootloaderResponse, error) { +func BurnBootloader(ctx context.Context, req *rpc.BurnBootloaderRequest, outStream io.Writer, errStream io.Writer) (*rpc.BurnBootloaderResponse, *status.Status) { logrus. WithField("fqbn", req.GetFqbn()). WithField("port", req.GetPort()). diff --git a/commands/upload/upload.go b/commands/upload/upload.go index 00a0e07dbb9..4f94267ec3b 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -35,6 +35,8 @@ import ( properties "github.com/arduino/go-properties-orderedmap" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var tr = i18n.Tr @@ -61,9 +63,9 @@ func SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsReques return nil, fmt.Errorf(tr("loading board data: %s"), err) } - toolID, err := getToolID(board.Properties, "upload", req.Protocol) - if err != nil { - return nil, err + toolID, st := getToolID(board.Properties, "upload", req.Protocol) + if st != nil { + return nil, st.Err() } return &rpc.SupportedUserFieldsResponse{ @@ -73,7 +75,7 @@ func SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsReques // getToolID returns the ID of the tool that supports the action and protocol combination by searching in props. // Returns error if tool cannot be found. -func getToolID(props *properties.Map, action, protocol string) (string, error) { +func getToolID(props *properties.Map, action, protocol string) (string, *status.Status) { toolProperty := fmt.Sprintf("%s.tool.%s", action, protocol) defaultToolProperty := fmt.Sprintf("%s.tool.default", action) @@ -84,7 +86,7 @@ func getToolID(props *properties.Map, action, protocol string) (string, error) { // https://arduino.github.io/arduino-cli/latest/platform-specification/#sketch-upload-configuration return t, nil } - return "", fmt.Errorf(tr("cannot find tool: undefined '%s' property"), toolProperty) + return "", status.Newf(codes.FailedPrecondition, tr("Cannot find tool: undefined '%s' property"), toolProperty) } // getUserFields return all user fields supported by the tools specified. @@ -112,7 +114,7 @@ func getUserFields(toolID string, platformRelease *cores.PlatformRelease) []*rpc } // Upload FIXMEDOC -func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadResponse, error) { +func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadResponse, *status.Status) { logrus.Tracef("Upload %s on %s started", req.GetSketchPath(), req.GetFqbn()) // TODO: make a generic function to extract sketch from request @@ -120,12 +122,12 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil && req.GetImportDir() == "" && req.GetImportFile() == "" { - return nil, fmt.Errorf(tr("opening sketch: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Sketch not found: %s"), err) } pm := commands.GetPackageManager(req.GetInstance().GetId()) - err = runProgramAction( + return &rpc.UploadResponse{}, runProgramAction( pm, sk, req.GetImportFile(), @@ -141,18 +143,14 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er req.GetDryRun(), req.GetUserFields(), ) - if err != nil { - return nil, err - } - return &rpc.UploadResponse{}, nil } // UsingProgrammer FIXMEDOC -func UsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadUsingProgrammerResponse, error) { +func UsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadUsingProgrammerResponse, *status.Status) { logrus.Tracef("Upload using programmer %s on %s started", req.GetSketchPath(), req.GetFqbn()) if req.GetProgrammer() == "" { - return nil, errors.New(tr("programmer not specified")) + return nil, status.New(codes.InvalidArgument, tr("Programmer not specified")) } _, err := Upload(ctx, &rpc.UploadRequest{ Instance: req.GetInstance(), @@ -175,10 +173,10 @@ func runProgramAction(pm *packagemanager.PackageManager, programmerID string, verbose, verify, burnBootloader bool, outStream, errStream io.Writer, - dryRun bool, userFields map[string]string) error { + dryRun bool, userFields map[string]string) *status.Status { if burnBootloader && programmerID == "" { - return fmt.Errorf(tr("no programmer specified for burning bootloader")) + return status.New(codes.InvalidArgument, tr("No programmer specified for burning bootloader")) } logrus.WithField("port", port).Tracef("Upload port") @@ -187,18 +185,18 @@ func runProgramAction(pm *packagemanager.PackageManager, fqbnIn = sk.Metadata.CPU.Fqbn } if fqbnIn == "" { - return fmt.Errorf(tr("no Fully Qualified Board Name provided")) + return status.New(codes.InvalidArgument, tr("No FQBN (Fully Qualified Board Name) provided")) } fqbn, err := cores.ParseFQBN(fqbnIn) if err != nil { - return fmt.Errorf(tr("incorrect FQBN: %s"), err) + return status.Newf(codes.InvalidArgument, fmt.Sprintf(tr("Invalid FQBN: %s"), err)) } logrus.WithField("fqbn", fqbn).Tracef("Detected FQBN") // Find target board and board properties _, boardPlatform, board, boardProperties, buildPlatform, err := pm.ResolveFQBN(fqbn) if err != nil { - return fmt.Errorf(tr("incorrect FQBN: %s"), err) + return status.Newf(codes.InvalidArgument, tr("Could not resolve FQBN: %s"), err) } logrus. WithField("boardPlatform", boardPlatform). @@ -215,7 +213,7 @@ func runProgramAction(pm *packagemanager.PackageManager, programmer = buildPlatform.Programmers[programmerID] } if programmer == nil { - return fmt.Errorf(tr("programmer '%s' not available"), programmerID) + return status.Newf(codes.InvalidArgument, tr("Programmer '%s' not available"), programmerID) } } @@ -234,9 +232,9 @@ func runProgramAction(pm *packagemanager.PackageManager, } else if programmer != nil { action = "program" } - uploadToolID, err := getToolID(props, action, port.Protocol) - if err != nil { - return err + uploadToolID, st := getToolID(props, action, port.Protocol) + if st != nil { + return st } var uploadToolPlatform *cores.PlatformRelease @@ -251,7 +249,7 @@ func runProgramAction(pm *packagemanager.PackageManager, Trace("Upload tool") if split := strings.Split(uploadToolID, ":"); len(split) > 2 { - return fmt.Errorf(tr("invalid 'upload.tool' property: %s"), uploadToolID) + return status.Newf(codes.FailedPrecondition, tr("Invalid 'upload.tool' property: %s"), uploadToolID) } else if len(split) == 2 { uploadToolID = split[1] uploadToolPlatform = pm.GetInstalledPlatformRelease( @@ -299,7 +297,10 @@ func runProgramAction(pm *packagemanager.PackageManager, } if !uploadProperties.ContainsKey("upload.protocol") && programmer == nil { - return fmt.Errorf(tr("a programmer is required to upload for this board")) + err, _ := status. + Newf(codes.InvalidArgument, tr("A programmer is required to upload on this board")). + WithDetails(&rpc.ProgrammerIsRequiredForUploadError{}) + return err } // Set properties for verbose upload @@ -347,13 +348,13 @@ func runProgramAction(pm *packagemanager.PackageManager, if !burnBootloader { importPath, sketchName, err := determineBuildPathAndSketchName(importFile, importDir, sk, fqbn) if err != nil { - return errors.Errorf(tr("retrieving build artifacts: %s"), err) + return status.Newf(codes.Internal, tr("Error finding build artifacts: %s"), err) } if !importPath.Exist() { - return fmt.Errorf(tr("compiled sketch not found in %s"), importPath) + return status.Newf(codes.Internal, tr("Compiled sketch not found in %s"), importPath) } if !importPath.IsDir() { - return fmt.Errorf(tr("expected compiled sketch in directory %s, but is a file instead"), importPath) + return status.Newf(codes.Internal, tr("Expected compiled sketch in directory %s, but is a file instead"), importPath) } uploadProperties.SetPath("build.path", importPath) uploadProperties.Set("build.project_name", sketchName) @@ -446,18 +447,18 @@ func runProgramAction(pm *packagemanager.PackageManager, // Run recipes for upload if burnBootloader { if err := runTool("erase.pattern", uploadProperties, outStream, errStream, verbose, dryRun); err != nil { - return fmt.Errorf(tr("chip erase error: %s"), err) + return status.Newf(codes.Internal, tr("Failed chip erase: %s"), err) } if err := runTool("bootloader.pattern", uploadProperties, outStream, errStream, verbose, dryRun); err != nil { - return fmt.Errorf(tr("burn bootloader error: %s"), err) + return status.Newf(codes.Internal, tr("Failed to burn bootloader: %s"), err) } } else if programmer != nil { if err := runTool("program.pattern", uploadProperties, outStream, errStream, verbose, dryRun); err != nil { - return fmt.Errorf(tr("programming error: %s"), err) + return status.Newf(codes.Internal, tr("Failed programming: %s"), err) } } else { if err := runTool("upload.pattern", uploadProperties, outStream, errStream, verbose, dryRun); err != nil { - return fmt.Errorf(tr("uploading error: %s"), err) + return status.Newf(codes.Internal, tr("Failed uploading: %s"), err) } } diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index d9a9495eec6..07708115083 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -180,7 +180,7 @@ func TestUploadPropertiesComposition(t *testing.T) { testRunner := func(t *testing.T, test test, verboseVerify bool) { outStream := &bytes.Buffer{} errStream := &bytes.Buffer{} - err := runProgramAction( + status := runProgramAction( pm, nil, // sketch "", // importFile @@ -201,9 +201,9 @@ func TestUploadPropertiesComposition(t *testing.T) { verboseVerifyOutput = "quiet noverify" } if test.expectedOutput == "FAIL" { - require.Error(t, err) + require.NotNil(t, status) } else { - require.NoError(t, err) + require.Nil(t, status) outFiltered := strings.ReplaceAll(outStream.String(), "\r", "") outFiltered = strings.ReplaceAll(outFiltered, "\\", "/") require.Contains(t, outFiltered, strings.ReplaceAll(test.expectedOutput, "$$VERBOSE-VERIFY$$", verboseVerifyOutput)) diff --git a/rpc/cc/arduino/cli/commands/v1/board.pb.go b/rpc/cc/arduino/cli/commands/v1/board.pb.go index cba8bc07f75..88deb29b261 100644 --- a/rpc/cc/arduino/cli/commands/v1/board.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/board.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/commands/v1/board.proto package commands diff --git a/rpc/cc/arduino/cli/commands/v1/commands.pb.go b/rpc/cc/arduino/cli/commands/v1/commands.pb.go index 5aec0c6b9b4..1ce280b35e9 100644 --- a/rpc/cc/arduino/cli/commands/v1/commands.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/commands.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/commands/v1/commands.proto package commands diff --git a/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go b/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go index 5bf4da6a263..3db9d57f19e 100644 --- a/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go @@ -11,6 +11,7 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 // ArduinoCoreServiceClient is the client API for ArduinoCoreService service. @@ -117,7 +118,7 @@ func (c *arduinoCoreServiceClient) Create(ctx context.Context, in *CreateRequest } func (c *arduinoCoreServiceClient) Init(ctx context.Context, in *InitRequest, opts ...grpc.CallOption) (ArduinoCoreService_InitClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[0], "/cc.arduino.cli.commands.v1.ArduinoCoreService/Init", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[0], "/cc.arduino.cli.commands.v1.ArduinoCoreService/Init", opts...) if err != nil { return nil, err } @@ -158,7 +159,7 @@ func (c *arduinoCoreServiceClient) Destroy(ctx context.Context, in *DestroyReque } func (c *arduinoCoreServiceClient) UpdateIndex(ctx context.Context, in *UpdateIndexRequest, opts ...grpc.CallOption) (ArduinoCoreService_UpdateIndexClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[1], "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateIndex", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[1], "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateIndex", opts...) if err != nil { return nil, err } @@ -190,7 +191,7 @@ func (x *arduinoCoreServiceUpdateIndexClient) Recv() (*UpdateIndexResponse, erro } func (c *arduinoCoreServiceClient) UpdateLibrariesIndex(ctx context.Context, in *UpdateLibrariesIndexRequest, opts ...grpc.CallOption) (ArduinoCoreService_UpdateLibrariesIndexClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[2], "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateLibrariesIndex", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[2], "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateLibrariesIndex", opts...) if err != nil { return nil, err } @@ -222,7 +223,7 @@ func (x *arduinoCoreServiceUpdateLibrariesIndexClient) Recv() (*UpdateLibrariesI } func (c *arduinoCoreServiceClient) UpdateCoreLibrariesIndex(ctx context.Context, in *UpdateCoreLibrariesIndexRequest, opts ...grpc.CallOption) (ArduinoCoreService_UpdateCoreLibrariesIndexClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[3], "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateCoreLibrariesIndex", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[3], "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateCoreLibrariesIndex", opts...) if err != nil { return nil, err } @@ -263,7 +264,7 @@ func (c *arduinoCoreServiceClient) Outdated(ctx context.Context, in *OutdatedReq } func (c *arduinoCoreServiceClient) Upgrade(ctx context.Context, in *UpgradeRequest, opts ...grpc.CallOption) (ArduinoCoreService_UpgradeClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[4], "/cc.arduino.cli.commands.v1.ArduinoCoreService/Upgrade", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[4], "/cc.arduino.cli.commands.v1.ArduinoCoreService/Upgrade", opts...) if err != nil { return nil, err } @@ -331,7 +332,7 @@ func (c *arduinoCoreServiceClient) BoardDetails(ctx context.Context, in *BoardDe } func (c *arduinoCoreServiceClient) BoardAttach(ctx context.Context, in *BoardAttachRequest, opts ...grpc.CallOption) (ArduinoCoreService_BoardAttachClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[5], "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardAttach", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[5], "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardAttach", opts...) if err != nil { return nil, err } @@ -390,7 +391,7 @@ func (c *arduinoCoreServiceClient) BoardSearch(ctx context.Context, in *BoardSea } func (c *arduinoCoreServiceClient) BoardListWatch(ctx context.Context, opts ...grpc.CallOption) (ArduinoCoreService_BoardListWatchClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[6], "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardListWatch", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[6], "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardListWatch", opts...) if err != nil { return nil, err } @@ -421,7 +422,7 @@ func (x *arduinoCoreServiceBoardListWatchClient) Recv() (*BoardListWatchResponse } func (c *arduinoCoreServiceClient) Compile(ctx context.Context, in *CompileRequest, opts ...grpc.CallOption) (ArduinoCoreService_CompileClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[7], "/cc.arduino.cli.commands.v1.ArduinoCoreService/Compile", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[7], "/cc.arduino.cli.commands.v1.ArduinoCoreService/Compile", opts...) if err != nil { return nil, err } @@ -453,7 +454,7 @@ func (x *arduinoCoreServiceCompileClient) Recv() (*CompileResponse, error) { } func (c *arduinoCoreServiceClient) PlatformInstall(ctx context.Context, in *PlatformInstallRequest, opts ...grpc.CallOption) (ArduinoCoreService_PlatformInstallClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[8], "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformInstall", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[8], "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformInstall", opts...) if err != nil { return nil, err } @@ -485,7 +486,7 @@ func (x *arduinoCoreServicePlatformInstallClient) Recv() (*PlatformInstallRespon } func (c *arduinoCoreServiceClient) PlatformDownload(ctx context.Context, in *PlatformDownloadRequest, opts ...grpc.CallOption) (ArduinoCoreService_PlatformDownloadClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[9], "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformDownload", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[9], "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformDownload", opts...) if err != nil { return nil, err } @@ -517,7 +518,7 @@ func (x *arduinoCoreServicePlatformDownloadClient) Recv() (*PlatformDownloadResp } func (c *arduinoCoreServiceClient) PlatformUninstall(ctx context.Context, in *PlatformUninstallRequest, opts ...grpc.CallOption) (ArduinoCoreService_PlatformUninstallClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[10], "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformUninstall", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[10], "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformUninstall", opts...) if err != nil { return nil, err } @@ -549,7 +550,7 @@ func (x *arduinoCoreServicePlatformUninstallClient) Recv() (*PlatformUninstallRe } func (c *arduinoCoreServiceClient) PlatformUpgrade(ctx context.Context, in *PlatformUpgradeRequest, opts ...grpc.CallOption) (ArduinoCoreService_PlatformUpgradeClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[11], "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformUpgrade", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[11], "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformUpgrade", opts...) if err != nil { return nil, err } @@ -581,7 +582,7 @@ func (x *arduinoCoreServicePlatformUpgradeClient) Recv() (*PlatformUpgradeRespon } func (c *arduinoCoreServiceClient) Upload(ctx context.Context, in *UploadRequest, opts ...grpc.CallOption) (ArduinoCoreService_UploadClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[12], "/cc.arduino.cli.commands.v1.ArduinoCoreService/Upload", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[12], "/cc.arduino.cli.commands.v1.ArduinoCoreService/Upload", opts...) if err != nil { return nil, err } @@ -613,7 +614,7 @@ func (x *arduinoCoreServiceUploadClient) Recv() (*UploadResponse, error) { } func (c *arduinoCoreServiceClient) UploadUsingProgrammer(ctx context.Context, in *UploadUsingProgrammerRequest, opts ...grpc.CallOption) (ArduinoCoreService_UploadUsingProgrammerClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[13], "/cc.arduino.cli.commands.v1.ArduinoCoreService/UploadUsingProgrammer", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[13], "/cc.arduino.cli.commands.v1.ArduinoCoreService/UploadUsingProgrammer", opts...) if err != nil { return nil, err } @@ -654,7 +655,7 @@ func (c *arduinoCoreServiceClient) ListProgrammersAvailableForUpload(ctx context } func (c *arduinoCoreServiceClient) BurnBootloader(ctx context.Context, in *BurnBootloaderRequest, opts ...grpc.CallOption) (ArduinoCoreService_BurnBootloaderClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[14], "/cc.arduino.cli.commands.v1.ArduinoCoreService/BurnBootloader", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[14], "/cc.arduino.cli.commands.v1.ArduinoCoreService/BurnBootloader", opts...) if err != nil { return nil, err } @@ -704,7 +705,7 @@ func (c *arduinoCoreServiceClient) PlatformList(ctx context.Context, in *Platfor } func (c *arduinoCoreServiceClient) LibraryDownload(ctx context.Context, in *LibraryDownloadRequest, opts ...grpc.CallOption) (ArduinoCoreService_LibraryDownloadClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[15], "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryDownload", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[15], "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryDownload", opts...) if err != nil { return nil, err } @@ -736,7 +737,7 @@ func (x *arduinoCoreServiceLibraryDownloadClient) Recv() (*LibraryDownloadRespon } func (c *arduinoCoreServiceClient) LibraryInstall(ctx context.Context, in *LibraryInstallRequest, opts ...grpc.CallOption) (ArduinoCoreService_LibraryInstallClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[16], "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryInstall", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[16], "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryInstall", opts...) if err != nil { return nil, err } @@ -768,7 +769,7 @@ func (x *arduinoCoreServiceLibraryInstallClient) Recv() (*LibraryInstallResponse } func (c *arduinoCoreServiceClient) ZipLibraryInstall(ctx context.Context, in *ZipLibraryInstallRequest, opts ...grpc.CallOption) (ArduinoCoreService_ZipLibraryInstallClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[17], "/cc.arduino.cli.commands.v1.ArduinoCoreService/ZipLibraryInstall", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[17], "/cc.arduino.cli.commands.v1.ArduinoCoreService/ZipLibraryInstall", opts...) if err != nil { return nil, err } @@ -800,7 +801,7 @@ func (x *arduinoCoreServiceZipLibraryInstallClient) Recv() (*ZipLibraryInstallRe } func (c *arduinoCoreServiceClient) GitLibraryInstall(ctx context.Context, in *GitLibraryInstallRequest, opts ...grpc.CallOption) (ArduinoCoreService_GitLibraryInstallClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[18], "/cc.arduino.cli.commands.v1.ArduinoCoreService/GitLibraryInstall", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[18], "/cc.arduino.cli.commands.v1.ArduinoCoreService/GitLibraryInstall", opts...) if err != nil { return nil, err } @@ -832,7 +833,7 @@ func (x *arduinoCoreServiceGitLibraryInstallClient) Recv() (*GitLibraryInstallRe } func (c *arduinoCoreServiceClient) LibraryUninstall(ctx context.Context, in *LibraryUninstallRequest, opts ...grpc.CallOption) (ArduinoCoreService_LibraryUninstallClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[19], "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryUninstall", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[19], "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryUninstall", opts...) if err != nil { return nil, err } @@ -864,7 +865,7 @@ func (x *arduinoCoreServiceLibraryUninstallClient) Recv() (*LibraryUninstallResp } func (c *arduinoCoreServiceClient) LibraryUpgradeAll(ctx context.Context, in *LibraryUpgradeAllRequest, opts ...grpc.CallOption) (ArduinoCoreService_LibraryUpgradeAllClient, error) { - stream, err := c.cc.NewStream(ctx, &_ArduinoCoreService_serviceDesc.Streams[20], "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryUpgradeAll", opts...) + stream, err := c.cc.NewStream(ctx, &ArduinoCoreService_ServiceDesc.Streams[20], "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryUpgradeAll", opts...) if err != nil { return nil, err } @@ -1133,8 +1134,8 @@ type UnsafeArduinoCoreServiceServer interface { mustEmbedUnimplementedArduinoCoreServiceServer() } -func RegisterArduinoCoreServiceServer(s *grpc.Server, srv ArduinoCoreServiceServer) { - s.RegisterService(&_ArduinoCoreService_serviceDesc, srv) +func RegisterArduinoCoreServiceServer(s grpc.ServiceRegistrar, srv ArduinoCoreServiceServer) { + s.RegisterService(&ArduinoCoreService_ServiceDesc, srv) } func _ArduinoCoreService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { @@ -1871,7 +1872,10 @@ func _ArduinoCoreService_LibraryList_Handler(srv interface{}, ctx context.Contex return interceptor(ctx, in, info, handler) } -var _ArduinoCoreService_serviceDesc = grpc.ServiceDesc{ +// ArduinoCoreService_ServiceDesc is the grpc.ServiceDesc for ArduinoCoreService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var ArduinoCoreService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "cc.arduino.cli.commands.v1.ArduinoCoreService", HandlerType: (*ArduinoCoreServiceServer)(nil), Methods: []grpc.MethodDesc{ diff --git a/rpc/cc/arduino/cli/commands/v1/common.pb.go b/rpc/cc/arduino/cli/commands/v1/common.pb.go index 637a9557233..a798924a13c 100644 --- a/rpc/cc/arduino/cli/commands/v1/common.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/common.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/commands/v1/common.proto package commands diff --git a/rpc/cc/arduino/cli/commands/v1/compile.pb.go b/rpc/cc/arduino/cli/commands/v1/compile.pb.go index becaf763077..6f5a69cf332 100644 --- a/rpc/cc/arduino/cli/commands/v1/compile.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/compile.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/commands/v1/compile.proto package commands diff --git a/rpc/cc/arduino/cli/commands/v1/core.pb.go b/rpc/cc/arduino/cli/commands/v1/core.pb.go index 83a1fc849fc..c0ee99accb8 100644 --- a/rpc/cc/arduino/cli/commands/v1/core.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/core.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/commands/v1/core.proto package commands diff --git a/rpc/cc/arduino/cli/commands/v1/lib.pb.go b/rpc/cc/arduino/cli/commands/v1/lib.pb.go index e5a97a2c865..70e7918fc56 100644 --- a/rpc/cc/arduino/cli/commands/v1/lib.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/lib.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/commands/v1/lib.proto package commands diff --git a/rpc/cc/arduino/cli/commands/v1/port.pb.go b/rpc/cc/arduino/cli/commands/v1/port.pb.go index ee185906d70..c61dd584898 100644 --- a/rpc/cc/arduino/cli/commands/v1/port.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/port.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/commands/v1/port.proto package commands diff --git a/rpc/cc/arduino/cli/commands/v1/upload.pb.go b/rpc/cc/arduino/cli/commands/v1/upload.pb.go index ebe0426bf7c..647b4dcb370 100644 --- a/rpc/cc/arduino/cli/commands/v1/upload.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/upload.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/commands/v1/upload.proto package commands @@ -244,6 +244,44 @@ func (x *UploadResponse) GetErrStream() []byte { return nil } +type ProgrammerIsRequiredForUploadError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ProgrammerIsRequiredForUploadError) Reset() { + *x = ProgrammerIsRequiredForUploadError{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProgrammerIsRequiredForUploadError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProgrammerIsRequiredForUploadError) ProtoMessage() {} + +func (x *ProgrammerIsRequiredForUploadError) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProgrammerIsRequiredForUploadError.ProtoReflect.Descriptor instead. +func (*ProgrammerIsRequiredForUploadError) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{2} +} + type UploadUsingProgrammerRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -288,7 +326,7 @@ type UploadUsingProgrammerRequest struct { func (x *UploadUsingProgrammerRequest) Reset() { *x = UploadUsingProgrammerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -301,7 +339,7 @@ func (x *UploadUsingProgrammerRequest) String() string { func (*UploadUsingProgrammerRequest) ProtoMessage() {} func (x *UploadUsingProgrammerRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -314,7 +352,7 @@ func (x *UploadUsingProgrammerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadUsingProgrammerRequest.ProtoReflect.Descriptor instead. func (*UploadUsingProgrammerRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{2} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{3} } func (x *UploadUsingProgrammerRequest) GetInstance() *Instance { @@ -408,7 +446,7 @@ type UploadUsingProgrammerResponse struct { func (x *UploadUsingProgrammerResponse) Reset() { *x = UploadUsingProgrammerResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -421,7 +459,7 @@ func (x *UploadUsingProgrammerResponse) String() string { func (*UploadUsingProgrammerResponse) ProtoMessage() {} func (x *UploadUsingProgrammerResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -434,7 +472,7 @@ func (x *UploadUsingProgrammerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UploadUsingProgrammerResponse.ProtoReflect.Descriptor instead. func (*UploadUsingProgrammerResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{3} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{4} } func (x *UploadUsingProgrammerResponse) GetOutStream() []byte { @@ -483,7 +521,7 @@ type BurnBootloaderRequest struct { func (x *BurnBootloaderRequest) Reset() { *x = BurnBootloaderRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -496,7 +534,7 @@ func (x *BurnBootloaderRequest) String() string { func (*BurnBootloaderRequest) ProtoMessage() {} func (x *BurnBootloaderRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -509,7 +547,7 @@ func (x *BurnBootloaderRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use BurnBootloaderRequest.ProtoReflect.Descriptor instead. func (*BurnBootloaderRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{4} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{5} } func (x *BurnBootloaderRequest) GetInstance() *Instance { @@ -582,7 +620,7 @@ type BurnBootloaderResponse struct { func (x *BurnBootloaderResponse) Reset() { *x = BurnBootloaderResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -595,7 +633,7 @@ func (x *BurnBootloaderResponse) String() string { func (*BurnBootloaderResponse) ProtoMessage() {} func (x *BurnBootloaderResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -608,7 +646,7 @@ func (x *BurnBootloaderResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use BurnBootloaderResponse.ProtoReflect.Descriptor instead. func (*BurnBootloaderResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{5} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{6} } func (x *BurnBootloaderResponse) GetOutStream() []byte { @@ -637,7 +675,7 @@ type ListProgrammersAvailableForUploadRequest struct { func (x *ListProgrammersAvailableForUploadRequest) Reset() { *x = ListProgrammersAvailableForUploadRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -650,7 +688,7 @@ func (x *ListProgrammersAvailableForUploadRequest) String() string { func (*ListProgrammersAvailableForUploadRequest) ProtoMessage() {} func (x *ListProgrammersAvailableForUploadRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -663,7 +701,7 @@ func (x *ListProgrammersAvailableForUploadRequest) ProtoReflect() protoreflect.M // Deprecated: Use ListProgrammersAvailableForUploadRequest.ProtoReflect.Descriptor instead. func (*ListProgrammersAvailableForUploadRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{6} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{7} } func (x *ListProgrammersAvailableForUploadRequest) GetInstance() *Instance { @@ -691,7 +729,7 @@ type ListProgrammersAvailableForUploadResponse struct { func (x *ListProgrammersAvailableForUploadResponse) Reset() { *x = ListProgrammersAvailableForUploadResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -704,7 +742,7 @@ func (x *ListProgrammersAvailableForUploadResponse) String() string { func (*ListProgrammersAvailableForUploadResponse) ProtoMessage() {} func (x *ListProgrammersAvailableForUploadResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -717,7 +755,7 @@ func (x *ListProgrammersAvailableForUploadResponse) ProtoReflect() protoreflect. // Deprecated: Use ListProgrammersAvailableForUploadResponse.ProtoReflect.Descriptor instead. func (*ListProgrammersAvailableForUploadResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{7} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{8} } func (x *ListProgrammersAvailableForUploadResponse) GetProgrammers() []*Programmer { @@ -743,7 +781,7 @@ type SupportedUserFieldsRequest struct { func (x *SupportedUserFieldsRequest) Reset() { *x = SupportedUserFieldsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -756,7 +794,7 @@ func (x *SupportedUserFieldsRequest) String() string { func (*SupportedUserFieldsRequest) ProtoMessage() {} func (x *SupportedUserFieldsRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -769,7 +807,7 @@ func (x *SupportedUserFieldsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SupportedUserFieldsRequest.ProtoReflect.Descriptor instead. func (*SupportedUserFieldsRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{8} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{9} } func (x *SupportedUserFieldsRequest) GetInstance() *Instance { @@ -812,7 +850,7 @@ type UserField struct { func (x *UserField) Reset() { *x = UserField{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -825,7 +863,7 @@ func (x *UserField) String() string { func (*UserField) ProtoMessage() {} func (x *UserField) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -838,7 +876,7 @@ func (x *UserField) ProtoReflect() protoreflect.Message { // Deprecated: Use UserField.ProtoReflect.Descriptor instead. func (*UserField) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{9} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{10} } func (x *UserField) GetToolId() string { @@ -882,7 +920,7 @@ type SupportedUserFieldsResponse struct { func (x *SupportedUserFieldsResponse) Reset() { *x = SupportedUserFieldsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -895,7 +933,7 @@ func (x *SupportedUserFieldsResponse) String() string { func (*SupportedUserFieldsResponse) ProtoMessage() {} func (x *SupportedUserFieldsResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10] + mi := &file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -908,7 +946,7 @@ func (x *SupportedUserFieldsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SupportedUserFieldsResponse.ProtoReflect.Descriptor instead. func (*SupportedUserFieldsResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{10} + return file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP(), []int{11} } func (x *SupportedUserFieldsResponse) GetUserFields() []*UserField { @@ -967,123 +1005,125 @@ var file_cc_arduino_cli_commands_v1_upload_proto_rawDesc = []byte{ 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0xa0, 0x04, 0x0a, 0x1c, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, - 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, - 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x24, 0x0a, 0x22, 0x50, 0x72, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x49, 0x73, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x22, 0xa0, 0x04, 0x0a, 0x1c, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6b, 0x65, 0x74, 0x63, + 0x68, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6b, + 0x65, 0x74, 0x63, 0x68, 0x50, 0x61, 0x74, 0x68, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, + 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x69, + 0x66, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, + 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, + 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, + 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x69, 0x0a, 0x0b, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, + 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, + 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x5d, 0x0a, 0x1d, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, + 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x22, 0xb1, 0x03, 0x0a, 0x15, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, + 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, + 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, + 0x62, 0x6e, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, - 0x6f, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, - 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6d, - 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x69, - 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x69, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, - 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x6f, 0x73, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, + 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, - 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, - 0x52, 0x75, 0x6e, 0x12, 0x69, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, + 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, + 0x52, 0x75, 0x6e, 0x12, 0x62, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, - 0x67, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x3d, - 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5d, 0x0a, - 0x1d, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x55, 0x73, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x6f, 0x67, - 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, - 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0xb1, 0x03, 0x0a, - 0x15, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, - 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x34, 0x0a, 0x04, - 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, - 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x70, 0x6f, - 0x72, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x65, 0x72, 0x62, 0x6f, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, - 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x76, 0x65, - 0x72, 0x69, 0x66, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, - 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, - 0x6d, 0x6d, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x62, 0x0a, - 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, - 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x56, 0x0a, 0x16, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, - 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, - 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, - 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, - 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x80, 0x01, 0x0a, 0x28, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, - 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, - 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x22, 0x75, 0x0a, 0x29, 0x4c, - 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, - 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x67, - 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, 0x6f, 0x74, 0x6c, 0x6f, + 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x55, 0x73, 0x65, 0x72, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x75, 0x73, 0x65, + 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x55, 0x73, 0x65, 0x72, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x56, 0x0a, 0x16, 0x42, 0x75, 0x72, 0x6e, 0x42, 0x6f, + 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, + 0x1d, 0x0a, 0x0a, 0x65, 0x72, 0x72, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x65, 0x72, 0x72, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x80, + 0x01, 0x0a, 0x28, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, + 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, - 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, - 0x72, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x1a, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, - 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, + 0x6e, 0x22, 0x75, 0x0a, 0x29, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, + 0x6d, 0x65, 0x72, 0x73, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x6f, 0x72, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, + 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x22, 0x66, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x74, 0x6f, 0x6f, 0x6c, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x65, 0x0a, 0x1b, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x25, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, - 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, - 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, - 0x69, 0x6e, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, - 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x52, 0x0b, 0x70, 0x72, 0x6f, + 0x67, 0x72, 0x61, 0x6d, 0x6d, 0x65, 0x72, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x1a, 0x53, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, + 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, + 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1a, 0x0a, + 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x66, 0x0a, 0x09, 0x55, 0x73, 0x65, + 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x6f, 0x6f, 0x6c, 0x49, 0x64, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, + 0x74, 0x22, 0x65, 0x0a, 0x1b, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x55, 0x73, + 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x46, 0x0a, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, + 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0a, 0x75, 0x73, + 0x65, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, + 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, + 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1098,40 +1138,41 @@ func file_cc_arduino_cli_commands_v1_upload_proto_rawDescGZIP() []byte { return file_cc_arduino_cli_commands_v1_upload_proto_rawDescData } -var file_cc_arduino_cli_commands_v1_upload_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_cc_arduino_cli_commands_v1_upload_proto_msgTypes = make([]protoimpl.MessageInfo, 15) var file_cc_arduino_cli_commands_v1_upload_proto_goTypes = []interface{}{ (*UploadRequest)(nil), // 0: cc.arduino.cli.commands.v1.UploadRequest (*UploadResponse)(nil), // 1: cc.arduino.cli.commands.v1.UploadResponse - (*UploadUsingProgrammerRequest)(nil), // 2: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest - (*UploadUsingProgrammerResponse)(nil), // 3: cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse - (*BurnBootloaderRequest)(nil), // 4: cc.arduino.cli.commands.v1.BurnBootloaderRequest - (*BurnBootloaderResponse)(nil), // 5: cc.arduino.cli.commands.v1.BurnBootloaderResponse - (*ListProgrammersAvailableForUploadRequest)(nil), // 6: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest - (*ListProgrammersAvailableForUploadResponse)(nil), // 7: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse - (*SupportedUserFieldsRequest)(nil), // 8: cc.arduino.cli.commands.v1.SupportedUserFieldsRequest - (*UserField)(nil), // 9: cc.arduino.cli.commands.v1.UserField - (*SupportedUserFieldsResponse)(nil), // 10: cc.arduino.cli.commands.v1.SupportedUserFieldsResponse - nil, // 11: cc.arduino.cli.commands.v1.UploadRequest.UserFieldsEntry - nil, // 12: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.UserFieldsEntry - nil, // 13: cc.arduino.cli.commands.v1.BurnBootloaderRequest.UserFieldsEntry - (*Instance)(nil), // 14: cc.arduino.cli.commands.v1.Instance - (*Port)(nil), // 15: cc.arduino.cli.commands.v1.Port - (*Programmer)(nil), // 16: cc.arduino.cli.commands.v1.Programmer + (*ProgrammerIsRequiredForUploadError)(nil), // 2: cc.arduino.cli.commands.v1.ProgrammerIsRequiredForUploadError + (*UploadUsingProgrammerRequest)(nil), // 3: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest + (*UploadUsingProgrammerResponse)(nil), // 4: cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse + (*BurnBootloaderRequest)(nil), // 5: cc.arduino.cli.commands.v1.BurnBootloaderRequest + (*BurnBootloaderResponse)(nil), // 6: cc.arduino.cli.commands.v1.BurnBootloaderResponse + (*ListProgrammersAvailableForUploadRequest)(nil), // 7: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest + (*ListProgrammersAvailableForUploadResponse)(nil), // 8: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse + (*SupportedUserFieldsRequest)(nil), // 9: cc.arduino.cli.commands.v1.SupportedUserFieldsRequest + (*UserField)(nil), // 10: cc.arduino.cli.commands.v1.UserField + (*SupportedUserFieldsResponse)(nil), // 11: cc.arduino.cli.commands.v1.SupportedUserFieldsResponse + nil, // 12: cc.arduino.cli.commands.v1.UploadRequest.UserFieldsEntry + nil, // 13: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.UserFieldsEntry + nil, // 14: cc.arduino.cli.commands.v1.BurnBootloaderRequest.UserFieldsEntry + (*Instance)(nil), // 15: cc.arduino.cli.commands.v1.Instance + (*Port)(nil), // 16: cc.arduino.cli.commands.v1.Port + (*Programmer)(nil), // 17: cc.arduino.cli.commands.v1.Programmer } var file_cc_arduino_cli_commands_v1_upload_proto_depIdxs = []int32{ - 14, // 0: cc.arduino.cli.commands.v1.UploadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 15, // 1: cc.arduino.cli.commands.v1.UploadRequest.port:type_name -> cc.arduino.cli.commands.v1.Port - 11, // 2: cc.arduino.cli.commands.v1.UploadRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.UploadRequest.UserFieldsEntry - 14, // 3: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 15, // 4: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.port:type_name -> cc.arduino.cli.commands.v1.Port - 12, // 5: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.UserFieldsEntry - 14, // 6: cc.arduino.cli.commands.v1.BurnBootloaderRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 15, // 7: cc.arduino.cli.commands.v1.BurnBootloaderRequest.port:type_name -> cc.arduino.cli.commands.v1.Port - 13, // 8: cc.arduino.cli.commands.v1.BurnBootloaderRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.BurnBootloaderRequest.UserFieldsEntry - 14, // 9: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 16, // 10: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse.programmers:type_name -> cc.arduino.cli.commands.v1.Programmer - 14, // 11: cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 9, // 12: cc.arduino.cli.commands.v1.SupportedUserFieldsResponse.user_fields:type_name -> cc.arduino.cli.commands.v1.UserField + 15, // 0: cc.arduino.cli.commands.v1.UploadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 16, // 1: cc.arduino.cli.commands.v1.UploadRequest.port:type_name -> cc.arduino.cli.commands.v1.Port + 12, // 2: cc.arduino.cli.commands.v1.UploadRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.UploadRequest.UserFieldsEntry + 15, // 3: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 16, // 4: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.port:type_name -> cc.arduino.cli.commands.v1.Port + 13, // 5: cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest.UserFieldsEntry + 15, // 6: cc.arduino.cli.commands.v1.BurnBootloaderRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 16, // 7: cc.arduino.cli.commands.v1.BurnBootloaderRequest.port:type_name -> cc.arduino.cli.commands.v1.Port + 14, // 8: cc.arduino.cli.commands.v1.BurnBootloaderRequest.user_fields:type_name -> cc.arduino.cli.commands.v1.BurnBootloaderRequest.UserFieldsEntry + 15, // 9: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 17, // 10: cc.arduino.cli.commands.v1.ListProgrammersAvailableForUploadResponse.programmers:type_name -> cc.arduino.cli.commands.v1.Programmer + 15, // 11: cc.arduino.cli.commands.v1.SupportedUserFieldsRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 10, // 12: cc.arduino.cli.commands.v1.SupportedUserFieldsResponse.user_fields:type_name -> cc.arduino.cli.commands.v1.UserField 13, // [13:13] is the sub-list for method output_type 13, // [13:13] is the sub-list for method input_type 13, // [13:13] is the sub-list for extension type_name @@ -1172,7 +1213,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadUsingProgrammerRequest); i { + switch v := v.(*ProgrammerIsRequiredForUploadError); i { case 0: return &v.state case 1: @@ -1184,7 +1225,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UploadUsingProgrammerResponse); i { + switch v := v.(*UploadUsingProgrammerRequest); i { case 0: return &v.state case 1: @@ -1196,7 +1237,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BurnBootloaderRequest); i { + switch v := v.(*UploadUsingProgrammerResponse); i { case 0: return &v.state case 1: @@ -1208,7 +1249,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BurnBootloaderResponse); i { + switch v := v.(*BurnBootloaderRequest); i { case 0: return &v.state case 1: @@ -1220,7 +1261,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListProgrammersAvailableForUploadRequest); i { + switch v := v.(*BurnBootloaderResponse); i { case 0: return &v.state case 1: @@ -1232,7 +1273,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListProgrammersAvailableForUploadResponse); i { + switch v := v.(*ListProgrammersAvailableForUploadRequest); i { case 0: return &v.state case 1: @@ -1244,7 +1285,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SupportedUserFieldsRequest); i { + switch v := v.(*ListProgrammersAvailableForUploadResponse); i { case 0: return &v.state case 1: @@ -1256,7 +1297,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserField); i { + switch v := v.(*SupportedUserFieldsRequest); i { case 0: return &v.state case 1: @@ -1268,6 +1309,18 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { } } file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UserField); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cc_arduino_cli_commands_v1_upload_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*SupportedUserFieldsResponse); i { case 0: return &v.state @@ -1286,7 +1339,7 @@ func file_cc_arduino_cli_commands_v1_upload_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cc_arduino_cli_commands_v1_upload_proto_rawDesc, NumEnums: 0, - NumMessages: 14, + NumMessages: 15, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/cc/arduino/cli/commands/v1/upload.proto b/rpc/cc/arduino/cli/commands/v1/upload.proto index 5cef9fab666..d0aa108c0ef 100644 --- a/rpc/cc/arduino/cli/commands/v1/upload.proto +++ b/rpc/cc/arduino/cli/commands/v1/upload.proto @@ -68,6 +68,8 @@ message UploadResponse { bytes err_stream = 2; } +message ProgrammerIsRequiredForUploadError {} + message UploadUsingProgrammerRequest { // Arduino Core Service instance from the `Init` response. Instance instance = 1; diff --git a/rpc/cc/arduino/cli/debug/v1/debug.pb.go b/rpc/cc/arduino/cli/debug/v1/debug.pb.go index 2d1c9d5973b..795cd0f8e6c 100644 --- a/rpc/cc/arduino/cli/debug/v1/debug.pb.go +++ b/rpc/cc/arduino/cli/debug/v1/debug.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/debug/v1/debug.proto package debug diff --git a/rpc/cc/arduino/cli/debug/v1/debug_grpc.pb.go b/rpc/cc/arduino/cli/debug/v1/debug_grpc.pb.go index 48d9ed99f38..87ad365dd49 100644 --- a/rpc/cc/arduino/cli/debug/v1/debug_grpc.pb.go +++ b/rpc/cc/arduino/cli/debug/v1/debug_grpc.pb.go @@ -11,6 +11,7 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 // DebugServiceClient is the client API for DebugService service. @@ -31,7 +32,7 @@ func NewDebugServiceClient(cc grpc.ClientConnInterface) DebugServiceClient { } func (c *debugServiceClient) Debug(ctx context.Context, opts ...grpc.CallOption) (DebugService_DebugClient, error) { - stream, err := c.cc.NewStream(ctx, &_DebugService_serviceDesc.Streams[0], "/cc.arduino.cli.debug.v1.DebugService/Debug", opts...) + stream, err := c.cc.NewStream(ctx, &DebugService_ServiceDesc.Streams[0], "/cc.arduino.cli.debug.v1.DebugService/Debug", opts...) if err != nil { return nil, err } @@ -99,8 +100,8 @@ type UnsafeDebugServiceServer interface { mustEmbedUnimplementedDebugServiceServer() } -func RegisterDebugServiceServer(s *grpc.Server, srv DebugServiceServer) { - s.RegisterService(&_DebugService_serviceDesc, srv) +func RegisterDebugServiceServer(s grpc.ServiceRegistrar, srv DebugServiceServer) { + s.RegisterService(&DebugService_ServiceDesc, srv) } func _DebugService_Debug_Handler(srv interface{}, stream grpc.ServerStream) error { @@ -147,7 +148,10 @@ func _DebugService_GetDebugConfig_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } -var _DebugService_serviceDesc = grpc.ServiceDesc{ +// DebugService_ServiceDesc is the grpc.ServiceDesc for DebugService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var DebugService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "cc.arduino.cli.debug.v1.DebugService", HandlerType: (*DebugServiceServer)(nil), Methods: []grpc.MethodDesc{ diff --git a/rpc/cc/arduino/cli/monitor/v1/monitor.pb.go b/rpc/cc/arduino/cli/monitor/v1/monitor.pb.go index 0cb277578d1..8f6d764fe7b 100644 --- a/rpc/cc/arduino/cli/monitor/v1/monitor.pb.go +++ b/rpc/cc/arduino/cli/monitor/v1/monitor.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/monitor/v1/monitor.proto package monitor diff --git a/rpc/cc/arduino/cli/monitor/v1/monitor_grpc.pb.go b/rpc/cc/arduino/cli/monitor/v1/monitor_grpc.pb.go index 923bd13c61f..bd24416d142 100644 --- a/rpc/cc/arduino/cli/monitor/v1/monitor_grpc.pb.go +++ b/rpc/cc/arduino/cli/monitor/v1/monitor_grpc.pb.go @@ -11,6 +11,7 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 // MonitorServiceClient is the client API for MonitorService service. @@ -31,7 +32,7 @@ func NewMonitorServiceClient(cc grpc.ClientConnInterface) MonitorServiceClient { } func (c *monitorServiceClient) StreamingOpen(ctx context.Context, opts ...grpc.CallOption) (MonitorService_StreamingOpenClient, error) { - stream, err := c.cc.NewStream(ctx, &_MonitorService_serviceDesc.Streams[0], "/cc.arduino.cli.monitor.v1.MonitorService/StreamingOpen", opts...) + stream, err := c.cc.NewStream(ctx, &MonitorService_ServiceDesc.Streams[0], "/cc.arduino.cli.monitor.v1.MonitorService/StreamingOpen", opts...) if err != nil { return nil, err } @@ -87,8 +88,8 @@ type UnsafeMonitorServiceServer interface { mustEmbedUnimplementedMonitorServiceServer() } -func RegisterMonitorServiceServer(s *grpc.Server, srv MonitorServiceServer) { - s.RegisterService(&_MonitorService_serviceDesc, srv) +func RegisterMonitorServiceServer(s grpc.ServiceRegistrar, srv MonitorServiceServer) { + s.RegisterService(&MonitorService_ServiceDesc, srv) } func _MonitorService_StreamingOpen_Handler(srv interface{}, stream grpc.ServerStream) error { @@ -117,7 +118,10 @@ func (x *monitorServiceStreamingOpenServer) Recv() (*StreamingOpenRequest, error return m, nil } -var _MonitorService_serviceDesc = grpc.ServiceDesc{ +// MonitorService_ServiceDesc is the grpc.ServiceDesc for MonitorService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var MonitorService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "cc.arduino.cli.monitor.v1.MonitorService", HandlerType: (*MonitorServiceServer)(nil), Methods: []grpc.MethodDesc{}, diff --git a/rpc/cc/arduino/cli/settings/v1/settings.pb.go b/rpc/cc/arduino/cli/settings/v1/settings.pb.go index 7fff84832e9..6484a0a81d6 100644 --- a/rpc/cc/arduino/cli/settings/v1/settings.pb.go +++ b/rpc/cc/arduino/cli/settings/v1/settings.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 -// protoc v3.17.3 +// protoc v3.16.0 // source: cc/arduino/cli/settings/v1/settings.proto package settings diff --git a/rpc/cc/arduino/cli/settings/v1/settings_grpc.pb.go b/rpc/cc/arduino/cli/settings/v1/settings_grpc.pb.go index 2a5c87c6536..28ede224376 100644 --- a/rpc/cc/arduino/cli/settings/v1/settings_grpc.pb.go +++ b/rpc/cc/arduino/cli/settings/v1/settings_grpc.pb.go @@ -11,6 +11,7 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 // SettingsServiceClient is the client API for SettingsService service. @@ -127,8 +128,8 @@ type UnsafeSettingsServiceServer interface { mustEmbedUnimplementedSettingsServiceServer() } -func RegisterSettingsServiceServer(s *grpc.Server, srv SettingsServiceServer) { - s.RegisterService(&_SettingsService_serviceDesc, srv) +func RegisterSettingsServiceServer(s grpc.ServiceRegistrar, srv SettingsServiceServer) { + s.RegisterService(&SettingsService_ServiceDesc, srv) } func _SettingsService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { @@ -221,7 +222,10 @@ func _SettingsService_Write_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } -var _SettingsService_serviceDesc = grpc.ServiceDesc{ +// SettingsService_ServiceDesc is the grpc.ServiceDesc for SettingsService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var SettingsService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "cc.arduino.cli.settings.v1.SettingsService", HandlerType: (*SettingsServiceServer)(nil), Methods: []grpc.MethodDesc{ From b6522c0088e377182c6f054e021678cad55f93d4 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 25 Jun 2021 01:34:04 -0700 Subject: [PATCH 02/19] Update gRPC API of board command to return status.Status instead of error --- commands/board/attach.go | 17 +++++++++-------- commands/board/details.go | 12 ++++++------ commands/board/list.go | 18 ++++++++++-------- commands/board/listall.go | 7 ++++--- commands/board/search.go | 7 ++++--- commands/daemon/daemon.go | 31 +++++++++++++++++++++++-------- 6 files changed, 56 insertions(+), 36 deletions(-) diff --git a/commands/board/attach.go b/commands/board/attach.go index 4c9ba46e13f..14957d051a5 100644 --- a/commands/board/attach.go +++ b/commands/board/attach.go @@ -17,7 +17,6 @@ package board import ( "context" - "errors" "fmt" "net/url" "strings" @@ -31,15 +30,17 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" discovery "github.com/arduino/board-discovery" "github.com/arduino/go-paths-helper" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var tr = i18n.Tr // Attach FIXMEDOC -func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.TaskProgressCB) (*rpc.BoardAttachResponse, error) { +func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.TaskProgressCB) (*rpc.BoardAttachResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } var sketchPath *paths.Path if req.GetSketchPath() != "" { @@ -47,7 +48,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta } sk, err := sketch.New(sketchPath) if err != nil { - return nil, fmt.Errorf(tr("opening sketch: %s"), err) + return nil, status.Newf(codes.FailedPrecondition, tr("Error opening sketch: %s"), err) } boardURI := req.GetBoardUri() @@ -63,7 +64,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta } else { deviceURI, err := url.Parse(boardURI) if err != nil { - return nil, fmt.Errorf(tr("invalid Device URL format: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Invalid Device URL format: %s"), err) } var findBoardFunc func(*packagemanager.PackageManager, *discovery.Monitor, *url.URL) *cores.Board @@ -73,7 +74,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta case "http", "https", "tcp", "udp": findBoardFunc = findNetworkConnectedBoard default: - return nil, fmt.Errorf(tr("invalid device port type provided")) + return nil, status.New(codes.InvalidArgument, tr("Invalid device port type provided")) } duration, err := time.ParseDuration(req.GetSearchTimeout()) @@ -89,7 +90,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta // TODO: Handle the case when no board is found. board := findBoardFunc(pm, monitor, deviceURI) if board == nil { - return nil, fmt.Errorf(tr("no supported board found at %s"), deviceURI.String()) + return nil, status.Newf(codes.NotFound, tr("No supported board found at %s"), deviceURI.String()) } taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Board found: %s"), board.Name())}) @@ -104,7 +105,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta err = sk.ExportMetadata() if err != nil { - return nil, fmt.Errorf(tr("cannot export sketch metadata: %s"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Cannot export sketch metadata: %s"), err) } taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Selected fqbn: %s"), sk.Metadata.CPU.Fqbn), Completed: true}) return &rpc.BoardAttachResponse{}, nil diff --git a/commands/board/details.go b/commands/board/details.go index 5b8909300a2..9cd3239ff88 100644 --- a/commands/board/details.go +++ b/commands/board/details.go @@ -17,31 +17,31 @@ package board import ( "context" - "errors" - "fmt" "github.com/arduino/arduino-cli/arduino/cores" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // Details returns all details for a board including tools and HW identifiers. // This command basically gather al the information and translates it into the required grpc struct properties -func Details(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { +func Details(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } fqbn, err := cores.ParseFQBN(req.GetFqbn()) if err != nil { - return nil, fmt.Errorf(tr("parsing fqbn: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Error parsing fqbn: %s"), err) } boardPackage, boardPlatform, board, boardProperties, boardRefPlatform, err := pm.ResolveFQBN(fqbn) if err != nil { - return nil, fmt.Errorf(tr("loading board data: %s"), err) + return nil, status.Newf(codes.FailedPrecondition, tr("Error loading board data: %s"), err) } details := &rpc.BoardDetailsResponse{} diff --git a/commands/board/list.go b/commands/board/list.go index c6c2e8737ec..9e08ffe6c44 100644 --- a/commands/board/list.go +++ b/commands/board/list.go @@ -33,6 +33,8 @@ import ( "github.com/pkg/errors" "github.com/segmentio/stats/v4" "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var ( @@ -168,7 +170,7 @@ func identify(pm *packagemanager.PackageManager, port *discovery.Port) ([]*rpc.B } // List FIXMEDOC -func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e error) { +func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e *status.Status) { tags := map[string]string{} // Use defer func() to evaluate tags map when function returns // and set success flag inspecting the error named return parameter @@ -182,15 +184,15 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e error) { pm := commands.GetPackageManager(req.GetInstance().Id) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } dm := pm.DiscoveryManager() if errs := dm.RunAll(); len(errs) > 0 { - return nil, fmt.Errorf("%v", errs) + return nil, status.New(codes.FailedPrecondition, tr("Error getting port list: %v", errs)) } if errs := dm.StartAll(); len(errs) > 0 { - return nil, fmt.Errorf("%v", errs) + return nil, status.New(codes.FailedPrecondition, tr("Error getting port list: %v", errs)) } defer func() { if errs := dm.StopAll(); len(errs) > 0 { @@ -202,12 +204,12 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e error) { retVal := []*rpc.DetectedPort{} ports, errs := pm.DiscoveryManager().List() if len(errs) > 0 { - return nil, fmt.Errorf("%v", errs) + return nil, status.New(codes.FailedPrecondition, tr("Error getting port list: %v", errs)) } for _, port := range ports { boards, err := identify(pm, port) if err != nil { - return nil, err + return nil, status.New(codes.Internal, err.Error()) } // boards slice can be empty at this point if neither the cores nor the @@ -224,14 +226,14 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e error) { // Watch returns a channel that receives boards connection and disconnection events. // The discovery process can be interrupted by sending a message to the interrupt channel. -func Watch(instanceID int32, interrupt <-chan bool) (<-chan *rpc.BoardListWatchResponse, error) { +func Watch(instanceID int32, interrupt <-chan bool) (<-chan *rpc.BoardListWatchResponse, *status.Status) { pm := commands.GetPackageManager(instanceID) dm := pm.DiscoveryManager() runErrs := dm.RunAll() if len(runErrs) == len(dm.IDs()) { // All discoveries failed to run, we can't do anything - return nil, fmt.Errorf("%v", runErrs) + return nil, status.New(codes.FailedPrecondition, fmt.Sprintf("%v", runErrs)) } eventsChan, errs := dm.StartSyncAll() diff --git a/commands/board/listall.go b/commands/board/listall.go index be8553861f6..74fa859be56 100644 --- a/commands/board/listall.go +++ b/commands/board/listall.go @@ -17,19 +17,20 @@ package board import ( "context" - "errors" "strings" "github.com/arduino/arduino-cli/arduino/utils" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // ListAll FIXMEDOC -func ListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { +func ListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } searchArgs := strings.Join(req.GetSearchArgs(), " ") diff --git a/commands/board/search.go b/commands/board/search.go index 8847e0c712e..f35e9b57c5e 100644 --- a/commands/board/search.go +++ b/commands/board/search.go @@ -17,23 +17,24 @@ package board import ( "context" - "errors" "sort" "strings" "github.com/arduino/arduino-cli/arduino/utils" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // Search returns all boards that match the search arg. // Boards are searched in all platforms, including those in the index that are not yet // installed. Note that platforms that are not installed don't include boards' FQBNs. // If no search argument is used all boards are returned. -func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { +func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } res := &rpc.BoardSearchResponse{Boards: []*rpc.BoardListItem{}} diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index d81103b8680..131ffeeb395 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -43,14 +43,19 @@ var tr = i18n.Tr // BoardDetails FIXMEDOC func (s *ArduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { - return board.Details(ctx, req) + resp, err := board.Details(ctx, req) + if err != nil { + return nil, err.Err() + } + + return resp, nil } // BoardList FIXMEDOC func (s *ArduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { ports, err := board.List(req) if err != nil { - return nil, err + return nil, err.Err() } return &rpc.BoardListResponse{ @@ -60,12 +65,22 @@ func (s *ArduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardLis // BoardListAll FIXMEDOC func (s *ArduinoCoreServerImpl) BoardListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { - return board.ListAll(ctx, req) + resp, err := board.ListAll(ctx, req) + if err != nil { + return nil, err.Err() + } + + return resp, nil } // BoardSearch exposes to the gRPC interface the board search command func (s *ArduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { - return board.Search(ctx, req) + resp, err := board.Search(ctx, req) + if err != nil { + return nil, err.Err() + } + + return resp, nil } // BoardListWatch FIXMEDOC @@ -112,9 +127,9 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(stream rpc.ArduinoCoreService_Boa } }() - eventsChan, err := board.Watch(msg.Instance.Id, interrupt) - if err != nil { - return err + eventsChan, stat := board.Watch(msg.Instance.Id, interrupt) + if stat != nil { + return stat.Err() } for event := range eventsChan { @@ -134,7 +149,7 @@ func (s *ArduinoCoreServerImpl) BoardAttach(req *rpc.BoardAttachRequest, stream func(p *rpc.TaskProgress) { stream.Send(&rpc.BoardAttachResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } From 67c19f2cbfce593e1ab6b383e5616c4a644cac6a Mon Sep 17 00:00:00 2001 From: per1234 Date: Wed, 30 Jun 2021 09:06:14 -0700 Subject: [PATCH 03/19] Update gRPC API of remaining commands to return status.Status instead of error --- cli/compile/compile.go | 16 +-- cli/core/upgrade.go | 2 +- cli/debug/debug.go | 9 +- cli/instance/instance.go | 5 +- cli/lib/args.go | 4 +- cli/lib/check_deps.go | 6 +- commands/compile/compile.go | 37 +++---- commands/core/download.go | 15 +-- commands/core/install.go | 15 +-- commands/core/list.go | 9 +- commands/core/search.go | 7 +- commands/core/search_test.go | 32 +++--- commands/core/uninstall.go | 17 ++-- commands/core/upgrade.go | 10 +- commands/daemon/daemon.go | 61 +++++++----- commands/daemon/debug.go | 9 +- commands/debug/debug.go | 8 +- commands/debug/debug_info.go | 5 +- commands/instances.go | 146 ++++++++++++++-------------- commands/lib/download.go | 8 +- commands/lib/install.go | 40 ++++---- commands/lib/list.go | 16 +-- commands/lib/resolve_deps.go | 11 ++- commands/lib/search.go | 10 +- commands/lib/uninstall.go | 6 +- commands/lib/upgrade.go | 17 ++-- commands/sketch/archive.go | 19 ++-- commands/upload/programmers_list.go | 11 ++- 28 files changed, 288 insertions(+), 263 deletions(-) diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 7214bbce32e..4f6deb2e9ed 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -183,16 +183,16 @@ func run(cmd *cobra.Command, args []string) { compileErr := new(bytes.Buffer) verboseCompile := configuration.Settings.GetString("logging.level") == "debug" var compileRes *rpc.CompileResponse - var err error + var st *status.Status if output.OutputFormat == "json" { - compileRes, err = compile.Compile(context.Background(), compileRequest, compileOut, compileErr, verboseCompile) + compileRes, st = compile.Compile(context.Background(), compileRequest, compileOut, compileErr, verboseCompile) } else { - compileRes, err = compile.Compile(context.Background(), compileRequest, os.Stdout, os.Stderr, verboseCompile) + compileRes, st = compile.Compile(context.Background(), compileRequest, os.Stdout, os.Stderr, verboseCompile) } - if err == nil && uploadAfterCompile { + if st == nil && uploadAfterCompile { var sk *sketch.Sketch - sk, err = sketch.New(sketchPath) + sk, err := sketch.New(sketchPath) if err != nil { feedback.Errorf(tr("Error during Upload: %v"), err) os.Exit(errorcodes.ErrGeneric) @@ -250,10 +250,10 @@ func run(cmd *cobra.Command, args []string) { CompileOut: compileOut.String(), CompileErr: compileErr.String(), BuilderResult: compileRes, - Success: err == nil, + Success: st == nil, }) - if err != nil && output.OutputFormat != "json" { - feedback.Errorf(tr("Error during build: %v"), err) + if st != nil && output.OutputFormat != "json" { + feedback.Errorf(tr("Error during build: %v"), st.Message()) os.Exit(errorcodes.ErrGeneric) } } diff --git a/cli/core/upgrade.go b/cli/core/upgrade.go index 203e75c823d..a29f61b988d 100644 --- a/cli/core/upgrade.go +++ b/cli/core/upgrade.go @@ -95,7 +95,7 @@ func runUpgradeCommand(cmd *cobra.Command, args []string) { } _, err := core.PlatformUpgrade(context.Background(), r, output.ProgressBar(), output.TaskProgress()) - if err == core.ErrAlreadyLatest { + if err.Message() == core.ErrAlreadyLatest.Error() { feedback.Printf(tr("Platform %s is already at the latest version"), platformRef) } else if err != nil { feedback.Errorf(tr("Error during upgrade: %v"), err) diff --git a/cli/debug/debug.go b/cli/debug/debug.go index 8cdd60035ce..3f9aef47c7d 100644 --- a/cli/debug/debug.go +++ b/cli/debug/debug.go @@ -34,7 +34,6 @@ import ( "github.com/arduino/go-properties-orderedmap" "github.com/fatih/color" "github.com/spf13/cobra" - "google.golang.org/grpc/status" ) var ( @@ -101,12 +100,8 @@ func run(command *cobra.Command, args []string) { if printInfo { if res, err := debug.GetDebugConfig(context.Background(), debugConfigRequested); err != nil { - if status, ok := status.FromError(err); ok { - feedback.Errorf(tr("Error getting Debug info: %v"), status.Message()) - errorcodes.ExitWithGrpcStatus(status) - } - feedback.Errorf(tr("Error getting Debug info: %v"), err) - os.Exit(errorcodes.ErrGeneric) + feedback.Errorf(tr("Error getting Debug info: %v"), err.Message()) + errorcodes.ExitWithGrpcStatus(err) } else { feedback.PrintResult(&debugInfoResult{res}) } diff --git a/cli/instance/instance.go b/cli/instance/instance.go index 2e09f34fa8b..b0a9532014f 100644 --- a/cli/instance/instance.go +++ b/cli/instance/instance.go @@ -27,7 +27,6 @@ import ( "github.com/arduino/arduino-cli/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" - "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) @@ -120,7 +119,7 @@ func FirstUpdate(instance *rpc.Instance) *status.Status { output.ProgressBar(), ) if err != nil { - return status.Newf(codes.FailedPrecondition, err.Error()) + return err } } @@ -135,7 +134,7 @@ func FirstUpdate(instance *rpc.Instance) *status.Status { output.ProgressBar(), ) if err != nil { - return status.Newf(codes.FailedPrecondition, err.Error()) + return err } } diff --git a/cli/lib/args.go b/cli/lib/args.go index 306e0aca5b4..08f98068a4c 100644 --- a/cli/lib/args.go +++ b/cli/lib/args.go @@ -75,13 +75,13 @@ func ParseLibraryReferenceArgs(args []string) ([]*LibraryReferenceArg, error) { // ParseLibraryReferenceArgAndAdjustCase parse a command line argument that reference a // library and possibly adjust the case of the name to match a library in the index func ParseLibraryReferenceArgAndAdjustCase(instance *rpc.Instance, arg string) (*LibraryReferenceArg, error) { - libRef, err := ParseLibraryReferenceArg(arg) + libRef, _ := ParseLibraryReferenceArg(arg) res, err := lib.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ Instance: instance, Query: libRef.Name, }) if err != nil { - return nil, err + return nil, err.Err() } candidates := []*rpc.SearchedLibrary{} diff --git a/cli/lib/check_deps.go b/cli/lib/check_deps.go index 05056634bb3..87e556d4bd1 100644 --- a/cli/lib/check_deps.go +++ b/cli/lib/check_deps.go @@ -51,13 +51,13 @@ func runDepsCommand(cmd *cobra.Command, args []string) { os.Exit(errorcodes.ErrBadArgument) } - deps, err := lib.LibraryResolveDependencies(context.Background(), &rpc.LibraryResolveDependenciesRequest{ + deps, stat := lib.LibraryResolveDependencies(context.Background(), &rpc.LibraryResolveDependenciesRequest{ Instance: instance, Name: libRef.Name, Version: libRef.Version, }) - if err != nil { - feedback.Errorf(tr("Error resolving dependencies for %[1]s: %[2]s"), libRef, err) + if stat != nil { + feedback.Errorf(tr("Error resolving dependencies for %[1]s: %[2]s", libRef, err)) } feedback.PrintResult(&checkDepResult{deps: deps}) diff --git a/commands/compile/compile.go b/commands/compile/compile.go index ab41d31c329..0838b5852f6 100644 --- a/commands/compile/compile.go +++ b/commands/compile/compile.go @@ -17,7 +17,6 @@ package compile import ( "context" - "fmt" "io" "path/filepath" "sort" @@ -41,12 +40,14 @@ import ( "github.com/pkg/errors" "github.com/segmentio/stats/v4" "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var tr = i18n.Tr // Compile FIXMEDOC -func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream io.Writer, debug bool) (r *rpc.CompileResponse, e error) { +func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream io.Writer, debug bool) (r *rpc.CompileResponse, e *status.Status) { // There is a binding between the export binaries setting and the CLI flag to explicitly set it, // since we want this binding to work also for the gRPC interface we must read it here in this @@ -90,17 +91,17 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } logrus.Tracef("Compile %s for %s started", req.GetSketchPath(), req.GetFqbn()) if req.GetSketchPath() == "" { - return nil, fmt.Errorf(tr("missing sketchPath")) + return nil, status.New(codes.InvalidArgument, tr("Missing sketch path")) } sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil { - return nil, fmt.Errorf(tr("opening sketch: %s"), err) + return nil, status.Newf(codes.NotFound, tr("Error opening sketch: %s"), err) } fqbnIn := req.GetFqbn() @@ -108,11 +109,11 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream fqbnIn = sk.Metadata.CPU.Fqbn } if fqbnIn == "" { - return nil, fmt.Errorf(tr("no FQBN provided")) + return nil, status.New(codes.InvalidArgument, tr("No FQBN (Fully Qualified Board Name) provided")) } fqbn, err := cores.ParseFQBN(fqbnIn) if err != nil { - return nil, fmt.Errorf(tr("incorrect FQBN: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Invalid FQBN: %s"), err) } targetPlatform := pm.FindPlatform(&packagemanager.PlatformReference{ @@ -125,7 +126,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream // "\"%[1]s:%[2]s\" platform is not installed, please install it by running \""+ // version.GetAppName()+" core install %[1]s:%[2]s\".", fqbn.Package, fqbn.PlatformArch) // feedback.Error(errorMessage) - return nil, fmt.Errorf(tr("platform not installed")) + return nil, status.New(codes.NotFound, tr("Platform not installed")) } builderCtx := &types.Context{} @@ -148,7 +149,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream builderCtx.BuildPath = paths.New(req.GetBuildPath()) } if err = builderCtx.BuildPath.MkdirAll(); err != nil { - return nil, fmt.Errorf(tr("cannot create build directory: %s"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Cannot create build directory: %s"), err) } builderCtx.CompilationDatabase = bldr.NewCompilationDatabase( builderCtx.BuildPath.Join("compile_commands.json"), @@ -178,7 +179,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream builderCtx.BuildCachePath = paths.New(req.GetBuildCachePath()) err = builderCtx.BuildCachePath.MkdirAll() if err != nil { - return nil, fmt.Errorf(tr("cannot create build cache directory: %s"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Cannot create build cache directory: %s"), err) } } @@ -221,14 +222,14 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream // if --preprocess or --show-properties were passed, we can stop here if req.GetShowProperties() { - return r, builder.RunParseHardwareAndDumpBuildProperties(builderCtx) + return r, status.Convert(builder.RunParseHardwareAndDumpBuildProperties(builderCtx)) } else if req.GetPreprocess() { - return r, builder.RunPreprocess(builderCtx) + return r, status.Convert(builder.RunPreprocess(builderCtx)) } // if it's a regular build, go on... if err := builder.RunBuilder(builderCtx); err != nil { - return r, err + return r, status.Convert(err) } // If the export directory is set we assume you want to export the binaries @@ -250,17 +251,17 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream } logrus.WithField("path", exportPath).Trace("Saving sketch to export path.") if err := exportPath.MkdirAll(); err != nil { - return r, errors.Wrap(err, tr("creating output dir")) + return r, status.New(codes.PermissionDenied, errors.Wrap(err, tr("Error creating output dir")).Error()) } // Copy all "sketch.ino.*" artifacts to the export directory baseName, ok := builderCtx.BuildProperties.GetOk("build.project_name") // == "sketch.ino" if !ok { - return r, errors.New(tr("missing 'build.project_name' build property")) + return r, status.New(codes.Internal, tr("Missing 'build.project_name' build property")) } buildFiles, err := builderCtx.BuildPath.ReadDir() if err != nil { - return r, errors.Errorf(tr("reading build directory: %s"), err) + return r, status.Newf(codes.PermissionDenied, tr("Error reading build directory: %s"), err) } buildFiles.FilterPrefix(baseName) for _, buildFile := range buildFiles { @@ -270,7 +271,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream WithField("dest", exportedFile). Trace("Copying artifact.") if err = buildFile.CopyTo(exportedFile); err != nil { - return r, errors.Wrapf(err, tr("copying output file %s"), buildFile) + return r, status.New(codes.PermissionDenied, tr("Error copying output file %[1]s: %[2]s", buildFile, err)) } } } @@ -279,7 +280,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream for _, lib := range builderCtx.ImportedLibraries { rpcLib, err := lib.ToRPCLibrary() if err != nil { - return r, fmt.Errorf(tr("converting library %[1]s to rpc struct: %[2]w"), lib.Name, err) + return r, status.Newf(codes.PermissionDenied, tr("Error converting library %[1]s to rpc struct: %[2]s", lib.Name, err)) } importedLibs = append(importedLibs, rpcLib) } diff --git a/commands/core/download.go b/commands/core/download.go index 36c46b3dbaf..6d76a2739e4 100644 --- a/commands/core/download.go +++ b/commands/core/download.go @@ -17,7 +17,6 @@ package core import ( "context" - "errors" "fmt" "github.com/arduino/arduino-cli/arduino/cores" @@ -25,20 +24,22 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var tr = i18n.Tr // PlatformDownload FIXMEDOC -func PlatformDownload(ctx context.Context, req *rpc.PlatformDownloadRequest, downloadCB commands.DownloadProgressCB) (*rpc.PlatformDownloadResponse, error) { +func PlatformDownload(ctx context.Context, req *rpc.PlatformDownloadRequest, downloadCB commands.DownloadProgressCB) (*rpc.PlatformDownloadResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } version, err := commands.ParseVersion(req) if err != nil { - return nil, fmt.Errorf(tr("invalid version: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Invalid version: %s"), err) } platform, tools, err := pm.FindPlatformReleaseDependencies(&packagemanager.PlatformReference{ @@ -47,18 +48,18 @@ func PlatformDownload(ctx context.Context, req *rpc.PlatformDownloadRequest, dow PlatformVersion: version, }) if err != nil { - return nil, fmt.Errorf(tr("find platform dependencies: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Error finding platform dependencies: %s"), err) } err = downloadPlatform(pm, platform, downloadCB) if err != nil { - return nil, err + return nil, status.New(codes.Unavailable, err.Error()) } for _, tool := range tools { err := downloadTool(pm, tool, downloadCB) if err != nil { - return nil, fmt.Errorf(tr("downloading tool %[1]s: %[2]s"), tool, err) + return nil, status.Newf(codes.Unavailable, tr("Error downloading tool %[1]s: %[2]s"), tool, err) } } diff --git a/commands/core/install.go b/commands/core/install.go index 2655614e722..f30f9bc45af 100644 --- a/commands/core/install.go +++ b/commands/core/install.go @@ -23,21 +23,22 @@ import ( "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "github.com/pkg/errors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // PlatformInstall FIXMEDOC func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest, - downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformInstallResponse, error) { + downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformInstallResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } version, err := commands.ParseVersion(req) if err != nil { - return nil, fmt.Errorf(tr("invalid version: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Invalid version: %s"), err) } platform, tools, err := pm.FindPlatformReleaseDependencies(&packagemanager.PlatformReference{ @@ -46,17 +47,17 @@ func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest, PlatformVersion: version, }) if err != nil { - return nil, fmt.Errorf(tr("finding platform dependencies: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Error finding platform dependencies: %s"), err) } err = installPlatform(pm, platform, tools, downloadCB, taskCB, req.GetSkipPostInstall()) if err != nil { - return nil, err + return nil, status.Convert(err) } status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) if status != nil { - return nil, status.Err() + return nil, status } return &rpc.PlatformInstallResponse{}, nil diff --git a/commands/core/list.go b/commands/core/list.go index 167e6fd6c7c..ec816bbf919 100644 --- a/commands/core/list.go +++ b/commands/core/list.go @@ -22,21 +22,22 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "github.com/pkg/errors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // GetPlatforms returns a list of installed platforms, optionally filtered by // those requiring an update. -func GetPlatforms(req *rpc.PlatformListRequest) ([]*rpc.Platform, error) { +func GetPlatforms(req *rpc.PlatformListRequest) ([]*rpc.Platform, *status.Status) { instanceID := req.Instance.Id i := commands.GetInstance(instanceID) if i == nil { - return nil, errors.Errorf(tr("unable to find an instance with ID: %d"), instanceID) + return nil, status.Newf(codes.InvalidArgument, tr("Invalid instance")) } packageManager := i.PackageManager if packageManager == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } res := []*rpc.Platform{} diff --git a/commands/core/search.go b/commands/core/search.go index 93ea1bb95a3..d92eaa9c20a 100644 --- a/commands/core/search.go +++ b/commands/core/search.go @@ -16,7 +16,6 @@ package core import ( - "errors" "regexp" "sort" "strings" @@ -25,6 +24,8 @@ import ( "github.com/arduino/arduino-cli/arduino/utils" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // maximumSearchDistance is the maximum Levenshtein distance accepted when using fuzzy search. @@ -32,12 +33,12 @@ import ( const maximumSearchDistance = 20 // PlatformSearch FIXMEDOC -func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { +func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, *status.Status) { searchArgs := strings.TrimSpace(req.SearchArgs) allVersions := req.AllVersions pm := commands.GetPackageManager(req.Instance.Id) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } res := []*cores.PlatformRelease{} diff --git a/commands/core/search_test.go b/commands/core/search_test.go index cf51a05cb35..5e262fbb23e 100644 --- a/commands/core/search_test.go +++ b/commands/core/search_test.go @@ -44,12 +44,12 @@ func TestPlatformSearch(t *testing.T) { inst := instance.CreateAndInit() require.NotNil(t, inst) - res, err := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "retrokit", AllVersions: true, }) - require.Nil(t, err) + require.Nil(t, stat) require.NotNil(t, res) require.Len(t, res.SearchOutput, 2) @@ -74,12 +74,12 @@ func TestPlatformSearch(t *testing.T) { Boards: []*commands.Board{{Name: "RK002"}}, }) - res, err = PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat = PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "retrokit", AllVersions: false, }) - require.Nil(t, err) + require.Nil(t, stat) require.NotNil(t, res) require.Len(t, res.SearchOutput, 1) require.Contains(t, res.SearchOutput, &commands.Platform{ @@ -94,12 +94,12 @@ func TestPlatformSearch(t *testing.T) { }) // Search the Package Maintainer - res, err = PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat = PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "Retrokits (www.retrokits.com)", AllVersions: true, }) - require.Nil(t, err) + require.Nil(t, stat) require.NotNil(t, res) require.Len(t, res.SearchOutput, 2) require.Contains(t, res.SearchOutput, &commands.Platform{ @@ -124,12 +124,12 @@ func TestPlatformSearch(t *testing.T) { }) // Search using the Package name - res, err = PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat = PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "Retrokits-RK002", AllVersions: true, }) - require.Nil(t, err) + require.Nil(t, stat) require.NotNil(t, res) require.Len(t, res.SearchOutput, 2) require.Contains(t, res.SearchOutput, &commands.Platform{ @@ -154,12 +154,12 @@ func TestPlatformSearch(t *testing.T) { }) // Search using the Platform name - res, err = PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat = PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "rk002", AllVersions: true, }) - require.Nil(t, err) + require.Nil(t, stat) require.NotNil(t, res) require.Len(t, res.SearchOutput, 2) require.Contains(t, res.SearchOutput, &commands.Platform{ @@ -184,12 +184,12 @@ func TestPlatformSearch(t *testing.T) { }) // Search using a board name - res, err = PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat = PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "Yún", AllVersions: true, }) - require.Nil(t, err) + require.Nil(t, stat) require.NotNil(t, res) require.Len(t, res.SearchOutput, 1) require.Contains(t, res.SearchOutput, &commands.Platform{ @@ -230,12 +230,12 @@ func TestPlatformSearch(t *testing.T) { }, }) - res, err = PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat = PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "yun", AllVersions: true, }) - require.Nil(t, err) + require.Nil(t, stat) require.NotNil(t, res) require.Len(t, res.SearchOutput, 1) require.Contains(t, res.SearchOutput, &commands.Platform{ @@ -293,12 +293,12 @@ func TestPlatformSearchSorting(t *testing.T) { inst := instance.CreateAndInit() require.NotNil(t, inst) - res, err := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "", AllVersions: false, }) - require.Nil(t, err) + require.Nil(t, stat) require.NotNil(t, res) require.Len(t, res.SearchOutput, 3) diff --git a/commands/core/uninstall.go b/commands/core/uninstall.go index 2628c50ff4c..b5f9a1af4ae 100644 --- a/commands/core/uninstall.go +++ b/commands/core/uninstall.go @@ -17,20 +17,21 @@ package core import ( "context" - "errors" "fmt" "github.com/arduino/arduino-cli/arduino/cores" "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // PlatformUninstall FIXMEDOC -func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, taskCB commands.TaskProgressCB) (*rpc.PlatformUninstallResponse, error) { +func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, taskCB commands.TaskProgressCB) (*rpc.PlatformUninstallResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } ref := &packagemanager.PlatformReference{ @@ -40,12 +41,12 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, t if ref.PlatformVersion == nil { platform := pm.FindPlatform(ref) if platform == nil { - return nil, fmt.Errorf(tr("platform not found: %s"), ref) + return nil, status.Newf(codes.InvalidArgument, tr("Platform not found: %s"), ref) } platformRelease := pm.GetInstalledPlatformRelease(platform) if platformRelease == nil { - return nil, fmt.Errorf(tr("platform not installed: %s"), ref) + return nil, status.Newf(codes.InvalidArgument, tr("Platform not installed: %s"), ref) } ref.PlatformVersion = platformRelease.Version @@ -53,12 +54,12 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, t platform, tools, err := pm.FindPlatformReleaseDependencies(ref) if err != nil { - return nil, fmt.Errorf(tr("finding platform dependencies: %s"), err) + return nil, status.Newf(codes.Internal, tr("Error finding platform dependencies: %s"), err) } err = uninstallPlatformRelease(pm, platform, taskCB) if err != nil { - return nil, err + return nil, status.New(codes.PermissionDenied, err.Error()) } for _, tool := range tools { @@ -69,7 +70,7 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, t status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) if status != nil { - return nil, status.Err() + return nil, status } return &rpc.PlatformUninstallResponse{}, nil diff --git a/commands/core/upgrade.go b/commands/core/upgrade.go index d725f669aff..89f160c43cb 100644 --- a/commands/core/upgrade.go +++ b/commands/core/upgrade.go @@ -23,6 +23,8 @@ import ( "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var ( @@ -33,11 +35,11 @@ var ( // PlatformUpgrade FIXMEDOC func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, - downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformUpgradeResponse, error) { + downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformUpgradeResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } // Extract all PlatformReference to platforms that have updates @@ -46,12 +48,12 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, PlatformArchitecture: req.Architecture, } if err := upgradePlatform(pm, ref, downloadCB, taskCB, req.GetSkipPostInstall()); err != nil { - return nil, err + return nil, status.Convert(err) } status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) if status != nil { - return nil, status.Err() + return nil, status } return &rpc.PlatformUpgradeResponse{}, nil diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index 131ffeeb395..72acc4e2732 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -48,7 +48,7 @@ func (s *ArduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.Board return nil, err.Err() } - return resp, nil + return resp, err.Err() } // BoardList FIXMEDOC @@ -156,7 +156,8 @@ func (s *ArduinoCoreServerImpl) BoardAttach(req *rpc.BoardAttachRequest, stream // Destroy FIXMEDOC func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { - return commands.Destroy(ctx, req) + resp, err := commands.Destroy(ctx, req) + return resp, err.Err() } // UpdateIndex FIXMEDOC @@ -165,7 +166,7 @@ func (s *ArduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream func(p *rpc.DownloadProgress) { stream.Send(&rpc.UpdateIndexResponse{DownloadProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } @@ -176,7 +177,7 @@ func (s *ArduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd func(p *rpc.DownloadProgress) { stream.Send(&rpc.UpdateLibrariesIndexResponse{DownloadProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(&rpc.UpdateLibrariesIndexResponse{}) } @@ -187,14 +188,15 @@ func (s *ArduinoCoreServerImpl) UpdateCoreLibrariesIndex(req *rpc.UpdateCoreLibr func(p *rpc.DownloadProgress) { stream.Send(&rpc.UpdateCoreLibrariesIndexResponse{DownloadProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(&rpc.UpdateCoreLibrariesIndexResponse{}) } // Outdated FIXMEDOC func (s *ArduinoCoreServerImpl) Outdated(ctx context.Context, req *rpc.OutdatedRequest) (*rpc.OutdatedResponse, error) { - return commands.Outdated(ctx, req) + resp, err := commands.Outdated(ctx, req) + return resp, err.Err() } // Upgrade FIXMEDOC @@ -212,7 +214,7 @@ func (s *ArduinoCoreServerImpl) Upgrade(req *rpc.UpgradeRequest, stream rpc.Ardu }, ) if err != nil { - return err + return err.Err() } return stream.Send(&rpc.UpgradeResponse{}) } @@ -244,7 +246,8 @@ func (s *ArduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionReq // LoadSketch FIXMEDOC func (s *ArduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { - return commands.LoadSketch(ctx, req) + resp, err := commands.LoadSketch(ctx, req) + return resp, err.Err() } // Compile FIXMEDOC @@ -255,7 +258,7 @@ func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu utils.FeedStreamTo(func(data []byte) { stream.Send(&rpc.CompileResponse{ErrStream: data}) }), false) // Set debug to false if err != nil { - return err + return err.Err() } return stream.Send(resp) } @@ -268,7 +271,7 @@ func (s *ArduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } @@ -280,7 +283,7 @@ func (s *ArduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadReques func(p *rpc.DownloadProgress) { stream.Send(&rpc.PlatformDownloadResponse{Progress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } @@ -292,7 +295,7 @@ func (s *ArduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequ func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } @@ -305,21 +308,22 @@ func (s *ArduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformUpgradeResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } // PlatformSearch FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformSearch(ctx context.Context, req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { - return core.PlatformSearch(req) + resp, err := core.PlatformSearch(req) + return resp, err.Err() } // PlatformList FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformList(ctx context.Context, req *rpc.PlatformListRequest) (*rpc.PlatformListResponse, error) { platforms, err := core.GetPlatforms(req) if err != nil { - return nil, err + return nil, err.Err() } return &rpc.PlatformListResponse{InstalledPlatforms: platforms}, nil } @@ -365,7 +369,8 @@ func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, s // ListProgrammersAvailableForUpload FIXMEDOC func (s *ArduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { - return upload.ListProgrammersAvailableForUpload(ctx, req) + resp, err := upload.ListProgrammersAvailableForUpload(ctx, req) + return resp, err.Err() } // LibraryDownload FIXMEDOC @@ -375,7 +380,7 @@ func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, func(p *rpc.DownloadProgress) { stream.Send(&rpc.LibraryDownloadResponse{Progress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(resp) } @@ -388,7 +393,7 @@ func (s *ArduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(&rpc.LibraryInstallResponse{}) } @@ -399,7 +404,7 @@ func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallReques func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(&rpc.LibraryUninstallResponse{}) } @@ -411,29 +416,33 @@ func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequ func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(&rpc.LibraryUpgradeAllResponse{}) } // LibraryResolveDependencies FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { - return lib.LibraryResolveDependencies(ctx, req) + resp, err := lib.LibraryResolveDependencies(ctx, req) + return resp, err.Err() } // LibrarySearch FIXMEDOC func (s *ArduinoCoreServerImpl) LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { - return lib.LibrarySearch(ctx, req) + resp, err := lib.LibrarySearch(ctx, req) + return resp, err.Err() } // LibraryList FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { - return lib.LibraryList(ctx, req) + resp, err := lib.LibraryList(ctx, req) + return resp, err.Err() } // ArchiveSketch FIXMEDOC func (s *ArduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { - return sketch.ArchiveSketch(ctx, req) + resp, err := sketch.ArchiveSketch(ctx, req) + return resp, err.Err() } //ZipLibraryInstall FIXMEDOC @@ -443,7 +452,7 @@ func (s *ArduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequ func(p *rpc.TaskProgress) { stream.Send(&rpc.ZipLibraryInstallResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(&rpc.ZipLibraryInstallResponse{}) } @@ -455,7 +464,7 @@ func (s *ArduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequ func(p *rpc.TaskProgress) { stream.Send(&rpc.GitLibraryInstallResponse{TaskProgress: p}) }, ) if err != nil { - return err + return err.Err() } return stream.Send(&rpc.GitLibraryInstallResponse{}) } diff --git a/commands/daemon/debug.go b/commands/daemon/debug.go index 09a441527e3..1ef38dca476 100644 --- a/commands/daemon/debug.go +++ b/commands/daemon/debug.go @@ -50,7 +50,7 @@ func (s *DebugService) Debug(stream dbg.DebugService_DebugServer) error { // Launch debug recipe attaching stdin and out to grpc streaming signalChan := make(chan os.Signal) defer close(signalChan) - resp, err := cmd.Debug(stream.Context(), req, + resp, stat := cmd.Debug(stream.Context(), req, utils.ConsumeStreamFrom(func() ([]byte, error) { command, err := stream.Recv() if command.GetSendInterrupt() { @@ -62,13 +62,14 @@ func (s *DebugService) Debug(stream dbg.DebugService_DebugServer) error { stream.Send(&dbg.DebugResponse{Data: data}) }), signalChan) - if err != nil { - return (err) + if stat != nil { + return stat.Err() } return stream.Send(resp) } // GetDebugConfig return metadata about a debug session func (s *DebugService) GetDebugConfig(ctx context.Context, req *dbg.DebugConfigRequest) (*dbg.GetDebugConfigResponse, error) { - return cmd.GetDebugConfig(ctx, req) + resp, err := cmd.GetDebugConfig(ctx, req) + return resp, err.Err() } diff --git a/commands/debug/debug.go b/commands/debug/debug.go index 4ce0b2e2218..dc7865d2ef0 100644 --- a/commands/debug/debug.go +++ b/commands/debug/debug.go @@ -32,6 +32,8 @@ import ( "github.com/arduino/go-paths-helper" "github.com/pkg/errors" "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var tr = i18n.Tr @@ -42,13 +44,13 @@ var tr = i18n.Tr // grpc Out <- tool stdOut // grpc Out <- tool stdErr // It also implements tool process lifecycle management -func Debug(ctx context.Context, req *dbg.DebugConfigRequest, inStream io.Reader, out io.Writer, interrupt <-chan os.Signal) (*dbg.DebugResponse, error) { +func Debug(ctx context.Context, req *dbg.DebugConfigRequest, inStream io.Reader, out io.Writer, interrupt <-chan os.Signal) (*dbg.DebugResponse, *status.Status) { // Get debugging command line to run debugger pm := commands.GetPackageManager(req.GetInstance().GetId()) commandLine, err := getCommandLine(req, pm) if err != nil { - return nil, errors.Wrap(err, tr("Cannot get command line for tool")) + return nil, status.New(codes.FailedPrecondition, tr("Cannot get command line for tool: %s", err)) } for i, arg := range commandLine { @@ -64,7 +66,7 @@ func Debug(ctx context.Context, req *dbg.DebugConfigRequest, inStream io.Reader, cmd, err := executils.NewProcess(commandLine...) if err != nil { - return nil, errors.Wrap(err, tr("Cannot execute debug tool")) + return nil, status.New(codes.FailedPrecondition, tr("Cannot execute debug tool: %s", err)) } // Get stdIn pipe from tool diff --git a/commands/debug/debug_info.go b/commands/debug/debug_info.go index 27517869b7f..014a0b41155 100644 --- a/commands/debug/debug_info.go +++ b/commands/debug/debug_info.go @@ -34,10 +34,11 @@ import ( ) // GetDebugConfig returns metadata to start debugging with the specified board -func GetDebugConfig(ctx context.Context, req *debug.DebugConfigRequest) (*debug.GetDebugConfigResponse, error) { +func GetDebugConfig(ctx context.Context, req *debug.DebugConfigRequest) (*debug.GetDebugConfigResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) - return getDebugProperties(req, pm) + resp, err := getDebugProperties(req, pm) + return resp, status.Convert(err) } func getDebugProperties(req *debug.DebugConfigRequest, pm *packagemanager.PackageManager) (*debug.GetDebugConfigResponse, error) { diff --git a/commands/instances.go b/commands/instances.go index 1e0e27c4443..9b83731dff2 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -338,10 +338,10 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) *sta } // Destroy FIXMEDOC -func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { +func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, *status.Status) { id := req.GetInstance().GetId() if _, ok := instances[id]; !ok { - return nil, fmt.Errorf(tr("invalid handle")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } delete(instances, id) @@ -349,25 +349,25 @@ func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse } // UpdateLibrariesIndex updates the library_index.json -func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequest, downloadCB func(*rpc.DownloadProgress)) error { +func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequest, downloadCB func(*rpc.DownloadProgress)) *status.Status { logrus.Info("Updating libraries index") lm := GetLibraryManager(req.GetInstance().GetId()) if lm == nil { - return fmt.Errorf(tr("invalid handle")) + return status.New(codes.InvalidArgument, tr("Invalid instance")) } config, err := GetDownloaderConfig() if err != nil { - return err + return status.New(codes.FailedPrecondition, err.Error()) } if err := lm.IndexFile.Parent().MkdirAll(); err != nil { - return err + return status.New(codes.PermissionDenied, err.Error()) } // Create a temp dir to stage all downloads tmp, err := paths.MkTempDir("", "library_index_download") if err != nil { - return err + return status.New(codes.PermissionDenied, err.Error()) } defer tmp.RemoveAll() @@ -375,54 +375,54 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequ tmpIndexGz := tmp.Join("library_index.json.gz") if d, err := downloader.DownloadWithConfig(tmpIndexGz.String(), librariesmanager.LibraryIndexGZURL.String(), *config, downloader.NoResume); err == nil { if err := Download(d, tr("Updating index: library_index.json.gz"), downloadCB); err != nil { - return errors.Wrap(err, tr("downloading library_index.json.gz")) + return status.New(codes.Unavailable, errors.Wrap(err, tr("Error downloading library_index.json.gz")).Error()) } } else { - return err + return status.New(codes.Unavailable, err.Error()) } // Download signature tmpSignature := tmp.Join("library_index.json.sig") if d, err := downloader.DownloadWithConfig(tmpSignature.String(), librariesmanager.LibraryIndexSignature.String(), *config, downloader.NoResume); err == nil { if err := Download(d, tr("Updating index: library_index.json.sig"), downloadCB); err != nil { - return errors.Wrap(err, tr("downloading library_index.json.sig")) + return status.New(codes.Unavailable, errors.Wrap(err, tr("Error downloading library_index.json.sig")).Error()) } } else { - return err + return status.New(codes.Unavailable, err.Error()) } // Extract the real library_index tmpIndex := tmp.Join("library_index.json") if err := paths.GUnzip(tmpIndexGz, tmpIndex); err != nil { - return errors.Wrap(err, tr("unzipping library_index.json.gz")) + return status.New(codes.Unknown, errors.Wrap(err, tr("Error extracting library_index.json.gz")).Error()) } // Check signature if ok, _, err := security.VerifyArduinoDetachedSignature(tmpIndex, tmpSignature); err != nil { - return errors.Wrap(err, tr("verifying signature")) + return status.New(codes.Unknown, errors.Wrap(err, tr("Error verifying signature")).Error()) } else if !ok { - return errors.New(tr("library_index.json has an invalid signature")) + return status.New(codes.Unavailable, errors.New(tr("library_index.json has an invalid signature")).Error()) } // Copy extracted library_index and signature to final destination lm.IndexFile.Remove() lm.IndexFileSignature.Remove() if err := tmpIndex.CopyTo(lm.IndexFile); err != nil { - return errors.Wrap(err, tr("writing library_index.json")) + return status.New(codes.PermissionDenied, errors.Wrap(err, tr("Error writing library_index.json")).Error()) } if err := tmpSignature.CopyTo(lm.IndexFileSignature); err != nil { - return errors.Wrap(err, tr("writing library_index.json.sig")) + return status.New(codes.PermissionDenied, errors.Wrap(err, tr("Error writing library_index.json.sig")).Error()) } return nil } // UpdateIndex FIXMEDOC -func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB DownloadProgressCB) (*rpc.UpdateIndexResponse, error) { +func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB DownloadProgressCB) (*rpc.UpdateIndexResponse, *status.Status) { id := req.GetInstance().GetId() _, ok := instances[id] if !ok { - return nil, fmt.Errorf(tr("invalid handle")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } indexpath := paths.New(configuration.Settings.GetString("directories.Data")) @@ -442,7 +442,7 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do if URL.Scheme == "file" { path := paths.New(URL.Path) if _, err := packageindex.LoadIndexNoSign(path); err != nil { - return nil, fmt.Errorf(tr("invalid package index in %[1]s: %[2]s"), path, err) + return nil, status.Newf(codes.FailedPrecondition, tr("Invalid package index in %[1]s: %[2]s"), path, err) } fi, _ := os.Stat(path.String()) @@ -456,9 +456,9 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do var tmp *paths.Path if tmpFile, err := ioutil.TempFile("", ""); err != nil { - return nil, fmt.Errorf(tr("creating temp file for index download: %s"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Error creating temp file for index download: %s"), err) } else if err := tmpFile.Close(); err != nil { - return nil, fmt.Errorf(tr("creating temp file for index download: %s"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Error creating temp file for index download: %s"), err) } else { tmp = paths.New(tmpFile.Name()) } @@ -466,16 +466,16 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do config, err := GetDownloaderConfig() if err != nil { - return nil, fmt.Errorf(tr("downloading index %[1]s: %[2]s"), URL, err) + return nil, status.Newf(codes.FailedPrecondition, tr("Error downloading index %[1]s: %[2]s"), URL, err) } d, err := downloader.DownloadWithConfig(tmp.String(), URL.String(), *config) if err != nil { - return nil, fmt.Errorf(tr("downloading index %[1]s: %[2]s"), URL, err) + return nil, status.Newf(codes.Unavailable, tr("Error downloading index %[1]s: %[2]s"), URL, err) } coreIndexPath := indexpath.Join(path.Base(URL.Path)) err = Download(d, fmt.Sprintf(tr("Updating index: %s"), coreIndexPath.Base()), downloadCB) if err != nil { - return nil, fmt.Errorf(tr("downloading index %[1]s: %[2]s"), URL, err) + return nil, status.Newf(codes.Unavailable, tr("Error downloading index %[1]s: %[2]s"), URL, err) } // Check for signature @@ -484,14 +484,14 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do if URL.Hostname() == "downloads.arduino.cc" { URLSig, err := url.Parse(URL.String()) if err != nil { - return nil, fmt.Errorf(tr("parsing url for index signature check: %s"), err) + return nil, status.Newf(codes.FailedPrecondition, tr("Error parsing url for index signature check: %s"), err) } URLSig.Path += ".sig" if t, err := ioutil.TempFile("", ""); err != nil { - return nil, fmt.Errorf(tr("creating temp file for index signature download: %s"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Error creating temp file for index signature download: %s"), err) } else if err := t.Close(); err != nil { - return nil, fmt.Errorf(tr("creating temp file for index signature download: %s"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Error creating temp file for index signature download: %s"), err) } else { tmpSig = paths.New(t.Name()) } @@ -499,38 +499,38 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do d, err := downloader.DownloadWithConfig(tmpSig.String(), URLSig.String(), *config) if err != nil { - return nil, fmt.Errorf("downloading index signature %s: %s", URLSig, err) + return nil, status.Newf(codes.Unavailable, "downloading index signature %s: %s", URLSig, err) } coreIndexSigPath = indexpath.Join(path.Base(URLSig.Path)) Download(d, fmt.Sprintf(tr("Updating index: %s"), coreIndexSigPath.Base()), downloadCB) if d.Error() != nil { - return nil, fmt.Errorf(tr("downloading index signature %[1]s: %[2]s"), URL, d.Error()) + return nil, status.Newf(codes.Unavailable, tr("Error downloading index signature %[1]s: %[2]s"), URL, d.Error()) } valid, _, err := security.VerifyArduinoDetachedSignature(tmp, tmpSig) if err != nil { - return nil, fmt.Errorf(tr("signature verification error: %s"), err) + return nil, status.Newf(codes.Unknown, tr("Signature verification error: %s"), err) } if !valid { - return nil, fmt.Errorf(tr("index has an invalid signature")) + return nil, status.Newf(codes.FailedPrecondition, tr("Index '%s' has an invalid signature"), URL) } } if _, err := packageindex.LoadIndex(tmp); err != nil { - return nil, fmt.Errorf(tr("invalid package index in %[1]s: %[2]s"), URL, err) + return nil, status.Newf(codes.FailedPrecondition, tr("Invalid package index in %[1]s: %[2]s"), URL, err) } if err := indexpath.MkdirAll(); err != nil { - return nil, fmt.Errorf(tr("can't create data directory %[1]s: %[2]s"), indexpath, err) + return nil, status.Newf(codes.PermissionDenied, tr("Can't create data directory %[1]s: %[2]s"), indexpath, err) } if err := tmp.CopyTo(coreIndexPath); err != nil { - return nil, fmt.Errorf(tr("saving downloaded index %[1]s: %[2]s"), URL, err) + return nil, status.Newf(codes.PermissionDenied, tr("Error saving downloaded index %[1]s: %[2]s"), URL, err) } if tmpSig != nil { if err := tmpSig.CopyTo(coreIndexSigPath); err != nil { - return nil, fmt.Errorf(tr("saving downloaded index signature: %s"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Error saving downloaded index signature: %s"), err) } } } @@ -539,7 +539,7 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do } // UpdateCoreLibrariesIndex updates both Cores and Libraries indexes -func UpdateCoreLibrariesIndex(ctx context.Context, req *rpc.UpdateCoreLibrariesIndexRequest, downloadCB DownloadProgressCB) error { +func UpdateCoreLibrariesIndex(ctx context.Context, req *rpc.UpdateCoreLibrariesIndexRequest, downloadCB DownloadProgressCB) *status.Status { _, err := UpdateIndex(ctx, &rpc.UpdateIndexRequest{ Instance: req.Instance, }, downloadCB) @@ -558,12 +558,12 @@ func UpdateCoreLibrariesIndex(ctx context.Context, req *rpc.UpdateCoreLibrariesI } // Outdated returns a list struct containing both Core and Libraries that can be updated -func Outdated(ctx context.Context, req *rpc.OutdatedRequest) (*rpc.OutdatedResponse, error) { +func Outdated(ctx context.Context, req *rpc.OutdatedRequest) (*rpc.OutdatedResponse, *status.Status) { id := req.GetInstance().GetId() libraryManager := GetLibraryManager(id) if libraryManager == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } outdatedLibraries := []*rpc.InstalledLibrary{} @@ -586,7 +586,7 @@ func Outdated(ctx context.Context, req *rpc.OutdatedRequest) (*rpc.OutdatedRespo packageManager := GetPackageManager(id) if packageManager == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } outdatedPlatforms := []*rpc.Platform{} @@ -676,15 +676,15 @@ func getOutputRelease(lib *librariesindex.Release) *rpc.LibraryRelease { } // Upgrade downloads and installs outdated Cores and Libraries -func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadProgressCB, taskCB TaskProgressCB) error { +func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadProgressCB, taskCB TaskProgressCB) *status.Status { downloaderConfig, err := GetDownloaderConfig() if err != nil { - return err + return status.Newf(codes.FailedPrecondition, err.Error()) } lm := GetLibraryManager(req.Instance.Id) if lm == nil { - return fmt.Errorf(tr("invalid handle")) + return status.New(codes.InvalidArgument, tr("Invalid instance")) } for _, libAlternatives := range lm.Libraries { @@ -700,36 +700,36 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr // Downloads latest library release taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Downloading %s"), available)}) if d, err := available.Resource.Download(lm.DownloadsDir, downloaderConfig); err != nil { - return err + return status.Convert(err) } else if err := Download(d, available.String(), downloadCB); err != nil { - return err + return status.New(codes.Unavailable, err.Error()) } // Installs downloaded library - taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Installing %s"), available)}) + taskCB(&rpc.TaskProgress{Name: tr("Installing %s", available)}) libPath, libReplaced, err := lm.InstallPrerequisiteCheck(available) if err == librariesmanager.ErrAlreadyInstalled { - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Already installed %s"), available), Completed: true}) + taskCB(&rpc.TaskProgress{Message: tr("Already installed %s", available), Completed: true}) continue } else if err != nil { - return fmt.Errorf(tr("checking lib install prerequisites: %s"), err) + return status.Newf(codes.Unknown, tr("Error checking lib install prerequisites: %s"), err) } if libReplaced != nil { - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Replacing %[1]s with %[2]s"), libReplaced, available)}) + taskCB(&rpc.TaskProgress{Message: tr("Replacing %[1]s with %[2]s", libReplaced, available)}) } if err := lm.Install(available, libPath); err != nil { - return err + return status.Convert(err) } - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Installed %s"), available), Completed: true}) + taskCB(&rpc.TaskProgress{Message: tr("Installed %s", available), Completed: true}) } } pm := GetPackageManager(req.Instance.Id) if pm == nil { - return fmt.Errorf(tr("invalid handle")) + return status.New(codes.InvalidArgument, tr("Invalid instance")) } for _, targetPackage := range pm.Packages { @@ -748,7 +748,7 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr // Get list of installed tools needed by the currently installed version _, installedTools, err := pm.FindPlatformReleaseDependencies(ref) if err != nil { - return err + return status.Convert(err) } ref = &packagemanager.PlatformReference{ @@ -757,17 +757,17 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr PlatformVersion: latest.Version, } - taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Downloading %s"), latest)}) + taskCB(&rpc.TaskProgress{Name: tr("Downloading %s", latest)}) _, tools, err := pm.FindPlatformReleaseDependencies(ref) if err != nil { - return fmt.Errorf(tr("platform %s is not installed"), ref) + return status.Newf(codes.Unknown, tr("Platform %s is not installed", ref)) } toolsToInstall := []*cores.ToolRelease{} for _, tool := range tools { if tool.IsInstalled() { logrus.WithField("tool", tool).Warn("Tool already installed") - taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Tool %s already installed"), tool), Completed: true}) + taskCB(&rpc.TaskProgress{Name: tr("Tool %s already installed", tool), Completed: true}) } else { toolsToInstall = append(toolsToInstall, tool) } @@ -776,26 +776,26 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr // Downloads platform tools for _, tool := range toolsToInstall { if err := DownloadToolRelease(pm, tool, downloadCB); err != nil { - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Error downloading tool %s"), tool)}) - return err + taskCB(&rpc.TaskProgress{Message: tr("Error downloading tool %s", tool)}) + return status.Convert(err) } } // Downloads platform if d, err := pm.DownloadPlatformRelease(latest, downloaderConfig); err != nil { - return err + return status.Convert(err) } else if err := Download(d, latest.String(), downloadCB); err != nil { - return err + return status.New(codes.Unavailable, err.Error()) } logrus.Info("Updating platform " + installed.String()) - taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Updating %s"), latest)}) + taskCB(&rpc.TaskProgress{Name: tr("Updating platform %s", latest)}) // Installs tools for _, tool := range toolsToInstall { if err := InstallToolRelease(pm, tool, taskCB); err != nil { - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Error installing tool %s"), tool)}) - return err + taskCB(&rpc.TaskProgress{Message: tr("Error installing tool %s", tool)}) + return status.Convert(err) } } @@ -803,8 +803,8 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr err = pm.InstallPlatform(latest) if err != nil { logrus.WithError(err).Error("Cannot install platform") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Error installing %s"), latest)}) - return err + taskCB(&rpc.TaskProgress{Message: tr("Error installing platform %s", latest)}) + return status.Convert(err) } // Uninstall previously installed release @@ -813,13 +813,13 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr // In case uninstall fails tries to rollback if err != nil { logrus.WithError(err).Error("Error updating platform.") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Error upgrading platform: %s"), err)}) + taskCB(&rpc.TaskProgress{Message: tr("Error upgrading platform: %s", err)}) // Rollback if err := pm.UninstallPlatform(latest); err != nil { logrus.WithError(err).Error("Error rolling-back changes.") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Error rolling-back changes: %s"), err)}) - return err + taskCB(&rpc.TaskProgress{Message: tr("Error rolling-back changes: %s", err)}) + return status.Convert(err) } } @@ -829,15 +829,15 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr log := pm.Log.WithField("Tool", toolRelease) log.Info("Uninstalling tool") - taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Uninstalling %s, tool is no more required"), toolRelease)}) + taskCB(&rpc.TaskProgress{Name: tr("Uninstalling %s: tool is no more required", toolRelease)}) if err := pm.UninstallTool(toolRelease); err != nil { log.WithError(err).Error("Error uninstalling") - return err + return status.Convert(err) } log.Info("Tool uninstalled") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("%s uninstalled"), toolRelease), Completed: true}) + taskCB(&rpc.TaskProgress{Message: tr("%s uninstalled", toolRelease), Completed: true}) } } @@ -846,7 +846,7 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr logrus.Info("Running post_install script") taskCB(&rpc.TaskProgress{Message: tr("Configuring platform")}) if err := pm.RunPostInstallScript(latest); err != nil { - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("WARNING: cannot run post install: %s"), err)}) + taskCB(&rpc.TaskProgress{Message: tr("WARNING: cannot run post install: %s", err)}) } } else { logrus.Info("Skipping platform configuration (post_install run).") @@ -860,11 +860,11 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr } // LoadSketch collects and returns all files composing a sketch -func LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { +func LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, *status.Status) { // TODO: This should be a ToRpc function for the Sketch struct sketch, err := sk.New(paths.New(req.SketchPath)) if err != nil { - return nil, fmt.Errorf(tr("error loading sketch %[1]v: %[2]v"), req.SketchPath, err) + return nil, status.Newf(codes.Unknown, tr("Error loading sketch %[1]v: %[2]v"), req.SketchPath, err) } otherSketchFiles := make([]string, sketch.OtherSketchFiles.Len()) diff --git a/commands/lib/download.go b/commands/lib/download.go index 8bd61e7a246..fcbf73b82dc 100644 --- a/commands/lib/download.go +++ b/commands/lib/download.go @@ -25,12 +25,14 @@ import ( "github.com/arduino/arduino-cli/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var tr = i18n.Tr // LibraryDownload FIXMEDOC -func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downloadCB commands.DownloadProgressCB) (*rpc.LibraryDownloadResponse, error) { +func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downloadCB commands.DownloadProgressCB) (*rpc.LibraryDownloadResponse, *status.Status) { logrus.Info("Executing `arduino lib download`") lm := commands.GetLibraryManager(req.GetInstance().GetId()) @@ -39,11 +41,11 @@ func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downl lib, err := findLibraryIndexRelease(lm, req) if err != nil { - return nil, fmt.Errorf(tr("looking for library: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Error looking for library: %s"), err) } if err := downloadLibrary(lm, lib, downloadCB, func(*rpc.TaskProgress) {}); err != nil { - return nil, err + return nil, status.Convert(err) } return &rpc.LibraryDownloadResponse{}, nil diff --git a/commands/lib/install.go b/commands/lib/install.go index c0bfb0e2f98..997c08e908b 100644 --- a/commands/lib/install.go +++ b/commands/lib/install.go @@ -24,11 +24,13 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // LibraryInstall FIXMEDOC func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, - downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) error { + downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) *status.Status { lm := commands.GetLibraryManager(req.GetInstance().GetId()) @@ -45,13 +47,13 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, Version: req.Version, }) if err != nil { - return fmt.Errorf(tr("Error resolving dependencies for %[1]s@%[2]s: %[3]s"), req.Name, req.Version, err) + return status.Newf(err.Code(), tr("Error resolving dependencies for %[1]s@%[2]s: %[3]s", req.Name, req.Version, err.Message())) } for _, dep := range res.Dependencies { if existingDep, has := toInstall[dep.Name]; has { if existingDep.VersionRequired != dep.VersionRequired { - return fmt.Errorf(tr("two different versions of the library %[1]s are required: %[2]s and %[3]s"), + return status.Newf(codes.FailedPrecondition, tr("Two different versions of the library %[1]s are required: %[2]s and %[3]s"), dep.Name, dep.VersionRequired, existingDep.VersionRequired) } } @@ -65,31 +67,31 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, Version: lib.VersionRequired, }) if err != nil { - return fmt.Errorf(tr("looking for library: %s"), err) + return status.Newf(codes.InvalidArgument, tr("Error looking for library: %s", err)) } if err := downloadLibrary(lm, libRelease, downloadCB, taskCB); err != nil { - return fmt.Errorf(tr("downloading library: %s"), err) + return status.Newf(codes.Unknown, tr("Error downloading library: %s", err)) } if err := installLibrary(lm, libRelease, taskCB); err != nil { - return err + return status.New(codes.PermissionDenied, err.Error()) } } - status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) - if status != nil { - return fmt.Errorf(tr("rescanning libraries: %s"), status.Err()) + stat := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) + if stat != nil { + return status.Newf(stat.Code(), tr("Error rescanning libraries: %s", stat.Err())) } return nil } func installLibrary(lm *librariesmanager.LibrariesManager, libRelease *librariesindex.Release, taskCB commands.TaskProgressCB) error { - taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Installing %s"), libRelease)}) + taskCB(&rpc.TaskProgress{Name: tr("Installing %s", libRelease)}) logrus.WithField("library", libRelease).Info("Installing library") libPath, libReplaced, err := lm.InstallPrerequisiteCheck(libRelease) if err == librariesmanager.ErrAlreadyInstalled { - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Already installed %s"), libRelease), Completed: true}) + taskCB(&rpc.TaskProgress{Message: tr("Already installed %s", libRelease), Completed: true}) return nil } @@ -98,33 +100,33 @@ func installLibrary(lm *librariesmanager.LibrariesManager, libRelease *libraries } if libReplaced != nil { - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Replacing %[1]s with %[2]s"), libReplaced, libRelease)}) + taskCB(&rpc.TaskProgress{Message: tr("Replacing %[1]s with %[2]s", libReplaced, libRelease)}) } if err := lm.Install(libRelease, libPath); err != nil { return err } - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Installed %s"), libRelease), Completed: true}) + taskCB(&rpc.TaskProgress{Message: tr("Installed %s", libRelease), Completed: true}) return nil } //ZipLibraryInstall FIXMEDOC -func ZipLibraryInstall(ctx context.Context, req *rpc.ZipLibraryInstallRequest, taskCB commands.TaskProgressCB) error { +func ZipLibraryInstall(ctx context.Context, req *rpc.ZipLibraryInstallRequest, taskCB commands.TaskProgressCB) *status.Status { lm := commands.GetLibraryManager(req.GetInstance().GetId()) if err := lm.InstallZipLib(ctx, req.Path, req.Overwrite); err != nil { - return err + return status.New(codes.InvalidArgument, err.Error()) } - taskCB(&rpc.TaskProgress{Message: tr("Installed Archived Library"), Completed: true}) + taskCB(&rpc.TaskProgress{Message: tr("Library installed"), Completed: true}) return nil } //GitLibraryInstall FIXMEDOC -func GitLibraryInstall(ctx context.Context, req *rpc.GitLibraryInstallRequest, taskCB commands.TaskProgressCB) error { +func GitLibraryInstall(ctx context.Context, req *rpc.GitLibraryInstallRequest, taskCB commands.TaskProgressCB) *status.Status { lm := commands.GetLibraryManager(req.GetInstance().GetId()) if err := lm.InstallGitLib(req.Url, req.Overwrite); err != nil { - return err + return status.New(codes.InvalidArgument, err.Error()) } - taskCB(&rpc.TaskProgress{Message: tr("Installed Library from Git URL"), Completed: true}) + taskCB(&rpc.TaskProgress{Message: tr("Library installed"), Completed: true}) return nil } diff --git a/commands/lib/list.go b/commands/lib/list.go index 3642dff930f..b32cb831c6f 100644 --- a/commands/lib/list.go +++ b/commands/lib/list.go @@ -17,7 +17,6 @@ package lib import ( "context" - "fmt" "strings" "github.com/arduino/arduino-cli/arduino/cores" @@ -26,7 +25,8 @@ import ( "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "github.com/pkg/errors" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) type installedLib struct { @@ -35,15 +35,15 @@ type installedLib struct { } // LibraryList FIXMEDOC -func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { +func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } lm := commands.GetLibraryManager(req.GetInstance().GetId()) if lm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } nameFilter := strings.ToLower(req.GetName()) @@ -53,11 +53,11 @@ func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.Library if f := req.GetFqbn(); f != "" { fqbn, err := cores.ParseFQBN(req.GetFqbn()) if err != nil { - return nil, fmt.Errorf(tr("parsing fqbn: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Error parsing FQBN: %s", err)) } _, boardPlatform, _, _, refBoardPlatform, err := pm.ResolveFQBN(fqbn) if err != nil { - return nil, fmt.Errorf(tr("loading board data: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Error loading board data: %s", err)) } filteredRes := map[string]*installedLib{} @@ -105,7 +105,7 @@ func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.Library } rpcLib, err := lib.Library.ToRPCLibrary() if err != nil { - return nil, fmt.Errorf(tr("converting library %[1]s to rpc struct: %[2]w"), lib.Library.Name, err) + return nil, status.Newf(codes.PermissionDenied, tr("Error converting library %[1]s to rpc struct: %[2]s", lib.Library.Name, err)) } instaledLibs = append(instaledLibs, &rpc.InstalledLibrary{ Library: rpcLib, diff --git a/commands/lib/resolve_deps.go b/commands/lib/resolve_deps.go index 1ef7737a32c..095e741bded 100644 --- a/commands/lib/resolve_deps.go +++ b/commands/lib/resolve_deps.go @@ -17,21 +17,22 @@ package lib import ( "context" - "fmt" "github.com/arduino/arduino-cli/arduino/libraries" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // LibraryResolveDependencies FIXMEDOC -func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { +func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, *status.Status) { lm := commands.GetLibraryManager(req.GetInstance().GetId()) // Search the requested lib reqLibRelease, err := findLibraryIndexRelease(lm, req) if err != nil { - return nil, fmt.Errorf(tr("looking for library: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Error looking for library: %s", err)) } // Extract all installed libraries @@ -48,12 +49,12 @@ func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDepe // Check if there is a problem with the first level deps for _, directDep := range reqLibRelease.GetDependencies() { if _, ok := lm.Index.Libraries[directDep.GetName()]; !ok { - return nil, fmt.Errorf(tr("dependency '%s' is not available"), directDep.GetName()) + return nil, status.Newf(codes.FailedPrecondition, tr("Dependency '%s' is not available", directDep.GetName())) } } // Otherwise there is no possible solution, the depends field has an invalid formula - return nil, fmt.Errorf(tr("no valid solution found")) + return nil, status.New(codes.FailedPrecondition, tr("No valid dependencies solution found")) } res := []*rpc.LibraryDependencyStatus{} diff --git a/commands/lib/search.go b/commands/lib/search.go index 440da260cf3..8a2f270c7dc 100644 --- a/commands/lib/search.go +++ b/commands/lib/search.go @@ -17,7 +17,6 @@ package lib import ( "context" - "errors" "github.com/arduino/arduino-cli/arduino/libraries/librariesindex" "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" @@ -25,16 +24,19 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" semver "go.bug.st/relaxed-semver" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // LibrarySearch FIXMEDOC -func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { +func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, *status.Status) { lm := commands.GetLibraryManager(req.GetInstance().GetId()) if lm == nil { - return nil, errors.New(tr("invalid instance")) + return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) } - return searchLibrary(req, lm) + resp, err := searchLibrary(req, lm) + return resp, status.Convert(err) } func searchLibrary(req *rpc.LibrarySearchRequest, lm *librariesmanager.LibrariesManager) (*rpc.LibrarySearchResponse, error) { diff --git a/commands/lib/uninstall.go b/commands/lib/uninstall.go index 205d73e2346..47f27fb879c 100644 --- a/commands/lib/uninstall.go +++ b/commands/lib/uninstall.go @@ -21,14 +21,16 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // LibraryUninstall FIXMEDOC -func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallRequest, taskCB commands.TaskProgressCB) error { +func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallRequest, taskCB commands.TaskProgressCB) *status.Status { lm := commands.GetLibraryManager(req.GetInstance().GetId()) ref, err := createLibIndexReference(lm, req) if err != nil { - return err + return status.New(codes.InvalidArgument, err.Error()) } lib := lm.FindByReference(ref) diff --git a/commands/lib/upgrade.go b/commands/lib/upgrade.go index 9b97bb0d269..c0f2ee32384 100644 --- a/commands/lib/upgrade.go +++ b/commands/lib/upgrade.go @@ -16,26 +16,25 @@ package lib import ( - "fmt" - "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/status" ) // LibraryUpgradeAll upgrades all the available libraries func LibraryUpgradeAll(instanceID int32, downloadCB commands.DownloadProgressCB, - taskCB commands.TaskProgressCB) error { + taskCB commands.TaskProgressCB) *status.Status { // get the library manager lm := commands.GetLibraryManager(instanceID) if err := upgrade(lm, listLibraries(lm, true, true), downloadCB, taskCB); err != nil { - return err + return status.Convert(err) } - status := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: instanceID}}, nil) - if status != nil { - return fmt.Errorf(tr("rescanning libraries: %s"), status.Err()) + stat := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: instanceID}}, nil) + if stat != nil { + return status.Newf(stat.Code(), tr("Error rescanning libraries: %s", stat.Err())) } return nil @@ -43,7 +42,7 @@ func LibraryUpgradeAll(instanceID int32, downloadCB commands.DownloadProgressCB, // LibraryUpgrade upgrades only the given libraries func LibraryUpgrade(instanceID int32, libraryNames []string, downloadCB commands.DownloadProgressCB, - taskCB commands.TaskProgressCB) error { + taskCB commands.TaskProgressCB) *status.Status { // get the library manager lm := commands.GetLibraryManager(instanceID) @@ -51,7 +50,7 @@ func LibraryUpgrade(instanceID int32, libraryNames []string, downloadCB commands libs := filterByName(listLibraries(lm, true, true), libraryNames) // do it - return upgrade(lm, libs, downloadCB, taskCB) + return status.Convert(upgrade(lm, libs, downloadCB, taskCB)) } func upgrade(lm *librariesmanager.LibrariesManager, libs []*installedLib, downloadCB commands.DownloadProgressCB, diff --git a/commands/sketch/archive.go b/commands/sketch/archive.go index a45e5b89aaa..3561497169c 100644 --- a/commands/sketch/archive.go +++ b/commands/sketch/archive.go @@ -18,7 +18,6 @@ package sketch import ( "archive/zip" "context" - "fmt" "io" "path/filepath" "strings" @@ -27,12 +26,14 @@ import ( "github.com/arduino/arduino-cli/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) var tr = i18n.Tr // ArchiveSketch FIXMEDOC -func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { +func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, *status.Status) { // sketchName is the name of the sketch without extension, for example "MySketch" var sketchName string @@ -43,7 +44,7 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc s, err := sketch.New(sketchPath) if err != nil { - return nil, err + return nil, status.Convert(err) } sketchPath = s.FullPath @@ -56,7 +57,7 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc archivePath, err = archivePath.Clean().Abs() if err != nil { - return nil, fmt.Errorf(tr("Error getting absolute archive path %v"), err) + return nil, status.Newf(codes.Unknown, tr("Error getting absolute archive path %v"), err) } // Makes archivePath point to a zip file @@ -67,18 +68,18 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc } if archivePath.Exist() { - return nil, fmt.Errorf(tr("archive already exists")) + return nil, status.New(codes.InvalidArgument, tr("Archive already exists")) } filesToZip, err := sketchPath.ReadDirRecursive() if err != nil { - return nil, fmt.Errorf(tr("Error retrieving sketch files: %v"), err) + return nil, status.Newf(codes.Unknown, tr("Error retrieving sketch files: %v"), err) } filesToZip.FilterOutDirs() archive, err := archivePath.Create() if err != nil { - return nil, fmt.Errorf(tr("Error creating archive: %v"), err) + return nil, status.Newf(codes.PermissionDenied, tr("Error creating archive: %v"), err) } defer archive.Close() @@ -90,7 +91,7 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc if !req.IncludeBuildDir { filePath, err := sketchPath.Parent().RelTo(f) if err != nil { - return nil, fmt.Errorf(tr("Error calculating relative file path: %v"), err) + return nil, status.Newf(codes.Unknown, tr("Error calculating relative file path: %v"), err) } // Skips build folder @@ -103,7 +104,7 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc // If we don't do this the archive would contain all the sketch files as top level. err = addFileToSketchArchive(zipWriter, f, sketchPath.Parent()) if err != nil { - return nil, fmt.Errorf(tr("Error adding file to archive: %v"), err) + return nil, status.Newf(codes.Unknown, tr("Error adding file to archive: %v"), err) } } diff --git a/commands/upload/programmers_list.go b/commands/upload/programmers_list.go index a6c478edcff..26fa6aa2ef1 100644 --- a/commands/upload/programmers_list.go +++ b/commands/upload/programmers_list.go @@ -17,30 +17,31 @@ package upload import ( "context" - "fmt" "github.com/arduino/arduino-cli/arduino/cores" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" ) // ListProgrammersAvailableForUpload FIXMEDOC -func ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { +func ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, *status.Status) { pm := commands.GetPackageManager(req.GetInstance().GetId()) fqbnIn := req.GetFqbn() if fqbnIn == "" { - return nil, fmt.Errorf(tr("no Fully Qualified Board Name provided")) + return nil, status.New(codes.InvalidArgument, tr("No FQBN (Fully Qualified Board Name) provided")) } fqbn, err := cores.ParseFQBN(fqbnIn) if err != nil { - return nil, fmt.Errorf(tr("incorrect FQBN: %s"), err) + return nil, status.Newf(codes.InvalidArgument, tr("Invalid FQBN: %s"), err) } // Find target platforms _, platform, _, _, refPlatform, err := pm.ResolveFQBN(fqbn) if err != nil { - return nil, fmt.Errorf(tr("incorrect FQBN: %s"), err) + return nil, status.Newf(codes.Unknown, tr("Invalid FQBN: %s"), err) } result := []*rpc.Programmer{} From 17652b6ce4b54abbc6a6b4745f48693f136e8f36 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 9 Jul 2021 04:04:52 -0700 Subject: [PATCH 04/19] Replace custom error with protobuf message Previously, a custom error was returned when attempting to upgrade a platform that was already at the latest available version. There is dedicated code for handling this specific error. Now that the function has been changed to return a status.Status instead of error, the previous check for the return being this error is no longer possible. The capability is restored by replacing the error with a protocol buffer message. --- cli/core/upgrade.go | 4 +- commands/core/upgrade.go | 28 +-- rpc/cc/arduino/cli/commands/v1/core.pb.go | 283 +++++++++++++--------- rpc/cc/arduino/cli/commands/v1/core.proto | 4 + 4 files changed, 187 insertions(+), 132 deletions(-) diff --git a/cli/core/upgrade.go b/cli/core/upgrade.go index a29f61b988d..1f71e30c1c0 100644 --- a/cli/core/upgrade.go +++ b/cli/core/upgrade.go @@ -95,8 +95,8 @@ func runUpgradeCommand(cmd *cobra.Command, args []string) { } _, err := core.PlatformUpgrade(context.Background(), r, output.ProgressBar(), output.TaskProgress()) - if err.Message() == core.ErrAlreadyLatest.Error() { - feedback.Printf(tr("Platform %s is already at the latest version"), platformRef) + if d := err.Details(); len(d) > 0 && d[0].(*rpc.AlreadyAtLatestVersionError) != nil { + feedback.Printf(tr("Platform %s is already at the latest version", platformRef)) } else if err != nil { feedback.Errorf(tr("Error during upgrade: %v"), err) os.Exit(errorcodes.ErrGeneric) diff --git a/commands/core/upgrade.go b/commands/core/upgrade.go index 89f160c43cb..30adae6eac1 100644 --- a/commands/core/upgrade.go +++ b/commands/core/upgrade.go @@ -17,8 +17,6 @@ package core import ( "context" - "errors" - "fmt" "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/commands" @@ -27,12 +25,6 @@ import ( "google.golang.org/grpc/status" ) -var ( - // ErrAlreadyLatest is returned when an upgrade is not possible because - // already at latest version. - ErrAlreadyLatest = errors.New(tr("platform already at latest version")) -) - // PlatformUpgrade FIXMEDOC func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformUpgradeResponse, *status.Status) { @@ -48,7 +40,7 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, PlatformArchitecture: req.Architecture, } if err := upgradePlatform(pm, ref, downloadCB, taskCB, req.GetSkipPostInstall()); err != nil { - return nil, status.Convert(err) + return nil, err } status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) @@ -61,33 +53,37 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, func upgradePlatform(pm *packagemanager.PackageManager, platformRef *packagemanager.PlatformReference, downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB, - skipPostInstall bool) error { + skipPostInstall bool) *status.Status { if platformRef.PlatformVersion != nil { - return fmt.Errorf(tr("upgrade doesn't accept parameters with version")) + return status.New(codes.InvalidArgument, tr("Upgrade doesn't accept parameters with version")) } // Search the latest version for all specified platforms platform := pm.FindPlatform(platformRef) if platform == nil { - return fmt.Errorf(tr("platform %s not found"), platformRef) + return status.Newf(codes.InvalidArgument, tr("Platform %s not found", platformRef)) } installed := pm.GetInstalledPlatformRelease(platform) if installed == nil { - return fmt.Errorf(tr("platform %s is not installed"), platformRef) + return status.Newf(codes.InvalidArgument, tr("Platform %s is not installed", platformRef)) } latest := platform.GetLatestRelease() if !latest.Version.GreaterThan(installed.Version) { - return ErrAlreadyLatest + status, e := status.New(codes.AlreadyExists, "platform already at latest version").WithDetails(&rpc.AlreadyAtLatestVersionError{}) + if e != nil { // should never happen + panic(e) + } + return status } platformRef.PlatformVersion = latest.Version platformRelease, tools, err := pm.FindPlatformReleaseDependencies(platformRef) if err != nil { - return fmt.Errorf(tr("platform %s is not installed"), platformRef) + return status.Newf(codes.FailedPrecondition, tr("Platform %s is not installed", platformRef)) } err = installPlatform(pm, platformRelease, tools, downloadCB, taskCB, skipPostInstall) if err != nil { - return err + return status.Convert(err) } return nil diff --git a/rpc/cc/arduino/cli/commands/v1/core.pb.go b/rpc/cc/arduino/cli/commands/v1/core.pb.go index c0ee99accb8..e7acbab78e4 100644 --- a/rpc/cc/arduino/cli/commands/v1/core.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/core.pb.go @@ -413,6 +413,46 @@ func (x *PlatformUninstallResponse) GetTaskProgress() *TaskProgress { return nil } +// AlreadyAtLatestVersionError is returned when an upgrade is not possible +// because already at latest version. +type AlreadyAtLatestVersionError struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *AlreadyAtLatestVersionError) Reset() { + *x = AlreadyAtLatestVersionError{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AlreadyAtLatestVersionError) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AlreadyAtLatestVersionError) ProtoMessage() {} + +func (x *AlreadyAtLatestVersionError) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AlreadyAtLatestVersionError.ProtoReflect.Descriptor instead. +func (*AlreadyAtLatestVersionError) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{6} +} + type PlatformUpgradeRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -432,7 +472,7 @@ type PlatformUpgradeRequest struct { func (x *PlatformUpgradeRequest) Reset() { *x = PlatformUpgradeRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[6] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -445,7 +485,7 @@ func (x *PlatformUpgradeRequest) String() string { func (*PlatformUpgradeRequest) ProtoMessage() {} func (x *PlatformUpgradeRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[6] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -458,7 +498,7 @@ func (x *PlatformUpgradeRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformUpgradeRequest.ProtoReflect.Descriptor instead. func (*PlatformUpgradeRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{6} + return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{7} } func (x *PlatformUpgradeRequest) GetInstance() *Instance { @@ -503,7 +543,7 @@ type PlatformUpgradeResponse struct { func (x *PlatformUpgradeResponse) Reset() { *x = PlatformUpgradeResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[7] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -516,7 +556,7 @@ func (x *PlatformUpgradeResponse) String() string { func (*PlatformUpgradeResponse) ProtoMessage() {} func (x *PlatformUpgradeResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[7] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -529,7 +569,7 @@ func (x *PlatformUpgradeResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformUpgradeResponse.ProtoReflect.Descriptor instead. func (*PlatformUpgradeResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{7} + return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{8} } func (x *PlatformUpgradeResponse) GetProgress() *DownloadProgress { @@ -563,7 +603,7 @@ type PlatformSearchRequest struct { func (x *PlatformSearchRequest) Reset() { *x = PlatformSearchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[8] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -576,7 +616,7 @@ func (x *PlatformSearchRequest) String() string { func (*PlatformSearchRequest) ProtoMessage() {} func (x *PlatformSearchRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[8] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -589,7 +629,7 @@ func (x *PlatformSearchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformSearchRequest.ProtoReflect.Descriptor instead. func (*PlatformSearchRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{8} + return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{9} } func (x *PlatformSearchRequest) GetInstance() *Instance { @@ -625,7 +665,7 @@ type PlatformSearchResponse struct { func (x *PlatformSearchResponse) Reset() { *x = PlatformSearchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[9] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -638,7 +678,7 @@ func (x *PlatformSearchResponse) String() string { func (*PlatformSearchResponse) ProtoMessage() {} func (x *PlatformSearchResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[9] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -651,7 +691,7 @@ func (x *PlatformSearchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformSearchResponse.ProtoReflect.Descriptor instead. func (*PlatformSearchResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{9} + return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{10} } func (x *PlatformSearchResponse) GetSearchOutput() []*Platform { @@ -680,7 +720,7 @@ type PlatformListRequest struct { func (x *PlatformListRequest) Reset() { *x = PlatformListRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[10] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -693,7 +733,7 @@ func (x *PlatformListRequest) String() string { func (*PlatformListRequest) ProtoMessage() {} func (x *PlatformListRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[10] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -706,7 +746,7 @@ func (x *PlatformListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformListRequest.ProtoReflect.Descriptor instead. func (*PlatformListRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{10} + return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{11} } func (x *PlatformListRequest) GetInstance() *Instance { @@ -742,7 +782,7 @@ type PlatformListResponse struct { func (x *PlatformListResponse) Reset() { *x = PlatformListResponse{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[11] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -755,7 +795,7 @@ func (x *PlatformListResponse) String() string { func (*PlatformListResponse) ProtoMessage() {} func (x *PlatformListResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[11] + mi := &file_cc_arduino_cli_commands_v1_core_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -768,7 +808,7 @@ func (x *PlatformListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformListResponse.ProtoReflect.Descriptor instead. func (*PlatformListResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{11} + return file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP(), []int{12} } func (x *PlatformListResponse) GetInstalledPlatforms() []*Platform { @@ -850,69 +890,71 @@ var file_cc_arduino_cli_commands_v1_core_proto_rawDesc = []byte{ 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x0c, 0x74, 0x61, - 0x73, 0x6b, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0xd5, 0x01, 0x0a, 0x16, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, - 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x61, - 0x67, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, - 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, - 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, - 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x22, 0xb2, 0x01, 0x0a, 0x17, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, - 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, - 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, - 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, - 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x08, - 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4d, 0x0a, 0x0d, 0x74, 0x61, 0x73, 0x6b, - 0x5f, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x28, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, - 0x6b, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x0c, 0x74, 0x61, 0x73, 0x6b, 0x50, - 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x15, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, - 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x61, 0x72, - 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x41, 0x72, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6c, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, 0x6c, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x63, 0x0a, 0x16, 0x50, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x49, 0x0a, 0x0d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, - 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x0c, - 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x90, 0x01, 0x0a, - 0x13, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x73, 0x6b, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x41, 0x6c, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x41, 0x74, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x22, 0xd5, 0x01, 0x0a, 0x16, 0x50, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x22, - 0x6d, 0x0a, 0x14, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x13, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, - 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x12, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x42, 0x48, - 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, - 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, - 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, - 0x63, 0x6c, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b, - 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, + 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x70, 0x6f, + 0x73, 0x74, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0f, 0x73, 0x6b, 0x69, 0x70, 0x50, 0x6f, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x22, 0xb2, 0x01, 0x0a, 0x17, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x55, 0x70, + 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x48, 0x0a, + 0x08, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, + 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x77, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x08, 0x70, + 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x12, 0x4d, 0x0a, 0x0d, 0x74, 0x61, 0x73, 0x6b, 0x5f, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, + 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x61, 0x73, 0x6b, + 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x52, 0x0c, 0x74, 0x61, 0x73, 0x6b, 0x50, 0x72, + 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x15, 0x50, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x61, 0x72, 0x67, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, + 0x72, 0x67, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x6c, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x61, 0x6c, 0x6c, 0x56, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x63, 0x0a, 0x16, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x49, 0x0a, 0x0d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, + 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x0c, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x90, 0x01, 0x0a, 0x13, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, + 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x61, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x22, 0x6d, + 0x0a, 0x14, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x13, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, + 0x6c, 0x65, 0x64, 0x5f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, + 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x12, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6c, 0x6c, 0x65, 0x64, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x42, 0x48, 0x5a, + 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x64, 0x75, + 0x69, 0x6e, 0x6f, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2d, 0x63, 0x6c, 0x69, 0x2f, + 0x72, 0x70, 0x63, 0x2f, 0x63, 0x63, 0x2f, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x63, + 0x6c, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -927,40 +969,41 @@ func file_cc_arduino_cli_commands_v1_core_proto_rawDescGZIP() []byte { return file_cc_arduino_cli_commands_v1_core_proto_rawDescData } -var file_cc_arduino_cli_commands_v1_core_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_cc_arduino_cli_commands_v1_core_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_cc_arduino_cli_commands_v1_core_proto_goTypes = []interface{}{ - (*PlatformInstallRequest)(nil), // 0: cc.arduino.cli.commands.v1.PlatformInstallRequest - (*PlatformInstallResponse)(nil), // 1: cc.arduino.cli.commands.v1.PlatformInstallResponse - (*PlatformDownloadRequest)(nil), // 2: cc.arduino.cli.commands.v1.PlatformDownloadRequest - (*PlatformDownloadResponse)(nil), // 3: cc.arduino.cli.commands.v1.PlatformDownloadResponse - (*PlatformUninstallRequest)(nil), // 4: cc.arduino.cli.commands.v1.PlatformUninstallRequest - (*PlatformUninstallResponse)(nil), // 5: cc.arduino.cli.commands.v1.PlatformUninstallResponse - (*PlatformUpgradeRequest)(nil), // 6: cc.arduino.cli.commands.v1.PlatformUpgradeRequest - (*PlatformUpgradeResponse)(nil), // 7: cc.arduino.cli.commands.v1.PlatformUpgradeResponse - (*PlatformSearchRequest)(nil), // 8: cc.arduino.cli.commands.v1.PlatformSearchRequest - (*PlatformSearchResponse)(nil), // 9: cc.arduino.cli.commands.v1.PlatformSearchResponse - (*PlatformListRequest)(nil), // 10: cc.arduino.cli.commands.v1.PlatformListRequest - (*PlatformListResponse)(nil), // 11: cc.arduino.cli.commands.v1.PlatformListResponse - (*Instance)(nil), // 12: cc.arduino.cli.commands.v1.Instance - (*DownloadProgress)(nil), // 13: cc.arduino.cli.commands.v1.DownloadProgress - (*TaskProgress)(nil), // 14: cc.arduino.cli.commands.v1.TaskProgress - (*Platform)(nil), // 15: cc.arduino.cli.commands.v1.Platform + (*PlatformInstallRequest)(nil), // 0: cc.arduino.cli.commands.v1.PlatformInstallRequest + (*PlatformInstallResponse)(nil), // 1: cc.arduino.cli.commands.v1.PlatformInstallResponse + (*PlatformDownloadRequest)(nil), // 2: cc.arduino.cli.commands.v1.PlatformDownloadRequest + (*PlatformDownloadResponse)(nil), // 3: cc.arduino.cli.commands.v1.PlatformDownloadResponse + (*PlatformUninstallRequest)(nil), // 4: cc.arduino.cli.commands.v1.PlatformUninstallRequest + (*PlatformUninstallResponse)(nil), // 5: cc.arduino.cli.commands.v1.PlatformUninstallResponse + (*AlreadyAtLatestVersionError)(nil), // 6: cc.arduino.cli.commands.v1.AlreadyAtLatestVersionError + (*PlatformUpgradeRequest)(nil), // 7: cc.arduino.cli.commands.v1.PlatformUpgradeRequest + (*PlatformUpgradeResponse)(nil), // 8: cc.arduino.cli.commands.v1.PlatformUpgradeResponse + (*PlatformSearchRequest)(nil), // 9: cc.arduino.cli.commands.v1.PlatformSearchRequest + (*PlatformSearchResponse)(nil), // 10: cc.arduino.cli.commands.v1.PlatformSearchResponse + (*PlatformListRequest)(nil), // 11: cc.arduino.cli.commands.v1.PlatformListRequest + (*PlatformListResponse)(nil), // 12: cc.arduino.cli.commands.v1.PlatformListResponse + (*Instance)(nil), // 13: cc.arduino.cli.commands.v1.Instance + (*DownloadProgress)(nil), // 14: cc.arduino.cli.commands.v1.DownloadProgress + (*TaskProgress)(nil), // 15: cc.arduino.cli.commands.v1.TaskProgress + (*Platform)(nil), // 16: cc.arduino.cli.commands.v1.Platform } var file_cc_arduino_cli_commands_v1_core_proto_depIdxs = []int32{ - 12, // 0: cc.arduino.cli.commands.v1.PlatformInstallRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 13, // 1: cc.arduino.cli.commands.v1.PlatformInstallResponse.progress:type_name -> cc.arduino.cli.commands.v1.DownloadProgress - 14, // 2: cc.arduino.cli.commands.v1.PlatformInstallResponse.task_progress:type_name -> cc.arduino.cli.commands.v1.TaskProgress - 12, // 3: cc.arduino.cli.commands.v1.PlatformDownloadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 13, // 4: cc.arduino.cli.commands.v1.PlatformDownloadResponse.progress:type_name -> cc.arduino.cli.commands.v1.DownloadProgress - 12, // 5: cc.arduino.cli.commands.v1.PlatformUninstallRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 14, // 6: cc.arduino.cli.commands.v1.PlatformUninstallResponse.task_progress:type_name -> cc.arduino.cli.commands.v1.TaskProgress - 12, // 7: cc.arduino.cli.commands.v1.PlatformUpgradeRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 13, // 8: cc.arduino.cli.commands.v1.PlatformUpgradeResponse.progress:type_name -> cc.arduino.cli.commands.v1.DownloadProgress - 14, // 9: cc.arduino.cli.commands.v1.PlatformUpgradeResponse.task_progress:type_name -> cc.arduino.cli.commands.v1.TaskProgress - 12, // 10: cc.arduino.cli.commands.v1.PlatformSearchRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 15, // 11: cc.arduino.cli.commands.v1.PlatformSearchResponse.search_output:type_name -> cc.arduino.cli.commands.v1.Platform - 12, // 12: cc.arduino.cli.commands.v1.PlatformListRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance - 15, // 13: cc.arduino.cli.commands.v1.PlatformListResponse.installed_platforms:type_name -> cc.arduino.cli.commands.v1.Platform + 13, // 0: cc.arduino.cli.commands.v1.PlatformInstallRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 14, // 1: cc.arduino.cli.commands.v1.PlatformInstallResponse.progress:type_name -> cc.arduino.cli.commands.v1.DownloadProgress + 15, // 2: cc.arduino.cli.commands.v1.PlatformInstallResponse.task_progress:type_name -> cc.arduino.cli.commands.v1.TaskProgress + 13, // 3: cc.arduino.cli.commands.v1.PlatformDownloadRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 14, // 4: cc.arduino.cli.commands.v1.PlatformDownloadResponse.progress:type_name -> cc.arduino.cli.commands.v1.DownloadProgress + 13, // 5: cc.arduino.cli.commands.v1.PlatformUninstallRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 15, // 6: cc.arduino.cli.commands.v1.PlatformUninstallResponse.task_progress:type_name -> cc.arduino.cli.commands.v1.TaskProgress + 13, // 7: cc.arduino.cli.commands.v1.PlatformUpgradeRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 14, // 8: cc.arduino.cli.commands.v1.PlatformUpgradeResponse.progress:type_name -> cc.arduino.cli.commands.v1.DownloadProgress + 15, // 9: cc.arduino.cli.commands.v1.PlatformUpgradeResponse.task_progress:type_name -> cc.arduino.cli.commands.v1.TaskProgress + 13, // 10: cc.arduino.cli.commands.v1.PlatformSearchRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 16, // 11: cc.arduino.cli.commands.v1.PlatformSearchResponse.search_output:type_name -> cc.arduino.cli.commands.v1.Platform + 13, // 12: cc.arduino.cli.commands.v1.PlatformListRequest.instance:type_name -> cc.arduino.cli.commands.v1.Instance + 16, // 13: cc.arduino.cli.commands.v1.PlatformListResponse.installed_platforms:type_name -> cc.arduino.cli.commands.v1.Platform 14, // [14:14] is the sub-list for method output_type 14, // [14:14] is the sub-list for method input_type 14, // [14:14] is the sub-list for extension type_name @@ -1048,7 +1091,7 @@ func file_cc_arduino_cli_commands_v1_core_proto_init() { } } file_cc_arduino_cli_commands_v1_core_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlatformUpgradeRequest); i { + switch v := v.(*AlreadyAtLatestVersionError); i { case 0: return &v.state case 1: @@ -1060,7 +1103,7 @@ func file_cc_arduino_cli_commands_v1_core_proto_init() { } } file_cc_arduino_cli_commands_v1_core_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlatformUpgradeResponse); i { + switch v := v.(*PlatformUpgradeRequest); i { case 0: return &v.state case 1: @@ -1072,7 +1115,7 @@ func file_cc_arduino_cli_commands_v1_core_proto_init() { } } file_cc_arduino_cli_commands_v1_core_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlatformSearchRequest); i { + switch v := v.(*PlatformUpgradeResponse); i { case 0: return &v.state case 1: @@ -1084,7 +1127,7 @@ func file_cc_arduino_cli_commands_v1_core_proto_init() { } } file_cc_arduino_cli_commands_v1_core_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlatformSearchResponse); i { + switch v := v.(*PlatformSearchRequest); i { case 0: return &v.state case 1: @@ -1096,7 +1139,7 @@ func file_cc_arduino_cli_commands_v1_core_proto_init() { } } file_cc_arduino_cli_commands_v1_core_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlatformListRequest); i { + switch v := v.(*PlatformSearchResponse); i { case 0: return &v.state case 1: @@ -1108,6 +1151,18 @@ func file_cc_arduino_cli_commands_v1_core_proto_init() { } } file_cc_arduino_cli_commands_v1_core_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlatformListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_cc_arduino_cli_commands_v1_core_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PlatformListResponse); i { case 0: return &v.state @@ -1126,7 +1181,7 @@ func file_cc_arduino_cli_commands_v1_core_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cc_arduino_cli_commands_v1_core_proto_rawDesc, NumEnums: 0, - NumMessages: 12, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/cc/arduino/cli/commands/v1/core.proto b/rpc/cc/arduino/cli/commands/v1/core.proto index a1762f8f0bd..2b7e6a917f7 100644 --- a/rpc/cc/arduino/cli/commands/v1/core.proto +++ b/rpc/cc/arduino/cli/commands/v1/core.proto @@ -71,6 +71,10 @@ message PlatformUninstallResponse { TaskProgress task_progress = 1; } +// AlreadyAtLatestVersionError is returned when an upgrade is not possible +// because already at latest version. +message AlreadyAtLatestVersionError {} + message PlatformUpgradeRequest { // Arduino Core Service instance from the `Init` response. Instance instance = 1; From c6b72b9c81e44ef2e9c03126be52dfe8b178e01a Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 9 Jul 2021 05:27:02 -0700 Subject: [PATCH 05/19] Handle details of any type in `core.PlatformUpgrade()` status The status details of the function are used to identify the specific cause of a non-nil status. This is done via a type assertion. Previously, this type assertion was configured such that a details of any type other than the expected would result in a panic. At the moment, that will not occur because we only add details of one type. However, the whole point of the type assertion is to support details of multiple types, and if other types are added a panic will not be the appropriate behavior. A better approach is to check the result of the type assertion, handling the non-nil status as a generic error if its details are of a different type. --- cli/core/upgrade.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cli/core/upgrade.go b/cli/core/upgrade.go index 1f71e30c1c0..f6398eb0984 100644 --- a/cli/core/upgrade.go +++ b/cli/core/upgrade.go @@ -95,10 +95,15 @@ func runUpgradeCommand(cmd *cobra.Command, args []string) { } _, err := core.PlatformUpgrade(context.Background(), r, output.ProgressBar(), output.TaskProgress()) - if d := err.Details(); len(d) > 0 && d[0].(*rpc.AlreadyAtLatestVersionError) != nil { - feedback.Printf(tr("Platform %s is already at the latest version", platformRef)) - } else if err != nil { - feedback.Errorf(tr("Error during upgrade: %v"), err) + if err != nil { + if d := err.Details(); len(d) > 0 { + if _, ok := d[0].(*rpc.AlreadyAtLatestVersionError); ok { + feedback.Printf(tr("Platform %s is already at the latest version", platformRef)) + continue + } + } + + feedback.Errorf(tr("Error during upgrade: %v", err)) os.Exit(errorcodes.ErrGeneric) } } From 4696d0787711491545e365202b0328e9c1a5afb0 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 13 Jul 2021 16:22:25 +0200 Subject: [PATCH 06/19] Return nil on program action if an error occurred --- commands/upload/upload.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/commands/upload/upload.go b/commands/upload/upload.go index 4f94267ec3b..ce7e1f0f6c6 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -127,7 +127,7 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er pm := commands.GetPackageManager(req.GetInstance().GetId()) - return &rpc.UploadResponse{}, runProgramAction( + if err := runProgramAction( pm, sk, req.GetImportFile(), @@ -142,7 +142,11 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er errStream, req.GetDryRun(), req.GetUserFields(), - ) + ); err != nil { + return nil, err + } + + return &rpc.UploadResponse{}, nil } // UsingProgrammer FIXMEDOC From acf791ec27d908980e126e491b39a798054e4b82 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 25 Aug 2021 11:13:11 +0200 Subject: [PATCH 07/19] Refactoring 'upload' commands --- arduino/cores/fqbn.go | 8 +- cli/compile/compile.go | 15 +- commands/daemon/daemon.go | 15 +- commands/errors.go | 207 ++++++++++++++++++++++++++++ commands/upload/burnbootloader.go | 3 +- commands/upload/programmers_list.go | 10 +- commands/upload/upload.go | 68 ++++----- commands/upload/upload_test.go | 2 +- 8 files changed, 270 insertions(+), 58 deletions(-) create mode 100644 commands/errors.go diff --git a/arduino/cores/fqbn.go b/arduino/cores/fqbn.go index e107cdda168..68391781220 100644 --- a/arduino/cores/fqbn.go +++ b/arduino/cores/fqbn.go @@ -35,7 +35,7 @@ func ParseFQBN(fqbnIn string) (*FQBN, error) { // Split fqbn fqbnParts := strings.Split(fqbnIn, ":") if len(fqbnParts) < 3 || len(fqbnParts) > 4 { - return nil, fmt.Errorf("invalid fqbn: %s", fqbnIn) + return nil, fmt.Errorf("not an FQBN: %s", fqbnIn) } fqbn := &FQBN{ @@ -45,18 +45,18 @@ func ParseFQBN(fqbnIn string) (*FQBN, error) { Configs: properties.NewMap(), } if fqbn.BoardID == "" { - return nil, fmt.Errorf(tr("invalid fqbn: empty board identifier")) + return nil, fmt.Errorf(tr("empty board identifier")) } if len(fqbnParts) > 3 { for _, pair := range strings.Split(fqbnParts[3], ",") { parts := strings.SplitN(pair, "=", 2) if len(parts) != 2 { - return nil, fmt.Errorf(tr("invalid fqbn config: %s"), pair) + return nil, fmt.Errorf(tr("invalid config oprion: %s"), pair) } k := strings.TrimSpace(parts[0]) v := strings.TrimSpace(parts[1]) if k == "" { - return nil, fmt.Errorf(tr("invalid fqbn config: %s"), pair) + return nil, fmt.Errorf(tr("invalid config option: %s"), pair) } fqbn.Configs.Set(k, v) } diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 4f6deb2e9ed..7d099ab117b 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -231,17 +231,18 @@ func run(cmd *cobra.Command, args []string) { Programmer: programmer, UserFields: fields, } - var st *status.Status + + var uploadError error if output.OutputFormat == "json" { // TODO: do not print upload output in json mode - uploadOut := new(bytes.Buffer) - uploadErr := new(bytes.Buffer) - _, st = upload.Upload(context.Background(), uploadRequest, uploadOut, uploadErr) + uploadStdOut := new(bytes.Buffer) + uploadStdErr := new(bytes.Buffer) + _, uploadError = upload.Upload(context.Background(), uploadRequest, uploadStdOut, uploadStdErr) } else { - _, st = upload.Upload(context.Background(), uploadRequest, os.Stdout, os.Stderr) + _, uploadError = upload.Upload(context.Background(), uploadRequest, os.Stdout, os.Stderr) } - if st != nil { - feedback.Errorf(tr("Error during Upload: %v"), st.Message()) + if uploadError != nil { + feedback.Errorf(tr("Error during Upload: %v"), uploadError) os.Exit(errorcodes.ErrGeneric) } } diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index 72acc4e2732..b1c786a0ad8 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -41,6 +41,13 @@ type ArduinoCoreServerImpl struct { var tr = i18n.Tr +func convertErrorToRPCStatus(err error) error { + if cmdErr, ok := err.(commands.CommandError); ok { + return cmdErr.ToRPCStatus().Err() + } + return err +} + // BoardDetails FIXMEDOC func (s *ArduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { resp, err := board.Details(ctx, req) @@ -336,7 +343,7 @@ func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.Arduin utils.FeedStreamTo(func(data []byte) { stream.Send(&rpc.UploadResponse{ErrStream: data}) }), ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -349,7 +356,7 @@ func (s *ArduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgra utils.FeedStreamTo(func(data []byte) { stream.Send(&rpc.UploadUsingProgrammerResponse{ErrStream: data}) }), ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -362,7 +369,7 @@ func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, s utils.FeedStreamTo(func(data []byte) { stream.Send(&rpc.BurnBootloaderResponse{ErrStream: data}) }), ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -370,7 +377,7 @@ func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, s // ListProgrammersAvailableForUpload FIXMEDOC func (s *ArduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { resp, err := upload.ListProgrammersAvailableForUpload(ctx, req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // LibraryDownload FIXMEDOC diff --git a/commands/errors.go b/commands/errors.go new file mode 100644 index 00000000000..541445028f8 --- /dev/null +++ b/commands/errors.go @@ -0,0 +1,207 @@ +// This file is part of arduino-cli. +// +// Copyright 2020 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 commands + +import ( + "fmt" + + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func composeErrorMsg(msg string, cause error) string { + if cause == nil { + return msg + } + return fmt.Sprintf("%v: %v", msg, cause) +} + +// CommandError is an error that may be converted into a gRPC status. +type CommandError interface { + ToRPCStatus() *status.Status +} + +// InvalidInstanceError is returned if the instance used in the command is not valid. +type InvalidInstanceError struct{} + +func (e *InvalidInstanceError) Error() string { + return tr("Invalid instance") +} + +func (e *InvalidInstanceError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +// InvalidFQBNError is returned when the FQBN has syntax errors +type InvalidFQBNError struct { + Cause error +} + +func (e *InvalidFQBNError) Error() string { + return composeErrorMsg(tr("Invalid FQBN"), e.Cause) +} + +func (e *InvalidFQBNError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +func (e *InvalidFQBNError) Unwrap() error { + return e.Cause +} + +// MissingFQBNError is returned when the FQBN is mandatory and not specified +type MissingFQBNError struct{} + +func (e *MissingFQBNError) Error() string { + return tr("Missing FQBN (Fully Qualified Board Name)") +} + +func (e *MissingFQBNError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +// UnknownFQBNError is returned when the FQBN is not found +type UnknownFQBNError struct { + Cause error +} + +func (e *UnknownFQBNError) Error() string { + return composeErrorMsg(tr("Unknown FQBN"), e.Cause) +} + +func (e *UnknownFQBNError) Unwrap() error { + return e.Cause +} + +func (e *UnknownFQBNError) ToRPCStatus() *status.Status { + return status.New(codes.NotFound, e.Error()) +} + +// MissingPortProtocolError is returned when the port protocol is mandatory and not specified +type MissingPortProtocolError struct{} + +func (e *MissingPortProtocolError) Error() string { + return tr("Missing port protocol") +} + +func (e *MissingPortProtocolError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +// MissingProgrammerError is returned when the programmer is mandatory and not specified +type MissingProgrammerError struct{} + +func (e *MissingProgrammerError) Error() string { + return tr("Missing programmer") +} + +func (e *MissingProgrammerError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +// ProgreammerRequiredForUploadError is returned then the upload can be done only using a programmer +type ProgreammerRequiredForUploadError struct{} + +func (e *ProgreammerRequiredForUploadError) Error() string { + return tr("A programmer is required to upload") +} + +func (e *ProgreammerRequiredForUploadError) ToRPCStatus() *status.Status { + st, _ := status. + New(codes.InvalidArgument, e.Error()). + WithDetails(&rpc.ProgrammerIsRequiredForUploadError{}) + return st +} + +// UnknownProgrammerError is returned when the programmer is not found +type UnknownProgrammerError struct { + Cause error +} + +func (e *UnknownProgrammerError) Error() string { + return composeErrorMsg(tr("Unknown programmer"), e.Cause) +} + +func (e *UnknownProgrammerError) Unwrap() error { + return e.Cause +} + +func (e *UnknownProgrammerError) ToRPCStatus() *status.Status { + return status.New(codes.NotFound, e.Error()) +} + +// InvalidPlatformPropertyError is returned when a property in the platform is not valid +type InvalidPlatformPropertyError struct { + Property string + Value string +} + +func (e *InvalidPlatformPropertyError) Error() string { + return tr("Invalid '%[1]s' property: %[2]s", e.Property, e.Value) +} + +func (e *InvalidPlatformPropertyError) ToRPCStatus() *status.Status { + return status.New(codes.FailedPrecondition, e.Error()) +} + +// MissingPlatformPropertyError is returned when a property in the platform is not found +type MissingPlatformPropertyError struct { + Property string +} + +func (e *MissingPlatformPropertyError) Error() string { + return tr("Property '%s' is undefined", e.Property) +} + +func (e *MissingPlatformPropertyError) ToRPCStatus() *status.Status { + return status.New(codes.FailedPrecondition, e.Error()) +} + +// SketchNotFoundError is returned when the sketch is not found +type SketchNotFoundError struct { + Cause error +} + +func (e *SketchNotFoundError) Error() string { + return composeErrorMsg(tr("Sketch not found"), e.Cause) +} + +func (e *SketchNotFoundError) Unwrap() error { + return e.Cause +} + +func (e *SketchNotFoundError) ToRPCStatus() *status.Status { + return status.New(codes.NotFound, e.Error()) +} + +// FailedUploadError is returned when the upload fails +type FailedUploadError struct { + Message string + Cause error +} + +func (e *FailedUploadError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *FailedUploadError) Unwrap() error { + return e.Cause +} + +func (e *FailedUploadError) ToRPCStatus() *status.Status { + return status.New(codes.Internal, e.Error()) +} diff --git a/commands/upload/burnbootloader.go b/commands/upload/burnbootloader.go index d9a0559c68a..8866bbdb837 100644 --- a/commands/upload/burnbootloader.go +++ b/commands/upload/burnbootloader.go @@ -22,11 +22,10 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" - "google.golang.org/grpc/status" ) // BurnBootloader FIXMEDOC -func BurnBootloader(ctx context.Context, req *rpc.BurnBootloaderRequest, outStream io.Writer, errStream io.Writer) (*rpc.BurnBootloaderResponse, *status.Status) { +func BurnBootloader(ctx context.Context, req *rpc.BurnBootloaderRequest, outStream io.Writer, errStream io.Writer) (*rpc.BurnBootloaderResponse, error) { logrus. WithField("fqbn", req.GetFqbn()). WithField("port", req.GetPort()). diff --git a/commands/upload/programmers_list.go b/commands/upload/programmers_list.go index 26fa6aa2ef1..1da6d93a2f7 100644 --- a/commands/upload/programmers_list.go +++ b/commands/upload/programmers_list.go @@ -21,27 +21,25 @@ import ( "github.com/arduino/arduino-cli/arduino/cores" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // ListProgrammersAvailableForUpload FIXMEDOC -func ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, *status.Status) { +func ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) fqbnIn := req.GetFqbn() if fqbnIn == "" { - return nil, status.New(codes.InvalidArgument, tr("No FQBN (Fully Qualified Board Name) provided")) + return nil, &commands.MissingFQBNError{} } fqbn, err := cores.ParseFQBN(fqbnIn) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Invalid FQBN: %s"), err) + return nil, &commands.InvalidFQBNError{Cause: err} } // Find target platforms _, platform, _, _, refPlatform, err := pm.ResolveFQBN(fqbn) if err != nil { - return nil, status.Newf(codes.Unknown, tr("Invalid FQBN: %s"), err) + return nil, &commands.UnknownFQBNError{Cause: err} } result := []*rpc.Programmer{} diff --git a/commands/upload/upload.go b/commands/upload/upload.go index ce7e1f0f6c6..9c28de7bf46 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -35,8 +35,6 @@ import ( properties "github.com/arduino/go-properties-orderedmap" "github.com/pkg/errors" "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var tr = i18n.Tr @@ -45,27 +43,27 @@ var tr = i18n.Tr // by the upload tools needed by the board using the protocol specified in SupportedUserFieldsRequest. func SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsRequest) (*rpc.SupportedUserFieldsResponse, error) { if req.Protocol == "" { - return nil, fmt.Errorf(tr("missing protocol")) + return nil, &commands.MissingPortProtocolError{} } pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, fmt.Errorf(tr("invalid instance")) + return nil, &commands.InvalidInstanceError{} } fqbn, err := cores.ParseFQBN(req.GetFqbn()) if err != nil { - return nil, fmt.Errorf(tr("parsing fqbn: %s"), err) + return nil, &commands.InvalidFQBNError{Cause: err} } _, platformRelease, board, _, _, err := pm.ResolveFQBN(fqbn) if err != nil { - return nil, fmt.Errorf(tr("loading board data: %s"), err) + return nil, &commands.UnknownFQBNError{Cause: err} } - toolID, st := getToolID(board.Properties, "upload", req.Protocol) - if st != nil { - return nil, st.Err() + toolID, err := getToolID(board.Properties, "upload", req.Protocol) + if err != nil { + return nil, err } return &rpc.SupportedUserFieldsResponse{ @@ -75,18 +73,21 @@ func SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsReques // getToolID returns the ID of the tool that supports the action and protocol combination by searching in props. // Returns error if tool cannot be found. -func getToolID(props *properties.Map, action, protocol string) (string, *status.Status) { +func getToolID(props *properties.Map, action, protocol string) (string, error) { toolProperty := fmt.Sprintf("%s.tool.%s", action, protocol) defaultToolProperty := fmt.Sprintf("%s.tool.default", action) if t, ok := props.GetOk(toolProperty); ok { return t, nil - } else if t, ok := props.GetOk(defaultToolProperty); ok { + } + + if t, ok := props.GetOk(defaultToolProperty); ok { // Fallback for platform that don't support the specified protocol for specified action: // https://arduino.github.io/arduino-cli/latest/platform-specification/#sketch-upload-configuration return t, nil } - return "", status.Newf(codes.FailedPrecondition, tr("Cannot find tool: undefined '%s' property"), toolProperty) + + return "", &commands.MissingPlatformPropertyError{Property: toolProperty} } // getUserFields return all user fields supported by the tools specified. @@ -114,7 +115,7 @@ func getUserFields(toolID string, platformRelease *cores.PlatformRelease) []*rpc } // Upload FIXMEDOC -func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadResponse, *status.Status) { +func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadResponse, error) { logrus.Tracef("Upload %s on %s started", req.GetSketchPath(), req.GetFqbn()) // TODO: make a generic function to extract sketch from request @@ -122,7 +123,7 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil && req.GetImportDir() == "" && req.GetImportFile() == "" { - return nil, status.Newf(codes.InvalidArgument, tr("Sketch not found: %s"), err) + return nil, &commands.SketchNotFoundError{Cause: err} } pm := commands.GetPackageManager(req.GetInstance().GetId()) @@ -150,11 +151,11 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er } // UsingProgrammer FIXMEDOC -func UsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadUsingProgrammerResponse, *status.Status) { +func UsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadUsingProgrammerResponse, error) { logrus.Tracef("Upload using programmer %s on %s started", req.GetSketchPath(), req.GetFqbn()) if req.GetProgrammer() == "" { - return nil, status.New(codes.InvalidArgument, tr("Programmer not specified")) + return nil, &commands.MissingProgrammerError{} } _, err := Upload(ctx, &rpc.UploadRequest{ Instance: req.GetInstance(), @@ -177,10 +178,10 @@ func runProgramAction(pm *packagemanager.PackageManager, programmerID string, verbose, verify, burnBootloader bool, outStream, errStream io.Writer, - dryRun bool, userFields map[string]string) *status.Status { + dryRun bool, userFields map[string]string) error { if burnBootloader && programmerID == "" { - return status.New(codes.InvalidArgument, tr("No programmer specified for burning bootloader")) + return &commands.MissingProgrammerError{} } logrus.WithField("port", port).Tracef("Upload port") @@ -189,18 +190,18 @@ func runProgramAction(pm *packagemanager.PackageManager, fqbnIn = sk.Metadata.CPU.Fqbn } if fqbnIn == "" { - return status.New(codes.InvalidArgument, tr("No FQBN (Fully Qualified Board Name) provided")) + return &commands.MissingFQBNError{} } fqbn, err := cores.ParseFQBN(fqbnIn) if err != nil { - return status.Newf(codes.InvalidArgument, fmt.Sprintf(tr("Invalid FQBN: %s"), err)) + return &commands.InvalidFQBNError{Cause: err} } logrus.WithField("fqbn", fqbn).Tracef("Detected FQBN") // Find target board and board properties _, boardPlatform, board, boardProperties, buildPlatform, err := pm.ResolveFQBN(fqbn) if err != nil { - return status.Newf(codes.InvalidArgument, tr("Could not resolve FQBN: %s"), err) + return &commands.UnknownFQBNError{Cause: err} } logrus. WithField("boardPlatform", boardPlatform). @@ -217,7 +218,7 @@ func runProgramAction(pm *packagemanager.PackageManager, programmer = buildPlatform.Programmers[programmerID] } if programmer == nil { - return status.Newf(codes.InvalidArgument, tr("Programmer '%s' not available"), programmerID) + return &commands.UnknownProgrammerError{Cause: fmt.Errorf(tr("programmer '%s' not available"), programmerID)} } } @@ -253,7 +254,9 @@ func runProgramAction(pm *packagemanager.PackageManager, Trace("Upload tool") if split := strings.Split(uploadToolID, ":"); len(split) > 2 { - return status.Newf(codes.FailedPrecondition, tr("Invalid 'upload.tool' property: %s"), uploadToolID) + return &commands.InvalidPlatformPropertyError{ + Property: fmt.Sprintf("%s.tool.%s", action, port.Protocol), // TODO: Can be done better, maybe inline getToolID(...) + Value: uploadToolID} } else if len(split) == 2 { uploadToolID = split[1] uploadToolPlatform = pm.GetInstalledPlatformRelease( @@ -301,10 +304,7 @@ func runProgramAction(pm *packagemanager.PackageManager, } if !uploadProperties.ContainsKey("upload.protocol") && programmer == nil { - err, _ := status. - Newf(codes.InvalidArgument, tr("A programmer is required to upload on this board")). - WithDetails(&rpc.ProgrammerIsRequiredForUploadError{}) - return err + return &commands.ProgreammerRequiredForUploadError{} } // Set properties for verbose upload @@ -352,13 +352,13 @@ func runProgramAction(pm *packagemanager.PackageManager, if !burnBootloader { importPath, sketchName, err := determineBuildPathAndSketchName(importFile, importDir, sk, fqbn) if err != nil { - return status.Newf(codes.Internal, tr("Error finding build artifacts: %s"), err) + return &commands.FailedUploadError{Message: tr("Error finding build artifacts"), Cause: err} } if !importPath.Exist() { - return status.Newf(codes.Internal, tr("Compiled sketch not found in %s"), importPath) + return &commands.FailedUploadError{Message: tr("Compiled sketch not found in %s", importPath)} } if !importPath.IsDir() { - return status.Newf(codes.Internal, tr("Expected compiled sketch in directory %s, but is a file instead"), importPath) + return &commands.FailedUploadError{Message: tr("Expected compiled sketch in directory %s, but is a file instead", importPath)} } uploadProperties.SetPath("build.path", importPath) uploadProperties.Set("build.project_name", sketchName) @@ -451,18 +451,18 @@ func runProgramAction(pm *packagemanager.PackageManager, // Run recipes for upload if burnBootloader { if err := runTool("erase.pattern", uploadProperties, outStream, errStream, verbose, dryRun); err != nil { - return status.Newf(codes.Internal, tr("Failed chip erase: %s"), err) + return &commands.FailedUploadError{Message: tr("Failed chip erase"), Cause: err} } if err := runTool("bootloader.pattern", uploadProperties, outStream, errStream, verbose, dryRun); err != nil { - return status.Newf(codes.Internal, tr("Failed to burn bootloader: %s"), err) + return &commands.FailedUploadError{Message: tr("Failed to burn bootloader"), Cause: err} } } else if programmer != nil { if err := runTool("program.pattern", uploadProperties, outStream, errStream, verbose, dryRun); err != nil { - return status.Newf(codes.Internal, tr("Failed programming: %s"), err) + return &commands.FailedUploadError{Message: tr("Failed programming"), Cause: err} } } else { if err := runTool("upload.pattern", uploadProperties, outStream, errStream, verbose, dryRun); err != nil { - return status.Newf(codes.Internal, tr("Failed uploading: %s"), err) + return &commands.FailedUploadError{Message: tr("Failed uploading"), Cause: err} } } diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 07708115083..9f7b04a6d3a 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -243,7 +243,7 @@ upload.tool.network=arduino_ota`)) require.Equal(t, "avrdude", toolID) toolID, err = getToolID(props, "bootloader", "network") - require.EqualError(t, err, "cannot find tool: undefined 'bootloader.tool.network' property") + require.EqualError(t, err, "Property 'bootloader.tool.network' is undefined") require.Equal(t, "", toolID) props, err = properties.LoadFromBytes([]byte(` From 4fa1080c3a50ef8760aa74207f54ef814ccf54f3 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 26 Aug 2021 00:55:14 +0200 Subject: [PATCH 08/19] Refactoring 'board' commands --- commands/board/attach.go | 16 ++++----- commands/board/details.go | 11 +++--- commands/board/list.go | 20 +++++------ commands/board/listall.go | 6 ++-- commands/board/search.go | 6 ++-- commands/daemon/daemon.go | 30 +++++----------- commands/errors.go | 72 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 104 insertions(+), 57 deletions(-) diff --git a/commands/board/attach.go b/commands/board/attach.go index 14957d051a5..459bbc89b74 100644 --- a/commands/board/attach.go +++ b/commands/board/attach.go @@ -30,17 +30,15 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" discovery "github.com/arduino/board-discovery" "github.com/arduino/go-paths-helper" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var tr = i18n.Tr // Attach FIXMEDOC -func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.TaskProgressCB) (*rpc.BoardAttachResponse, *status.Status) { +func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.TaskProgressCB) (*rpc.BoardAttachResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } var sketchPath *paths.Path if req.GetSketchPath() != "" { @@ -48,7 +46,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta } sk, err := sketch.New(sketchPath) if err != nil { - return nil, status.Newf(codes.FailedPrecondition, tr("Error opening sketch: %s"), err) + return nil, &commands.SketchNotFoundError{Cause: err} } boardURI := req.GetBoardUri() @@ -64,7 +62,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta } else { deviceURI, err := url.Parse(boardURI) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Invalid Device URL format: %s"), err) + return nil, &commands.InvalidArgumentError{Message: tr("Invalid Device URL format"), Cause: err} } var findBoardFunc func(*packagemanager.PackageManager, *discovery.Monitor, *url.URL) *cores.Board @@ -74,7 +72,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta case "http", "https", "tcp", "udp": findBoardFunc = findNetworkConnectedBoard default: - return nil, status.New(codes.InvalidArgument, tr("Invalid device port type provided")) + return nil, &commands.InvalidArgumentError{Message: tr("Invalid device port type provided")} } duration, err := time.ParseDuration(req.GetSearchTimeout()) @@ -90,7 +88,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta // TODO: Handle the case when no board is found. board := findBoardFunc(pm, monitor, deviceURI) if board == nil { - return nil, status.Newf(codes.NotFound, tr("No supported board found at %s"), deviceURI.String()) + return nil, &commands.InvalidArgumentError{Message: tr("No supported board found at %s", deviceURI)} } taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Board found: %s"), board.Name())}) @@ -105,7 +103,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta err = sk.ExportMetadata() if err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Cannot export sketch metadata: %s"), err) + return nil, &commands.PermissionDeniedError{Message: tr("Cannot export sketch metadata"), Cause: err} } taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Selected fqbn: %s"), sk.Metadata.CPU.Fqbn), Completed: true}) return &rpc.BoardAttachResponse{}, nil diff --git a/commands/board/details.go b/commands/board/details.go index 9cd3239ff88..c22f7f2526e 100644 --- a/commands/board/details.go +++ b/commands/board/details.go @@ -21,27 +21,24 @@ import ( "github.com/arduino/arduino-cli/arduino/cores" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // Details returns all details for a board including tools and HW identifiers. // This command basically gather al the information and translates it into the required grpc struct properties -func Details(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, *status.Status) { +func Details(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } fqbn, err := cores.ParseFQBN(req.GetFqbn()) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Error parsing fqbn: %s"), err) + return nil, &commands.InvalidFQBNError{Cause: err} } boardPackage, boardPlatform, board, boardProperties, boardRefPlatform, err := pm.ResolveFQBN(fqbn) - if err != nil { - return nil, status.Newf(codes.FailedPrecondition, tr("Error loading board data: %s"), err) + return nil, &commands.UnknownFQBNError{Cause: err} } details := &rpc.BoardDetailsResponse{} diff --git a/commands/board/list.go b/commands/board/list.go index 9e08ffe6c44..84d1fff773b 100644 --- a/commands/board/list.go +++ b/commands/board/list.go @@ -33,8 +33,6 @@ import ( "github.com/pkg/errors" "github.com/segmentio/stats/v4" "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var ( @@ -139,7 +137,7 @@ func identify(pm *packagemanager.PackageManager, port *discovery.Port) ([]*rpc.B logrus.Debug("Board not recognized") } else if err != nil { // this is bad, bail out - return nil, errors.Wrap(err, tr("error getting board info from Arduino Cloud")) + return nil, &commands.UnavailableError{Message: tr("Error getting board info from Arduino Cloud")} } // add a DetectedPort entry in any case: the `Boards` field will @@ -170,7 +168,7 @@ func identify(pm *packagemanager.PackageManager, port *discovery.Port) ([]*rpc.B } // List FIXMEDOC -func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e *status.Status) { +func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e error) { tags := map[string]string{} // Use defer func() to evaluate tags map when function returns // and set success flag inspecting the error named return parameter @@ -184,15 +182,15 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e *status.Status) { pm := commands.GetPackageManager(req.GetInstance().Id) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } dm := pm.DiscoveryManager() if errs := dm.RunAll(); len(errs) > 0 { - return nil, status.New(codes.FailedPrecondition, tr("Error getting port list: %v", errs)) + return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: errs[0]} } if errs := dm.StartAll(); len(errs) > 0 { - return nil, status.New(codes.FailedPrecondition, tr("Error getting port list: %v", errs)) + return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: errs[0]} } defer func() { if errs := dm.StopAll(); len(errs) > 0 { @@ -204,12 +202,12 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e *status.Status) { retVal := []*rpc.DetectedPort{} ports, errs := pm.DiscoveryManager().List() if len(errs) > 0 { - return nil, status.New(codes.FailedPrecondition, tr("Error getting port list: %v", errs)) + return nil, &commands.UnavailableError{Message: tr("Error getting board list"), Cause: errs[0]} } for _, port := range ports { boards, err := identify(pm, port) if err != nil { - return nil, status.New(codes.Internal, err.Error()) + return nil, err } // boards slice can be empty at this point if neither the cores nor the @@ -226,14 +224,14 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e *status.Status) { // Watch returns a channel that receives boards connection and disconnection events. // The discovery process can be interrupted by sending a message to the interrupt channel. -func Watch(instanceID int32, interrupt <-chan bool) (<-chan *rpc.BoardListWatchResponse, *status.Status) { +func Watch(instanceID int32, interrupt <-chan bool) (<-chan *rpc.BoardListWatchResponse, error) { pm := commands.GetPackageManager(instanceID) dm := pm.DiscoveryManager() runErrs := dm.RunAll() if len(runErrs) == len(dm.IDs()) { // All discoveries failed to run, we can't do anything - return nil, status.New(codes.FailedPrecondition, fmt.Sprintf("%v", runErrs)) + return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: runErrs[0]} } eventsChan, errs := dm.StartSyncAll() diff --git a/commands/board/listall.go b/commands/board/listall.go index 74fa859be56..0a80a43ac16 100644 --- a/commands/board/listall.go +++ b/commands/board/listall.go @@ -22,15 +22,13 @@ import ( "github.com/arduino/arduino-cli/arduino/utils" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // ListAll FIXMEDOC -func ListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, *status.Status) { +func ListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } searchArgs := strings.Join(req.GetSearchArgs(), " ") diff --git a/commands/board/search.go b/commands/board/search.go index f35e9b57c5e..c04c65b4d59 100644 --- a/commands/board/search.go +++ b/commands/board/search.go @@ -23,18 +23,16 @@ import ( "github.com/arduino/arduino-cli/arduino/utils" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // Search returns all boards that match the search arg. // Boards are searched in all platforms, including those in the index that are not yet // installed. Note that platforms that are not installed don't include boards' FQBNs. // If no search argument is used all boards are returned. -func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, *status.Status) { +func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } res := &rpc.BoardSearchResponse{Boards: []*rpc.BoardListItem{}} diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index b1c786a0ad8..1c716465f70 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -51,20 +51,15 @@ func convertErrorToRPCStatus(err error) error { // BoardDetails FIXMEDOC func (s *ArduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { resp, err := board.Details(ctx, req) - if err != nil { - return nil, err.Err() - } - - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // BoardList FIXMEDOC func (s *ArduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { ports, err := board.List(req) if err != nil { - return nil, err.Err() + return nil, convertErrorToRPCStatus(err) } - return &rpc.BoardListResponse{ Ports: ports, }, nil @@ -73,21 +68,13 @@ func (s *ArduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardLis // BoardListAll FIXMEDOC func (s *ArduinoCoreServerImpl) BoardListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { resp, err := board.ListAll(ctx, req) - if err != nil { - return nil, err.Err() - } - - return resp, nil + return resp, convertErrorToRPCStatus(err) } // BoardSearch exposes to the gRPC interface the board search command func (s *ArduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { resp, err := board.Search(ctx, req) - if err != nil { - return nil, err.Err() - } - - return resp, nil + return resp, convertErrorToRPCStatus(err) } // BoardListWatch FIXMEDOC @@ -134,9 +121,9 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(stream rpc.ArduinoCoreService_Boa } }() - eventsChan, stat := board.Watch(msg.Instance.Id, interrupt) - if stat != nil { - return stat.Err() + eventsChan, err := board.Watch(msg.Instance.Id, interrupt) + if err != nil { + return convertErrorToRPCStatus(err) } for event := range eventsChan { @@ -151,12 +138,11 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(stream rpc.ArduinoCoreService_Boa // BoardAttach FIXMEDOC func (s *ArduinoCoreServerImpl) BoardAttach(req *rpc.BoardAttachRequest, stream rpc.ArduinoCoreService_BoardAttachServer) error { - resp, err := board.Attach(stream.Context(), req, func(p *rpc.TaskProgress) { stream.Send(&rpc.BoardAttachResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } diff --git a/commands/errors.go b/commands/errors.go index 541445028f8..715483ecb3e 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -205,3 +205,75 @@ func (e *FailedUploadError) Unwrap() error { func (e *FailedUploadError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } + +// InvalidArgumentError is returned when an invalid argument is passed to the command +type InvalidArgumentError struct { + Message string + Cause error +} + +func (e *InvalidArgumentError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *InvalidArgumentError) Unwrap() error { + return e.Cause +} + +func (e *InvalidArgumentError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +// NotFoundError is returned when a resource is not found +type NotFoundError struct { + Message string + Cause error +} + +func (e *NotFoundError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *NotFoundError) Unwrap() error { + return e.Cause +} + +func (e *NotFoundError) ToRPCStatus() *status.Status { + return status.New(codes.NotFound, e.Error()) +} + +// PermissionDeniedError is returned when a resource cannot be accessed or modified +type PermissionDeniedError struct { + Message string + Cause error +} + +func (e *PermissionDeniedError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *PermissionDeniedError) Unwrap() error { + return e.Cause +} + +func (e *PermissionDeniedError) ToRPCStatus() *status.Status { + return status.New(codes.PermissionDenied, e.Error()) +} + +// UnavailableError is returned when a resource is temporarily not available +type UnavailableError struct { + Message string + Cause error +} + +func (e *UnavailableError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *UnavailableError) Unwrap() error { + return e.Cause +} + +func (e *UnavailableError) ToRPCStatus() *status.Status { + return status.New(codes.Unavailable, e.Error()) +} From ce3f802820ee87870f8022e87403d80bc925b2b5 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 26 Aug 2021 01:48:57 +0200 Subject: [PATCH 09/19] Refactoring 'compile' commands --- arduino/libraries/libraries.go | 2 +- cli/compile/compile.go | 23 ++++++++--------- commands/compile/compile.go | 46 +++++++++++++++++++--------------- commands/errors.go | 42 +++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 33 deletions(-) diff --git a/arduino/libraries/libraries.go b/arduino/libraries/libraries.go index c3271742471..c20196ab473 100644 --- a/arduino/libraries/libraries.go +++ b/arduino/libraries/libraries.go @@ -111,7 +111,7 @@ func (library *Library) ToRPCLibrary() (*rpc.Library, error) { var err error headers, err = library.SourceHeaders() if err != nil { - return nil, fmt.Errorf(tr("gathering library headers: %w"), err) + return nil, fmt.Errorf(tr("reading library headers: %w"), err) } } diff --git a/cli/compile/compile.go b/cli/compile/compile.go index 7d099ab117b..6d7d7e883d5 100644 --- a/cli/compile/compile.go +++ b/cli/compile/compile.go @@ -29,7 +29,6 @@ import ( "github.com/arduino/arduino-cli/cli/output" "github.com/arduino/arduino-cli/configuration" "github.com/arduino/arduino-cli/i18n" - "google.golang.org/grpc/status" "github.com/arduino/arduino-cli/cli/errorcodes" "github.com/arduino/arduino-cli/cli/instance" @@ -179,18 +178,18 @@ func run(cmd *cobra.Command, args []string) { SourceOverride: overrides, Library: library, } - compileOut := new(bytes.Buffer) - compileErr := new(bytes.Buffer) + compileStdOut := new(bytes.Buffer) + compileStdErr := new(bytes.Buffer) verboseCompile := configuration.Settings.GetString("logging.level") == "debug" var compileRes *rpc.CompileResponse - var st *status.Status + var compileError error if output.OutputFormat == "json" { - compileRes, st = compile.Compile(context.Background(), compileRequest, compileOut, compileErr, verboseCompile) + compileRes, compileError = compile.Compile(context.Background(), compileRequest, compileStdOut, compileStdErr, verboseCompile) } else { - compileRes, st = compile.Compile(context.Background(), compileRequest, os.Stdout, os.Stderr, verboseCompile) + compileRes, compileError = compile.Compile(context.Background(), compileRequest, os.Stdout, os.Stderr, verboseCompile) } - if st == nil && uploadAfterCompile { + if compileError == nil && uploadAfterCompile { var sk *sketch.Sketch sk, err := sketch.New(sketchPath) if err != nil { @@ -248,13 +247,13 @@ func run(cmd *cobra.Command, args []string) { } feedback.PrintResult(&compileResult{ - CompileOut: compileOut.String(), - CompileErr: compileErr.String(), + CompileOut: compileStdOut.String(), + CompileErr: compileStdErr.String(), BuilderResult: compileRes, - Success: st == nil, + Success: compileError == nil, }) - if st != nil && output.OutputFormat != "json" { - feedback.Errorf(tr("Error during build: %v"), st.Message()) + if compileError != nil && output.OutputFormat != "json" { + feedback.Errorf(tr("Error during build: %v"), compileError) os.Exit(errorcodes.ErrGeneric) } } diff --git a/commands/compile/compile.go b/commands/compile/compile.go index 0838b5852f6..6a84acc3fbd 100644 --- a/commands/compile/compile.go +++ b/commands/compile/compile.go @@ -17,6 +17,7 @@ package compile import ( "context" + "errors" "io" "path/filepath" "sort" @@ -37,17 +38,14 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" - "github.com/pkg/errors" "github.com/segmentio/stats/v4" "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var tr = i18n.Tr // Compile FIXMEDOC -func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream io.Writer, debug bool) (r *rpc.CompileResponse, e *status.Status) { +func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream io.Writer, debug bool) (r *rpc.CompileResponse, e error) { // There is a binding between the export binaries setting and the CLI flag to explicitly set it, // since we want this binding to work also for the gRPC interface we must read it here in this @@ -91,17 +89,17 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } logrus.Tracef("Compile %s for %s started", req.GetSketchPath(), req.GetFqbn()) if req.GetSketchPath() == "" { - return nil, status.New(codes.InvalidArgument, tr("Missing sketch path")) + return nil, &commands.MissingSketchPathError{} } sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil { - return nil, status.Newf(codes.NotFound, tr("Error opening sketch: %s"), err) + return nil, &commands.SketchNotFoundError{Cause: err} } fqbnIn := req.GetFqbn() @@ -109,11 +107,11 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream fqbnIn = sk.Metadata.CPU.Fqbn } if fqbnIn == "" { - return nil, status.New(codes.InvalidArgument, tr("No FQBN (Fully Qualified Board Name) provided")) + return nil, &commands.MissingFQBNError{} } fqbn, err := cores.ParseFQBN(fqbnIn) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Invalid FQBN: %s"), err) + return nil, &commands.InvalidFQBNError{Cause: err} } targetPlatform := pm.FindPlatform(&packagemanager.PlatformReference{ @@ -126,7 +124,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream // "\"%[1]s:%[2]s\" platform is not installed, please install it by running \""+ // version.GetAppName()+" core install %[1]s:%[2]s\".", fqbn.Package, fqbn.PlatformArch) // feedback.Error(errorMessage) - return nil, status.New(codes.NotFound, tr("Platform not installed")) + return nil, &commands.PlatformNotFound{Platform: targetPlatform.String(), Cause: errors.New(tr("platform not installed"))} } builderCtx := &types.Context{} @@ -149,7 +147,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream builderCtx.BuildPath = paths.New(req.GetBuildPath()) } if err = builderCtx.BuildPath.MkdirAll(); err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Cannot create build directory: %s"), err) + return nil, &commands.PermissionDeniedError{Message: tr("Cannot create build directory"), Cause: err} } builderCtx.CompilationDatabase = bldr.NewCompilationDatabase( builderCtx.BuildPath.Join("compile_commands.json"), @@ -179,7 +177,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream builderCtx.BuildCachePath = paths.New(req.GetBuildCachePath()) err = builderCtx.BuildCachePath.MkdirAll() if err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Cannot create build cache directory: %s"), err) + return nil, &commands.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err} } } @@ -222,14 +220,22 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream // if --preprocess or --show-properties were passed, we can stop here if req.GetShowProperties() { - return r, status.Convert(builder.RunParseHardwareAndDumpBuildProperties(builderCtx)) + compileErr := builder.RunParseHardwareAndDumpBuildProperties(builderCtx) + if compileErr != nil { + compileErr = &commands.CompileFailedError{Message: err.Error()} + } + return r, compileErr } else if req.GetPreprocess() { - return r, status.Convert(builder.RunPreprocess(builderCtx)) + compileErr := builder.RunPreprocess(builderCtx) + if compileErr != nil { + compileErr = &commands.CompileFailedError{Message: err.Error()} + } + return r, compileErr } // if it's a regular build, go on... if err := builder.RunBuilder(builderCtx); err != nil { - return r, status.Convert(err) + return r, &commands.CompileFailedError{Message: err.Error()} } // If the export directory is set we assume you want to export the binaries @@ -251,17 +257,17 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream } logrus.WithField("path", exportPath).Trace("Saving sketch to export path.") if err := exportPath.MkdirAll(); err != nil { - return r, status.New(codes.PermissionDenied, errors.Wrap(err, tr("Error creating output dir")).Error()) + return r, &commands.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err} } // Copy all "sketch.ino.*" artifacts to the export directory baseName, ok := builderCtx.BuildProperties.GetOk("build.project_name") // == "sketch.ino" if !ok { - return r, status.New(codes.Internal, tr("Missing 'build.project_name' build property")) + return r, &commands.MissingPlatformPropertyError{Property: "build.project_name"} } buildFiles, err := builderCtx.BuildPath.ReadDir() if err != nil { - return r, status.Newf(codes.PermissionDenied, tr("Error reading build directory: %s"), err) + return r, &commands.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err} } buildFiles.FilterPrefix(baseName) for _, buildFile := range buildFiles { @@ -271,7 +277,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream WithField("dest", exportedFile). Trace("Copying artifact.") if err = buildFile.CopyTo(exportedFile); err != nil { - return r, status.New(codes.PermissionDenied, tr("Error copying output file %[1]s: %[2]s", buildFile, err)) + return r, &commands.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err} } } } @@ -280,7 +286,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream for _, lib := range builderCtx.ImportedLibraries { rpcLib, err := lib.ToRPCLibrary() if err != nil { - return r, status.Newf(codes.PermissionDenied, tr("Error converting library %[1]s to rpc struct: %[2]s", lib.Name, err)) + return r, &commands.PermissionDeniedError{Message: tr("Error getting information for library %s", lib.Name), Cause: err} } importedLibs = append(importedLibs, rpcLib) } diff --git a/commands/errors.go b/commands/errors.go index 715483ecb3e..7666147bc84 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -171,6 +171,30 @@ func (e *MissingPlatformPropertyError) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } +// PlatformNotFound is returned when a platform is not found +type PlatformNotFound struct { + Platform string +} + +func (e *PlatformNotFound) Error() string { + return tr("Platform '%s' is not installed", e.Platform) +} + +func (e *PlatformNotFound) ToRPCStatus() *status.Status { + return status.New(codes.FailedPrecondition, e.Error()) +} + +// MissingSketchPathError is returned when the sketch path is mandatory and not specified +type MissingSketchPathError struct{} + +func (e *MissingSketchPathError) Error() string { + return tr("Missing sketch path") +} + +func (e *MissingSketchPathError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + // SketchNotFoundError is returned when the sketch is not found type SketchNotFoundError struct { Cause error @@ -206,6 +230,24 @@ func (e *FailedUploadError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } +// CompileFailedError is returned when the compile fails +type CompileFailedError struct { + Message string + Cause error +} + +func (e *CompileFailedError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *CompileFailedError) Unwrap() error { + return e.Cause +} + +func (e *CompileFailedError) ToRPCStatus() *status.Status { + return status.New(codes.Internal, e.Error()) +} + // InvalidArgumentError is returned when an invalid argument is passed to the command type InvalidArgumentError struct { Message string From 5890cb281773607aafff41c193faf139a5d691d1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 26 Aug 2021 11:01:09 +0200 Subject: [PATCH 10/19] Refactoring 'core' commands --- cli/core/upgrade.go | 13 +++--- commands/bundled_tools.go | 2 +- commands/core/download.go | 41 +++++++++-------- commands/core/install.go | 56 +++++++++++------------ commands/core/list.go | 18 ++------ commands/core/search.go | 10 +--- commands/core/uninstall.go | 32 ++++++------- commands/core/upgrade.go | 33 +++++-------- commands/daemon/daemon.go | 14 +++--- commands/errors.go | 94 +++++++++++++++++++++++++++++++++++++- 10 files changed, 187 insertions(+), 126 deletions(-) diff --git a/cli/core/upgrade.go b/cli/core/upgrade.go index f6398eb0984..7c95e59aaae 100644 --- a/cli/core/upgrade.go +++ b/cli/core/upgrade.go @@ -17,6 +17,7 @@ package core import ( "context" + "errors" "fmt" "os" @@ -25,6 +26,7 @@ import ( "github.com/arduino/arduino-cli/cli/feedback" "github.com/arduino/arduino-cli/cli/instance" "github.com/arduino/arduino-cli/cli/output" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/core" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" @@ -94,13 +96,10 @@ func runUpgradeCommand(cmd *cobra.Command, args []string) { SkipPostInstall: DetectSkipPostInstallValue(), } - _, err := core.PlatformUpgrade(context.Background(), r, output.ProgressBar(), output.TaskProgress()) - if err != nil { - if d := err.Details(); len(d) > 0 { - if _, ok := d[0].(*rpc.AlreadyAtLatestVersionError); ok { - feedback.Printf(tr("Platform %s is already at the latest version", platformRef)) - continue - } + if _, err := core.PlatformUpgrade(context.Background(), r, output.ProgressBar(), output.TaskProgress()); err != nil { + if errors.Is(err, &commands.PlatformAlreadyAtTheLatestVersionError{}) { + feedback.Print(err.Error()) + continue } feedback.Errorf(tr("Error during upgrade: %v", err)) diff --git a/commands/bundled_tools.go b/commands/bundled_tools.go index 9fcb17ed137..c2c9a77a10e 100644 --- a/commands/bundled_tools.go +++ b/commands/bundled_tools.go @@ -51,7 +51,7 @@ func InstallToolRelease(pm *packagemanager.PackageManager, toolRelease *cores.To err := pm.InstallTool(toolRelease) if err != nil { log.WithError(err).Warn("Cannot install tool") - return fmt.Errorf(tr("installing tool %[1]s: %[2]s"), toolRelease, err) + return &FailedInstallError{Message: tr("Cannot install tool %s", toolRelease), Cause: err} } log.Info("Tool installed") taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("%s installed"), toolRelease), Completed: true}) diff --git a/commands/core/download.go b/commands/core/download.go index 6d76a2739e4..d19ce52b098 100644 --- a/commands/core/download.go +++ b/commands/core/download.go @@ -17,49 +17,46 @@ package core import ( "context" - "fmt" + "errors" "github.com/arduino/arduino-cli/arduino/cores" "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var tr = i18n.Tr // PlatformDownload FIXMEDOC -func PlatformDownload(ctx context.Context, req *rpc.PlatformDownloadRequest, downloadCB commands.DownloadProgressCB) (*rpc.PlatformDownloadResponse, *status.Status) { +func PlatformDownload(ctx context.Context, req *rpc.PlatformDownloadRequest, downloadCB commands.DownloadProgressCB) (*rpc.PlatformDownloadResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } version, err := commands.ParseVersion(req) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Invalid version: %s"), err) + return nil, &commands.InvalidVersionError{Cause: err} } - platform, tools, err := pm.FindPlatformReleaseDependencies(&packagemanager.PlatformReference{ + ref := &packagemanager.PlatformReference{ Package: req.PlatformPackage, PlatformArchitecture: req.Architecture, PlatformVersion: version, - }) + } + platform, tools, err := pm.FindPlatformReleaseDependencies(ref) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Error finding platform dependencies: %s"), err) + return nil, &commands.PlatformNotFound{Platform: ref.String(), Cause: err} } - err = downloadPlatform(pm, platform, downloadCB) - if err != nil { - return nil, status.New(codes.Unavailable, err.Error()) + if err := downloadPlatform(pm, platform, downloadCB); err != nil { + return nil, err } for _, tool := range tools { - err := downloadTool(pm, tool, downloadCB) - if err != nil { - return nil, status.Newf(codes.Unavailable, tr("Error downloading tool %[1]s: %[2]s"), tool, err) + if err := downloadTool(pm, tool, downloadCB); err != nil { + return nil, err } } @@ -70,11 +67,11 @@ func downloadPlatform(pm *packagemanager.PackageManager, platformRelease *cores. // Download platform config, err := commands.GetDownloaderConfig() if err != nil { - return err + return &commands.FailedDownloadError{Message: tr("Error downloading platform %s", platformRelease), Cause: err} } resp, err := pm.DownloadPlatformRelease(platformRelease, config) if err != nil { - return err + return &commands.FailedDownloadError{Message: tr("Error downloading platform %s", platformRelease), Cause: err} } return commands.Download(resp, platformRelease.String(), downloadCB) } @@ -82,8 +79,14 @@ func downloadPlatform(pm *packagemanager.PackageManager, platformRelease *cores. func downloadTool(pm *packagemanager.PackageManager, tool *cores.ToolRelease, downloadCB commands.DownloadProgressCB) error { // Check if tool has a flavor available for the current OS if tool.GetCompatibleFlavour() == nil { - return fmt.Errorf(tr("tool %s not available for the current OS"), tool) + return &commands.FailedDownloadError{ + Message: tr("Error downloading tool %s", tool), + Cause: errors.New(tr("no versions available for the current OS", tool))} + } + + if err := commands.DownloadToolRelease(pm, tool, downloadCB); err != nil { + return &commands.FailedDownloadError{Message: tr("Error downloading tool %s", tool), Cause: err} } - return commands.DownloadToolRelease(pm, tool, downloadCB) + return nil } diff --git a/commands/core/install.go b/commands/core/install.go index f30f9bc45af..1e8c049ba5b 100644 --- a/commands/core/install.go +++ b/commands/core/install.go @@ -23,41 +23,40 @@ import ( "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // PlatformInstall FIXMEDOC func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest, - downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformInstallResponse, *status.Status) { + downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformInstallResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } version, err := commands.ParseVersion(req) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Invalid version: %s"), err) + return nil, &commands.InvalidVersionError{Cause: err} } - platform, tools, err := pm.FindPlatformReleaseDependencies(&packagemanager.PlatformReference{ + ref := &packagemanager.PlatformReference{ Package: req.PlatformPackage, PlatformArchitecture: req.Architecture, PlatformVersion: version, - }) + } + platform, tools, err := pm.FindPlatformReleaseDependencies(ref) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Error finding platform dependencies: %s"), err) + return nil, &commands.PlatformNotFound{Platform: ref.String(), Cause: err} } err = installPlatform(pm, platform, tools, downloadCB, taskCB, req.GetSkipPostInstall()) if err != nil { - return nil, status.Convert(err) + return nil, err } status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) if status != nil { - return nil, status + return nil, status.Err() } return &rpc.PlatformInstallResponse{}, nil @@ -92,16 +91,14 @@ func installPlatform(pm *packagemanager.PackageManager, return err } } - err := downloadPlatform(pm, platformRelease, downloadCB) - if err != nil { + if err := downloadPlatform(pm, platformRelease, downloadCB); err != nil { return err } taskCB(&rpc.TaskProgress{Completed: true}) // Install tools first for _, tool := range toolsToInstall { - err := commands.InstallToolRelease(pm, tool, taskCB) - if err != nil { + if err := commands.InstallToolRelease(pm, tool, taskCB); err != nil { return err } } @@ -111,11 +108,11 @@ func installPlatform(pm *packagemanager.PackageManager, if installed == nil { // No version of this platform is installed log.Info("Installing platform") - taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Installing %s"), platformRelease)}) + taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Installing platform %s"), platformRelease)}) } else { // A platform with a different version is already installed log.Info("Upgrading platform " + installed.String()) - taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Upgrading %[1]s with %[2]s"), installed, platformRelease)}) + taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Upgrading platform %[1]s with %[2]s"), installed, platformRelease)}) platformRef := &packagemanager.PlatformReference{ Package: platformRelease.Platform.Package.Name, PlatformArchitecture: platformRelease.Platform.Architecture, @@ -128,25 +125,24 @@ func installPlatform(pm *packagemanager.PackageManager, var err error _, installedTools, err = pm.FindPlatformReleaseDependencies(platformRef) if err != nil { - return fmt.Errorf(tr("can't find dependencies for platform %[1]s: %[2]w"), platformRef, err) + return &commands.NotFoundError{Message: tr("Can't find dependencies for platform %s", platformRef), Cause: err} } } // Install - err = pm.InstallPlatform(platformRelease) - if err != nil { + if err := pm.InstallPlatform(platformRelease); err != nil { log.WithError(err).Error("Cannot install platform") - return err + return &commands.FailedInstallError{Message: tr("Cannot install platform"), Cause: err} } // If upgrading remove previous release if installed != nil { - errUn := pm.UninstallPlatform(installed) + uninstallErr := pm.UninstallPlatform(installed) // In case of error try to rollback - if errUn != nil { - log.WithError(errUn).Error("Error upgrading platform.") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Error upgrading platform: %s"), errUn)}) + if uninstallErr != nil { + log.WithError(uninstallErr).Error("Error upgrading platform.") + taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Error upgrading platform: %s"), uninstallErr)}) // Rollback if err := pm.UninstallPlatform(platformRelease); err != nil { @@ -154,7 +150,7 @@ func installPlatform(pm *packagemanager.PackageManager, taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Error rolling-back changes: %s"), err)}) } - return fmt.Errorf(tr("upgrading platform: %s"), errUn) + return &commands.FailedInstallError{Message: tr("Cannot upgrade platform"), Cause: uninstallErr} } // Uninstall unused tools @@ -169,16 +165,16 @@ func installPlatform(pm *packagemanager.PackageManager, // Perform post install if !skipPostInstall { log.Info("Running post_install script") - taskCB(&rpc.TaskProgress{Message: tr("Configuring platform")}) + taskCB(&rpc.TaskProgress{Message: tr("Configuring platform.")}) if err := pm.RunPostInstallScript(platformRelease); err != nil { - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("WARNING: cannot run post install: %s"), err)}) + taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("WARNING cannot configure platform: %s"), err)}) } } else { - log.Info("Skipping platform configuration (post_install run).") - taskCB(&rpc.TaskProgress{Message: tr("Skipping platform configuration")}) + log.Info("Skipping platform configuration.") + taskCB(&rpc.TaskProgress{Message: tr("Skipping platform configuration.")}) } log.Info("Platform installed") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("%s installed"), platformRelease), Completed: true}) + taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Platform %s installed"), platformRelease), Completed: true}) return nil } diff --git a/commands/core/list.go b/commands/core/list.go index ec816bbf919..63fc813b9d7 100644 --- a/commands/core/list.go +++ b/commands/core/list.go @@ -16,28 +16,20 @@ package core import ( - "fmt" + "errors" "sort" "strings" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // GetPlatforms returns a list of installed platforms, optionally filtered by // those requiring an update. -func GetPlatforms(req *rpc.PlatformListRequest) ([]*rpc.Platform, *status.Status) { - instanceID := req.Instance.Id - i := commands.GetInstance(instanceID) - if i == nil { - return nil, status.Newf(codes.InvalidArgument, tr("Invalid instance")) - } - - packageManager := i.PackageManager +func GetPlatforms(req *rpc.PlatformListRequest) ([]*rpc.Platform, error) { + packageManager := commands.GetPackageManager(req.GetInstance().Id) if packageManager == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } res := []*rpc.Platform{} @@ -62,7 +54,7 @@ func GetPlatforms(req *rpc.PlatformListRequest) ([]*rpc.Platform, *status.Status if platformRelease != nil { latest := platform.GetLatestRelease() if latest == nil { - return nil, fmt.Errorf(tr("can't find latest release of core %s", platform)) + return nil, &commands.PlatformNotFound{Platform: platform.String(), Cause: errors.New(tr("the platform has no releases"))} } if req.UpdatableOnly { diff --git a/commands/core/search.go b/commands/core/search.go index d92eaa9c20a..97f0f566cc5 100644 --- a/commands/core/search.go +++ b/commands/core/search.go @@ -24,21 +24,15 @@ import ( "github.com/arduino/arduino-cli/arduino/utils" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) -// maximumSearchDistance is the maximum Levenshtein distance accepted when using fuzzy search. -// This value is completely arbitrary and picked randomly. -const maximumSearchDistance = 20 - // PlatformSearch FIXMEDOC -func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, *status.Status) { +func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { searchArgs := strings.TrimSpace(req.SearchArgs) allVersions := req.AllVersions pm := commands.GetPackageManager(req.Instance.Id) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } res := []*cores.PlatformRelease{} diff --git a/commands/core/uninstall.go b/commands/core/uninstall.go index b5f9a1af4ae..804ba02b755 100644 --- a/commands/core/uninstall.go +++ b/commands/core/uninstall.go @@ -23,15 +23,13 @@ import ( "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // PlatformUninstall FIXMEDOC -func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, taskCB commands.TaskProgressCB) (*rpc.PlatformUninstallResponse, *status.Status) { +func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, taskCB commands.TaskProgressCB) (*rpc.PlatformUninstallResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } ref := &packagemanager.PlatformReference{ @@ -41,25 +39,22 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, t if ref.PlatformVersion == nil { platform := pm.FindPlatform(ref) if platform == nil { - return nil, status.Newf(codes.InvalidArgument, tr("Platform not found: %s"), ref) - + return nil, &commands.PlatformNotFound{Platform: ref.String()} } platformRelease := pm.GetInstalledPlatformRelease(platform) if platformRelease == nil { - return nil, status.Newf(codes.InvalidArgument, tr("Platform not installed: %s"), ref) - + return nil, &commands.PlatformNotFound{Platform: ref.String()} } ref.PlatformVersion = platformRelease.Version } platform, tools, err := pm.FindPlatformReleaseDependencies(ref) if err != nil { - return nil, status.Newf(codes.Internal, tr("Error finding platform dependencies: %s"), err) + return nil, &commands.NotFoundError{Message: tr("Can't find dependencies for platform %s", ref), Cause: err} } - err = uninstallPlatformRelease(pm, platform, taskCB) - if err != nil { - return nil, status.New(codes.PermissionDenied, err.Error()) + if err := uninstallPlatformRelease(pm, platform, taskCB); err != nil { + return nil, err } for _, tool := range tools { @@ -68,9 +63,8 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, t } } - status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) - if status != nil { - return nil, status + if err := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil); err != nil { + return nil, err } return &rpc.PlatformUninstallResponse{}, nil @@ -84,11 +78,11 @@ func uninstallPlatformRelease(pm *packagemanager.PackageManager, platformRelease if err := pm.UninstallPlatform(platformRelease); err != nil { log.WithError(err).Error("Error uninstalling") - return err + return &commands.FailedUninstallError{Message: tr("Error uninstalling platform %s", platformRelease), Cause: err} } log.Info("Platform uninstalled") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("%s uninstalled"), platformRelease), Completed: true}) + taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Platofrm %s uninstalled"), platformRelease), Completed: true}) return nil } @@ -100,10 +94,10 @@ func uninstallToolRelease(pm *packagemanager.PackageManager, toolRelease *cores. if err := pm.UninstallTool(toolRelease); err != nil { log.WithError(err).Error("Error uninstalling") - return err + return &commands.FailedUninstallError{Message: tr("Error uninstalling tool %s", toolRelease), Cause: err} } log.Info("Tool uninstalled") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("%s uninstalled"), toolRelease), Completed: true}) + taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Tool %s uninstalled"), toolRelease), Completed: true}) return nil } diff --git a/commands/core/upgrade.go b/commands/core/upgrade.go index 30adae6eac1..3684d10287f 100644 --- a/commands/core/upgrade.go +++ b/commands/core/upgrade.go @@ -21,17 +21,15 @@ import ( "github.com/arduino/arduino-cli/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // PlatformUpgrade FIXMEDOC func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, - downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformUpgradeResponse, *status.Status) { + downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) (*rpc.PlatformUpgradeResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } // Extract all PlatformReference to platforms that have updates @@ -43,47 +41,40 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, return nil, err } - status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) - if status != nil { - return nil, status + if err := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil); err != nil { + return nil, err } return &rpc.PlatformUpgradeResponse{}, nil } func upgradePlatform(pm *packagemanager.PackageManager, platformRef *packagemanager.PlatformReference, - downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB, - skipPostInstall bool) *status.Status { + downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB, skipPostInstall bool) error { if platformRef.PlatformVersion != nil { - return status.New(codes.InvalidArgument, tr("Upgrade doesn't accept parameters with version")) + return &commands.InvalidArgumentError{Message: tr("Upgrade doesn't accept parameters with version")} } // Search the latest version for all specified platforms platform := pm.FindPlatform(platformRef) if platform == nil { - return status.Newf(codes.InvalidArgument, tr("Platform %s not found", platformRef)) + return &commands.PlatformNotFound{Platform: platformRef.String()} } installed := pm.GetInstalledPlatformRelease(platform) if installed == nil { - return status.Newf(codes.InvalidArgument, tr("Platform %s is not installed", platformRef)) + return &commands.PlatformNotFound{Platform: platformRef.String()} } latest := platform.GetLatestRelease() if !latest.Version.GreaterThan(installed.Version) { - status, e := status.New(codes.AlreadyExists, "platform already at latest version").WithDetails(&rpc.AlreadyAtLatestVersionError{}) - if e != nil { // should never happen - panic(e) - } - return status + return &commands.PlatformAlreadyAtTheLatestVersionError{} } platformRef.PlatformVersion = latest.Version platformRelease, tools, err := pm.FindPlatformReleaseDependencies(platformRef) if err != nil { - return status.Newf(codes.FailedPrecondition, tr("Platform %s is not installed", platformRef)) + return &commands.PlatformNotFound{Platform: platformRef.String()} } - err = installPlatform(pm, platformRelease, tools, downloadCB, taskCB, skipPostInstall) - if err != nil { - return status.Convert(err) + if err := installPlatform(pm, platformRelease, tools, downloadCB, taskCB, skipPostInstall); err != nil { + return err } return nil diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index 1c716465f70..d3682421740 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -251,7 +251,7 @@ func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu utils.FeedStreamTo(func(data []byte) { stream.Send(&rpc.CompileResponse{ErrStream: data}) }), false) // Set debug to false if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -264,7 +264,7 @@ func (s *ArduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -276,7 +276,7 @@ func (s *ArduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadReques func(p *rpc.DownloadProgress) { stream.Send(&rpc.PlatformDownloadResponse{Progress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -288,7 +288,7 @@ func (s *ArduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequ func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -301,7 +301,7 @@ func (s *ArduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, func(p *rpc.TaskProgress) { stream.Send(&rpc.PlatformUpgradeResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -309,14 +309,14 @@ func (s *ArduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, // PlatformSearch FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformSearch(ctx context.Context, req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { resp, err := core.PlatformSearch(req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // PlatformList FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformList(ctx context.Context, req *rpc.PlatformListRequest) (*rpc.PlatformListResponse, error) { platforms, err := core.GetPlatforms(req) if err != nil { - return nil, err.Err() + return nil, convertErrorToRPCStatus(err) } return &rpc.PlatformListResponse{InstalledPlatforms: platforms}, nil } diff --git a/commands/errors.go b/commands/errors.go index 7666147bc84..08cba00c6ca 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -63,6 +63,23 @@ func (e *InvalidFQBNError) Unwrap() error { return e.Cause } +// InvalidVersionError is returned when the version has syntax errors +type InvalidVersionError struct { + Cause error +} + +func (e *InvalidVersionError) Error() string { + return composeErrorMsg(tr("Invalid version"), e.Cause) +} + +func (e *InvalidVersionError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +func (e *InvalidVersionError) Unwrap() error { + return e.Cause +} + // MissingFQBNError is returned when the FQBN is mandatory and not specified type MissingFQBNError struct{} @@ -174,16 +191,37 @@ func (e *MissingPlatformPropertyError) ToRPCStatus() *status.Status { // PlatformNotFound is returned when a platform is not found type PlatformNotFound struct { Platform string + Cause error } func (e *PlatformNotFound) Error() string { - return tr("Platform '%s' is not installed", e.Platform) + return composeErrorMsg(tr("Platform '%s' not found", e.Platform), e.Cause) } func (e *PlatformNotFound) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } +func (e *PlatformNotFound) Unwrap() error { + return e.Cause +} + +// PlatformAlreadyAtTheLatestVersionError is returned when a platform is up to date +type PlatformAlreadyAtTheLatestVersionError struct { + Platform string +} + +func (e *PlatformAlreadyAtTheLatestVersionError) Error() string { + return tr("Platform is already at the latest version") +} + +func (e *PlatformAlreadyAtTheLatestVersionError) ToRPCStatus() *status.Status { + st, _ := status. + New(codes.AlreadyExists, e.Error()). + WithDetails(&rpc.AlreadyAtLatestVersionError{}) + return st +} + // MissingSketchPathError is returned when the sketch path is mandatory and not specified type MissingSketchPathError struct{} @@ -212,6 +250,60 @@ func (e *SketchNotFoundError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } +// FailedInstallError is returned if an install operation fails +type FailedInstallError struct { + Message string + Cause error +} + +func (e *FailedInstallError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *FailedInstallError) Unwrap() error { + return e.Cause +} + +func (e *FailedInstallError) ToRPCStatus() *status.Status { + return status.New(codes.Internal, e.Error()) +} + +// FailedUninstallError is returned if an uninstall operation fails +type FailedUninstallError struct { + Message string + Cause error +} + +func (e *FailedUninstallError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *FailedUninstallError) Unwrap() error { + return e.Cause +} + +func (e *FailedUninstallError) ToRPCStatus() *status.Status { + return status.New(codes.Internal, e.Error()) +} + +// FailedDownloadError is returned when a network download fails +type FailedDownloadError struct { + Message string + Cause error +} + +func (e *FailedDownloadError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *FailedDownloadError) Unwrap() error { + return e.Cause +} + +func (e *FailedDownloadError) ToRPCStatus() *status.Status { + return status.New(codes.Internal, e.Error()) +} + // FailedUploadError is returned when the upload fails type FailedUploadError struct { Message string From 01951114048c1f689fc8aa023bf851d1b478cc9f Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 26 Aug 2021 15:23:28 +0200 Subject: [PATCH 11/19] Refactoring 'debug' commands --- cli/debug/debug.go | 4 ++-- cli/errorcodes/errorcodes.go | 18 ------------------ commands/daemon/debug.go | 9 ++++----- commands/debug/debug.go | 13 +++++-------- commands/debug/debug_info.go | 28 +++++++++++----------------- commands/errors.go | 35 +++++++++++++++++++++++++++-------- commands/upload/upload.go | 8 ++++---- 7 files changed, 53 insertions(+), 62 deletions(-) diff --git a/cli/debug/debug.go b/cli/debug/debug.go index 3f9aef47c7d..91b68164696 100644 --- a/cli/debug/debug.go +++ b/cli/debug/debug.go @@ -100,8 +100,8 @@ func run(command *cobra.Command, args []string) { if printInfo { if res, err := debug.GetDebugConfig(context.Background(), debugConfigRequested); err != nil { - feedback.Errorf(tr("Error getting Debug info: %v"), err.Message()) - errorcodes.ExitWithGrpcStatus(err) + feedback.Errorf(tr("Error getting Debug info: %v"), err) + os.Exit(errorcodes.ErrBadArgument) } else { feedback.PrintResult(&debugInfoResult{res}) } diff --git a/cli/errorcodes/errorcodes.go b/cli/errorcodes/errorcodes.go index 529aead1efd..777967e9460 100644 --- a/cli/errorcodes/errorcodes.go +++ b/cli/errorcodes/errorcodes.go @@ -15,13 +15,6 @@ package errorcodes -import ( - "os" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - // Error codes to be used for os.Exit(). const ( _ = iota // 0 is not a valid exit error code @@ -36,14 +29,3 @@ const ( ErrCoreConfig ErrBadArgument ) - -// ExitWithGrpcStatus will terminate the current process by returing the correct -// error code closest matching the gRPC status. -func ExitWithGrpcStatus(s *status.Status) { - switch s.Code() { - case codes.Unimplemented: - os.Exit(ErrBadArgument) - default: - os.Exit(ErrGeneric) - } -} diff --git a/commands/daemon/debug.go b/commands/daemon/debug.go index 1ef38dca476..2ef82f96ac1 100644 --- a/commands/daemon/debug.go +++ b/commands/daemon/debug.go @@ -50,7 +50,7 @@ func (s *DebugService) Debug(stream dbg.DebugService_DebugServer) error { // Launch debug recipe attaching stdin and out to grpc streaming signalChan := make(chan os.Signal) defer close(signalChan) - resp, stat := cmd.Debug(stream.Context(), req, + resp, debugErr := cmd.Debug(stream.Context(), req, utils.ConsumeStreamFrom(func() ([]byte, error) { command, err := stream.Recv() if command.GetSendInterrupt() { @@ -62,14 +62,13 @@ func (s *DebugService) Debug(stream dbg.DebugService_DebugServer) error { stream.Send(&dbg.DebugResponse{Data: data}) }), signalChan) - if stat != nil { - return stat.Err() + if debugErr != nil { + return debugErr } return stream.Send(resp) } // GetDebugConfig return metadata about a debug session func (s *DebugService) GetDebugConfig(ctx context.Context, req *dbg.DebugConfigRequest) (*dbg.GetDebugConfigResponse, error) { - resp, err := cmd.GetDebugConfig(ctx, req) - return resp, err.Err() + return cmd.GetDebugConfig(ctx, req) } diff --git a/commands/debug/debug.go b/commands/debug/debug.go index dc7865d2ef0..ac5aea1e2ba 100644 --- a/commands/debug/debug.go +++ b/commands/debug/debug.go @@ -30,10 +30,7 @@ import ( "github.com/arduino/arduino-cli/i18n" dbg "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/debug/v1" "github.com/arduino/go-paths-helper" - "github.com/pkg/errors" "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var tr = i18n.Tr @@ -44,13 +41,13 @@ var tr = i18n.Tr // grpc Out <- tool stdOut // grpc Out <- tool stdErr // It also implements tool process lifecycle management -func Debug(ctx context.Context, req *dbg.DebugConfigRequest, inStream io.Reader, out io.Writer, interrupt <-chan os.Signal) (*dbg.DebugResponse, *status.Status) { +func Debug(ctx context.Context, req *dbg.DebugConfigRequest, inStream io.Reader, out io.Writer, interrupt <-chan os.Signal) (*dbg.DebugResponse, error) { // Get debugging command line to run debugger pm := commands.GetPackageManager(req.GetInstance().GetId()) commandLine, err := getCommandLine(req, pm) if err != nil { - return nil, status.New(codes.FailedPrecondition, tr("Cannot get command line for tool: %s", err)) + return nil, err } for i, arg := range commandLine { @@ -66,7 +63,7 @@ func Debug(ctx context.Context, req *dbg.DebugConfigRequest, inStream io.Reader, cmd, err := executils.NewProcess(commandLine...) if err != nil { - return nil, status.New(codes.FailedPrecondition, tr("Cannot execute debug tool: %s", err)) + return nil, &commands.FailedDebugError{Message: tr("Cannot execute debug tool"), Cause: err} } // Get stdIn pipe from tool @@ -133,7 +130,7 @@ func getCommandLine(req *dbg.DebugConfigRequest, pm *packagemanager.PackageManag } gdbPath = paths.New(debugInfo.ToolchainPath).Join(gdbexecutable) default: - return nil, errors.Errorf(tr("unsupported toolchain '%s'"), debugInfo.GetToolchain()) + return nil, &commands.FailedDebugError{Message: tr("Toolchain '%s' is not supported", debugInfo.GetToolchain())} } add(gdbPath.String()) @@ -172,7 +169,7 @@ func getCommandLine(req *dbg.DebugConfigRequest, pm *packagemanager.PackageManag add(serverCmd) default: - return nil, errors.Errorf(tr("unsupported gdb server '%s'"), debugInfo.GetServer()) + return nil, &commands.FailedDebugError{Message: tr("GDB server '%s' is not supported", debugInfo.GetServer())} } // Add executable diff --git a/commands/debug/debug_info.go b/commands/debug/debug_info.go index 014a0b41155..0e5c22625d5 100644 --- a/commands/debug/debug_info.go +++ b/commands/debug/debug_info.go @@ -17,7 +17,6 @@ package debug import ( "context" - "fmt" "strings" "github.com/arduino/arduino-cli/arduino/cores" @@ -27,30 +26,25 @@ import ( "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/debug/v1" "github.com/arduino/go-paths-helper" "github.com/arduino/go-properties-orderedmap" - "github.com/pkg/errors" "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // GetDebugConfig returns metadata to start debugging with the specified board -func GetDebugConfig(ctx context.Context, req *debug.DebugConfigRequest) (*debug.GetDebugConfigResponse, *status.Status) { +func GetDebugConfig(ctx context.Context, req *debug.DebugConfigRequest) (*debug.GetDebugConfigResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) - - resp, err := getDebugProperties(req, pm) - return resp, status.Convert(err) + return getDebugProperties(req, pm) } func getDebugProperties(req *debug.DebugConfigRequest, pm *packagemanager.PackageManager) (*debug.GetDebugConfigResponse, error) { // TODO: make a generic function to extract sketch from request // and remove duplication in commands/compile.go if req.GetSketchPath() == "" { - return nil, fmt.Errorf(tr("missing sketchPath")) + return nil, &commands.MissingSketchPathError{} } sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil { - return nil, errors.Wrap(err, tr("opening sketch")) + return nil, &commands.SketchNotFoundError{Cause: err} } // XXX Remove this code duplication!! @@ -59,17 +53,17 @@ func getDebugProperties(req *debug.DebugConfigRequest, pm *packagemanager.Packag fqbnIn = sk.Metadata.CPU.Fqbn } if fqbnIn == "" { - return nil, fmt.Errorf(tr("no Fully Qualified Board Name provided")) + return nil, &commands.MissingFQBNError{} } fqbn, err := cores.ParseFQBN(fqbnIn) if err != nil { - return nil, errors.Wrap(err, tr("error parsing FQBN")) + return nil, &commands.InvalidFQBNError{Cause: err} } // Find target board and board properties _, platformRelease, board, boardProperties, referencedPlatformRelease, err := pm.ResolveFQBN(fqbn) if err != nil { - return nil, errors.Wrap(err, tr("error resolving FQBN")) + return nil, &commands.UnknownFQBNError{Cause: err} } // Build configuration for debug @@ -112,7 +106,7 @@ func getDebugProperties(req *debug.DebugConfigRequest, pm *packagemanager.Packag } else if refP, ok := referencedPlatformRelease.Programmers[req.GetProgrammer()]; ok { toolProperties.Merge(refP.Properties) } else { - return nil, fmt.Errorf(tr("programmer '%s' not found"), req.GetProgrammer()) + return nil, &commands.ProgrammerNotFoundError{Programmer: req.GetProgrammer()} } } @@ -121,10 +115,10 @@ func getDebugProperties(req *debug.DebugConfigRequest, pm *packagemanager.Packag importPath = paths.New(importDir) } if !importPath.Exist() { - return nil, fmt.Errorf(tr("compiled sketch not found in %s"), importPath) + return nil, &commands.NotFoundError{Message: tr("Compiled sketch not found in %s", importPath)} } if !importPath.IsDir() { - return nil, fmt.Errorf(tr("expected compiled sketch in directory %s, but is a file instead"), importPath) + return nil, &commands.NotFoundError{Message: tr("Expected compiled sketch in directory %s, but is a file instead", importPath)} } toolProperties.SetPath("build.path", importPath) toolProperties.Set("build.project_name", sk.Name+".ino") @@ -144,7 +138,7 @@ func getDebugProperties(req *debug.DebugConfigRequest, pm *packagemanager.Packag } if !debugProperties.ContainsKey("executable") { - return nil, status.Error(codes.Unimplemented, fmt.Sprintf(tr("debugging not supported for board %s"), req.GetFqbn())) + return nil, &commands.FailedDebugError{Message: tr("Debugging not supported for board %s", req.GetFqbn())} } server := debugProperties.Get("server") diff --git a/commands/errors.go b/commands/errors.go index 08cba00c6ca..ca4bf57b3cc 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -144,20 +144,21 @@ func (e *ProgreammerRequiredForUploadError) ToRPCStatus() *status.Status { return st } -// UnknownProgrammerError is returned when the programmer is not found -type UnknownProgrammerError struct { - Cause error +// ProgrammerNotFoundError is returned when the programmer is not found +type ProgrammerNotFoundError struct { + Programmer string + Cause error } -func (e *UnknownProgrammerError) Error() string { - return composeErrorMsg(tr("Unknown programmer"), e.Cause) +func (e *ProgrammerNotFoundError) Error() string { + return composeErrorMsg(tr("Programmer '%s' not found", e.Programmer), e.Cause) } -func (e *UnknownProgrammerError) Unwrap() error { +func (e *ProgrammerNotFoundError) Unwrap() error { return e.Cause } -func (e *UnknownProgrammerError) ToRPCStatus() *status.Status { +func (e *ProgrammerNotFoundError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -212,7 +213,7 @@ type PlatformAlreadyAtTheLatestVersionError struct { } func (e *PlatformAlreadyAtTheLatestVersionError) Error() string { - return tr("Platform is already at the latest version") + return tr("Platform '%s' is already at the latest version", e.Platform) } func (e *PlatformAlreadyAtTheLatestVersionError) ToRPCStatus() *status.Status { @@ -322,6 +323,24 @@ func (e *FailedUploadError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } +// FailedDebugError is returned when the debug fails +type FailedDebugError struct { + Message string + Cause error +} + +func (e *FailedDebugError) Error() string { + return composeErrorMsg(e.Message, e.Cause) +} + +func (e *FailedDebugError) Unwrap() error { + return e.Cause +} + +func (e *FailedDebugError) ToRPCStatus() *status.Status { + return status.New(codes.Internal, e.Error()) +} + // CompileFailedError is returned when the compile fails type CompileFailedError struct { Message string diff --git a/commands/upload/upload.go b/commands/upload/upload.go index 9c28de7bf46..efed27a5c0a 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -218,7 +218,7 @@ func runProgramAction(pm *packagemanager.PackageManager, programmer = buildPlatform.Programmers[programmerID] } if programmer == nil { - return &commands.UnknownProgrammerError{Cause: fmt.Errorf(tr("programmer '%s' not available"), programmerID)} + return &commands.ProgrammerNotFoundError{Programmer: programmerID} } } @@ -352,13 +352,13 @@ func runProgramAction(pm *packagemanager.PackageManager, if !burnBootloader { importPath, sketchName, err := determineBuildPathAndSketchName(importFile, importDir, sk, fqbn) if err != nil { - return &commands.FailedUploadError{Message: tr("Error finding build artifacts"), Cause: err} + return &commands.NotFoundError{Message: tr("Error finding build artifacts"), Cause: err} } if !importPath.Exist() { - return &commands.FailedUploadError{Message: tr("Compiled sketch not found in %s", importPath)} + return &commands.NotFoundError{Message: tr("Compiled sketch not found in %s", importPath)} } if !importPath.IsDir() { - return &commands.FailedUploadError{Message: tr("Expected compiled sketch in directory %s, but is a file instead", importPath)} + return &commands.NotFoundError{Message: tr("Expected compiled sketch in directory %s, but is a file instead", importPath)} } uploadProperties.SetPath("build.path", importPath) uploadProperties.Set("build.project_name", sketchName) From 10259814a83d11a29e0eb23043405c46b74477ea Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 26 Aug 2021 16:01:22 +0200 Subject: [PATCH 12/19] Refactoring 'lib' commands --- cli/lib/args.go | 2 +- cli/lib/search.go | 9 ++--- commands/daemon/daemon.go | 21 ++++++----- commands/errors.go | 70 ++++++++++++++++++++++++++++++++++++ commands/lib/download.go | 17 ++++----- commands/lib/install.go | 40 +++++++++++---------- commands/lib/list.go | 14 ++++---- commands/lib/resolve_deps.go | 15 ++++---- commands/lib/search.go | 14 +++----- commands/lib/search_test.go | 12 ++----- commands/lib/uninstall.go | 6 ++-- commands/lib/upgrade.go | 29 +++++++-------- commands/lib/utils.go | 6 ++-- 13 files changed, 157 insertions(+), 98 deletions(-) diff --git a/cli/lib/args.go b/cli/lib/args.go index 08f98068a4c..d7c2e639fc7 100644 --- a/cli/lib/args.go +++ b/cli/lib/args.go @@ -81,7 +81,7 @@ func ParseLibraryReferenceArgAndAdjustCase(instance *rpc.Instance, arg string) ( Query: libRef.Name, }) if err != nil { - return nil, err.Err() + return nil, err } candidates := []*rpc.SearchedLibrary{} diff --git a/cli/lib/search.go b/cli/lib/search.go index de6251d7cf9..f11ac855741 100644 --- a/cli/lib/search.go +++ b/cli/lib/search.go @@ -58,10 +58,11 @@ func runSearchCommand(cmd *cobra.Command, args []string) { os.Exit(errorcodes.ErrGeneric) } - err := commands.UpdateLibrariesIndex(context.Background(), &rpc.UpdateLibrariesIndexRequest{ - Instance: inst, - }, output.ProgressBar()) - if err != nil { + if err := commands.UpdateLibrariesIndex( + context.Background(), + &rpc.UpdateLibrariesIndexRequest{Instance: inst}, + output.ProgressBar(), + ); err != nil { feedback.Errorf(tr("Error updating library index: %v"), err) os.Exit(errorcodes.ErrGeneric) } diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index d3682421740..18056ed4929 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -42,6 +42,9 @@ type ArduinoCoreServerImpl struct { var tr = i18n.Tr func convertErrorToRPCStatus(err error) error { + if err == nil { + return nil + } if cmdErr, ok := err.(commands.CommandError); ok { return cmdErr.ToRPCStatus().Err() } @@ -373,7 +376,7 @@ func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, func(p *rpc.DownloadProgress) { stream.Send(&rpc.LibraryDownloadResponse{Progress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -386,7 +389,7 @@ func (s *ArduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(&rpc.LibraryInstallResponse{}) } @@ -397,7 +400,7 @@ func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallReques func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(&rpc.LibraryUninstallResponse{}) } @@ -409,7 +412,7 @@ func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequ func(p *rpc.TaskProgress) { stream.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(&rpc.LibraryUpgradeAllResponse{}) } @@ -417,19 +420,19 @@ func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequ // LibraryResolveDependencies FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { resp, err := lib.LibraryResolveDependencies(ctx, req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // LibrarySearch FIXMEDOC func (s *ArduinoCoreServerImpl) LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { resp, err := lib.LibrarySearch(ctx, req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // LibraryList FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { resp, err := lib.LibraryList(ctx, req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // ArchiveSketch FIXMEDOC @@ -445,7 +448,7 @@ func (s *ArduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequ func(p *rpc.TaskProgress) { stream.Send(&rpc.ZipLibraryInstallResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(&rpc.ZipLibraryInstallResponse{}) } @@ -457,7 +460,7 @@ func (s *ArduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequ func(p *rpc.TaskProgress) { stream.Send(&rpc.GitLibraryInstallResponse{TaskProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(&rpc.GitLibraryInstallResponse{}) } diff --git a/commands/errors.go b/commands/errors.go index ca4bf57b3cc..49ef394c0b8 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -63,6 +63,23 @@ func (e *InvalidFQBNError) Unwrap() error { return e.Cause } +// InvalidLibraryError is returned when the library has syntax errors +type InvalidLibraryError struct { + Cause error +} + +func (e *InvalidLibraryError) Error() string { + return composeErrorMsg(tr("Invalid library"), e.Cause) +} + +func (e *InvalidLibraryError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +func (e *InvalidLibraryError) Unwrap() error { + return e.Cause +} + // InvalidVersionError is returned when the version has syntax errors type InvalidVersionError struct { Cause error @@ -207,6 +224,42 @@ func (e *PlatformNotFound) Unwrap() error { return e.Cause } +// LibraryNotFound is returned when a platform is not found +type LibraryNotFound struct { + Library string + Cause error +} + +func (e *LibraryNotFound) Error() string { + return composeErrorMsg(tr("Library '%s' not found", e.Library), e.Cause) +} + +func (e *LibraryNotFound) ToRPCStatus() *status.Status { + return status.New(codes.FailedPrecondition, e.Error()) +} + +func (e *LibraryNotFound) Unwrap() error { + return e.Cause +} + +// LibraryDependenciesResolutionFailedError is returned when an inconsistency is found in library dependencies +// or a solution cannot be found. +type LibraryDependenciesResolutionFailedError struct { + Cause error +} + +func (e *LibraryDependenciesResolutionFailedError) Error() string { + return composeErrorMsg(tr("No valid dependencies solution found"), e.Cause) +} + +func (e *LibraryDependenciesResolutionFailedError) ToRPCStatus() *status.Status { + return status.New(codes.FailedPrecondition, e.Error()) +} + +func (e *LibraryDependenciesResolutionFailedError) Unwrap() error { + return e.Cause +} + // PlatformAlreadyAtTheLatestVersionError is returned when a platform is up to date type PlatformAlreadyAtTheLatestVersionError struct { Platform string @@ -269,6 +322,23 @@ func (e *FailedInstallError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } +// FailedLibraryInstallError is returned if a library install operation fails +type FailedLibraryInstallError struct { + Cause error +} + +func (e *FailedLibraryInstallError) Error() string { + return composeErrorMsg(tr("Library install failed"), e.Cause) +} + +func (e *FailedLibraryInstallError) Unwrap() error { + return e.Cause +} + +func (e *FailedLibraryInstallError) ToRPCStatus() *status.Status { + return status.New(codes.Internal, e.Error()) +} + // FailedUninstallError is returned if an uninstall operation fails type FailedUninstallError struct { Message string diff --git a/commands/lib/download.go b/commands/lib/download.go index fcbf73b82dc..fc1cf5acad2 100644 --- a/commands/lib/download.go +++ b/commands/lib/download.go @@ -25,27 +25,28 @@ import ( "github.com/arduino/arduino-cli/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var tr = i18n.Tr // LibraryDownload FIXMEDOC -func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downloadCB commands.DownloadProgressCB) (*rpc.LibraryDownloadResponse, *status.Status) { +func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downloadCB commands.DownloadProgressCB) (*rpc.LibraryDownloadResponse, error) { logrus.Info("Executing `arduino lib download`") lm := commands.GetLibraryManager(req.GetInstance().GetId()) + if lm == nil { + return nil, &commands.InvalidInstanceError{} + } logrus.Info("Preparing download") lib, err := findLibraryIndexRelease(lm, req) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Error looking for library: %s"), err) + return nil, err } if err := downloadLibrary(lm, lib, downloadCB, func(*rpc.TaskProgress) {}); err != nil { - return nil, status.Convert(err) + return nil, err } return &rpc.LibraryDownloadResponse{}, nil @@ -57,12 +58,12 @@ func downloadLibrary(lm *librariesmanager.LibrariesManager, libRelease *librarie taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Downloading %s"), libRelease)}) config, err := commands.GetDownloaderConfig() if err != nil { - return err + return &commands.FailedDownloadError{Message: tr("Can't download library"), Cause: err} } if d, err := libRelease.Resource.Download(lm.DownloadsDir, config); err != nil { - return err + return &commands.FailedDownloadError{Message: tr("Can't download library"), Cause: err} } else if err := commands.Download(d, libRelease.String(), downloadCB); err != nil { - return err + return &commands.FailedDownloadError{Message: tr("Can't download library"), Cause: err} } taskCB(&rpc.TaskProgress{Completed: true}) diff --git a/commands/lib/install.go b/commands/lib/install.go index 997c08e908b..bf01716c7a0 100644 --- a/commands/lib/install.go +++ b/commands/lib/install.go @@ -17,22 +17,23 @@ package lib import ( "context" - "fmt" + "errors" "github.com/arduino/arduino-cli/arduino/libraries/librariesindex" "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // LibraryInstall FIXMEDOC func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, - downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) *status.Status { + downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) error { lm := commands.GetLibraryManager(req.GetInstance().GetId()) + if lm == nil { + return &commands.InvalidInstanceError{} + } toInstall := map[string]*rpc.LibraryDependencyStatus{} if req.NoDeps { @@ -47,14 +48,16 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, Version: req.Version, }) if err != nil { - return status.Newf(err.Code(), tr("Error resolving dependencies for %[1]s@%[2]s: %[3]s", req.Name, req.Version, err.Message())) + return err } for _, dep := range res.Dependencies { if existingDep, has := toInstall[dep.Name]; has { if existingDep.VersionRequired != dep.VersionRequired { - return status.Newf(codes.FailedPrecondition, tr("Two different versions of the library %[1]s are required: %[2]s and %[3]s"), - dep.Name, dep.VersionRequired, existingDep.VersionRequired) + err := errors.New( + tr("two different versions of the library %[1]s are required: %[2]s and %[3]s", + dep.Name, dep.VersionRequired, existingDep.VersionRequired)) + return &commands.LibraryDependenciesResolutionFailedError{Cause: err} } } toInstall[dep.Name] = dep @@ -67,21 +70,20 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, Version: lib.VersionRequired, }) if err != nil { - return status.Newf(codes.InvalidArgument, tr("Error looking for library: %s", err)) + return err } if err := downloadLibrary(lm, libRelease, downloadCB, taskCB); err != nil { - return status.Newf(codes.Unknown, tr("Error downloading library: %s", err)) + return err } if err := installLibrary(lm, libRelease, taskCB); err != nil { - return status.New(codes.PermissionDenied, err.Error()) + return err } } - stat := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) - if stat != nil { - return status.Newf(stat.Code(), tr("Error rescanning libraries: %s", stat.Err())) + if err := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil); err != nil { + return err } return nil } @@ -96,7 +98,7 @@ func installLibrary(lm *librariesmanager.LibrariesManager, libRelease *libraries } if err != nil { - return fmt.Errorf(tr("checking lib install prerequisites: %s"), err) + return &commands.FailedInstallError{Message: tr("Checking lib install prerequisites"), Cause: err} } if libReplaced != nil { @@ -104,7 +106,7 @@ func installLibrary(lm *librariesmanager.LibrariesManager, libRelease *libraries } if err := lm.Install(libRelease, libPath); err != nil { - return err + return &commands.FailedLibraryInstallError{Cause: err} } taskCB(&rpc.TaskProgress{Message: tr("Installed %s", libRelease), Completed: true}) @@ -112,20 +114,20 @@ func installLibrary(lm *librariesmanager.LibrariesManager, libRelease *libraries } //ZipLibraryInstall FIXMEDOC -func ZipLibraryInstall(ctx context.Context, req *rpc.ZipLibraryInstallRequest, taskCB commands.TaskProgressCB) *status.Status { +func ZipLibraryInstall(ctx context.Context, req *rpc.ZipLibraryInstallRequest, taskCB commands.TaskProgressCB) error { lm := commands.GetLibraryManager(req.GetInstance().GetId()) if err := lm.InstallZipLib(ctx, req.Path, req.Overwrite); err != nil { - return status.New(codes.InvalidArgument, err.Error()) + return &commands.FailedLibraryInstallError{Cause: err} } taskCB(&rpc.TaskProgress{Message: tr("Library installed"), Completed: true}) return nil } //GitLibraryInstall FIXMEDOC -func GitLibraryInstall(ctx context.Context, req *rpc.GitLibraryInstallRequest, taskCB commands.TaskProgressCB) *status.Status { +func GitLibraryInstall(ctx context.Context, req *rpc.GitLibraryInstallRequest, taskCB commands.TaskProgressCB) error { lm := commands.GetLibraryManager(req.GetInstance().GetId()) if err := lm.InstallGitLib(req.Url, req.Overwrite); err != nil { - return status.New(codes.InvalidArgument, err.Error()) + return &commands.FailedLibraryInstallError{Cause: err} } taskCB(&rpc.TaskProgress{Message: tr("Library installed"), Completed: true}) return nil diff --git a/commands/lib/list.go b/commands/lib/list.go index b32cb831c6f..2d1368e8456 100644 --- a/commands/lib/list.go +++ b/commands/lib/list.go @@ -25,8 +25,6 @@ import ( "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) type installedLib struct { @@ -35,15 +33,15 @@ type installedLib struct { } // LibraryList FIXMEDOC -func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, *status.Status) { +func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) if pm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } lm := commands.GetLibraryManager(req.GetInstance().GetId()) if lm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } nameFilter := strings.ToLower(req.GetName()) @@ -53,11 +51,11 @@ func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.Library if f := req.GetFqbn(); f != "" { fqbn, err := cores.ParseFQBN(req.GetFqbn()) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Error parsing FQBN: %s", err)) + return nil, &commands.InvalidFQBNError{Cause: err} } _, boardPlatform, _, _, refBoardPlatform, err := pm.ResolveFQBN(fqbn) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Error loading board data: %s", err)) + return nil, &commands.UnknownFQBNError{Cause: err} } filteredRes := map[string]*installedLib{} @@ -105,7 +103,7 @@ func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.Library } rpcLib, err := lib.Library.ToRPCLibrary() if err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Error converting library %[1]s to rpc struct: %[2]s", lib.Library.Name, err)) + return nil, &commands.PermissionDeniedError{Message: tr("Error getting information for library %s", lib.Library.Name), Cause: err} } instaledLibs = append(instaledLibs, &rpc.InstalledLibrary{ Library: rpcLib, diff --git a/commands/lib/resolve_deps.go b/commands/lib/resolve_deps.go index 095e741bded..4c1957a7a5e 100644 --- a/commands/lib/resolve_deps.go +++ b/commands/lib/resolve_deps.go @@ -17,22 +17,24 @@ package lib import ( "context" + "errors" "github.com/arduino/arduino-cli/arduino/libraries" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // LibraryResolveDependencies FIXMEDOC -func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, *status.Status) { +func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { lm := commands.GetLibraryManager(req.GetInstance().GetId()) + if lm == nil { + return nil, &commands.InvalidInstanceError{} + } // Search the requested lib reqLibRelease, err := findLibraryIndexRelease(lm, req) if err != nil { - return nil, status.Newf(codes.InvalidArgument, tr("Error looking for library: %s", err)) + return nil, err } // Extract all installed libraries @@ -49,12 +51,13 @@ func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDepe // Check if there is a problem with the first level deps for _, directDep := range reqLibRelease.GetDependencies() { if _, ok := lm.Index.Libraries[directDep.GetName()]; !ok { - return nil, status.Newf(codes.FailedPrecondition, tr("Dependency '%s' is not available", directDep.GetName())) + err := errors.New(tr("dependency '%s' is not available", directDep.GetName())) + return nil, &commands.LibraryDependenciesResolutionFailedError{Cause: err} } } // Otherwise there is no possible solution, the depends field has an invalid formula - return nil, status.New(codes.FailedPrecondition, tr("No valid dependencies solution found")) + return nil, &commands.LibraryDependenciesResolutionFailedError{} } res := []*rpc.LibraryDependencyStatus{} diff --git a/commands/lib/search.go b/commands/lib/search.go index 8a2f270c7dc..9e05bf0e95f 100644 --- a/commands/lib/search.go +++ b/commands/lib/search.go @@ -24,22 +24,18 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" semver "go.bug.st/relaxed-semver" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // LibrarySearch FIXMEDOC -func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, *status.Status) { +func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { lm := commands.GetLibraryManager(req.GetInstance().GetId()) if lm == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &commands.InvalidInstanceError{} } - - resp, err := searchLibrary(req, lm) - return resp, status.Convert(err) + return searchLibrary(req, lm), nil } -func searchLibrary(req *rpc.LibrarySearchRequest, lm *librariesmanager.LibrariesManager) (*rpc.LibrarySearchResponse, error) { +func searchLibrary(req *rpc.LibrarySearchRequest, lm *librariesmanager.LibrariesManager) *rpc.LibrarySearchResponse { res := []*rpc.SearchedLibrary{} status := rpc.LibrarySearchStatus_LIBRARY_SEARCH_STATUS_SUCCESS @@ -51,7 +47,7 @@ func searchLibrary(req *rpc.LibrarySearchRequest, lm *librariesmanager.Libraries res = append(res, indexLibraryToRPCSearchLibrary(lib)) } - return &rpc.LibrarySearchResponse{Libraries: res, Status: status}, nil + return &rpc.LibrarySearchResponse{Libraries: res, Status: status} } // indexLibraryToRPCSearchLibrary converts a librariindex.Library to rpc.SearchLibrary diff --git a/commands/lib/search_test.go b/commands/lib/search_test.go index 301b6f355a3..e9a48ddcac3 100644 --- a/commands/lib/search_test.go +++ b/commands/lib/search_test.go @@ -21,11 +21,7 @@ func TestSearchLibrary(t *testing.T) { Query: "test", } - resp, err := searchLibrary(req, lm) - if err != nil { - t.Fatal(err) - } - + resp := searchLibrary(req, lm) assert := assert.New(t) assert.Equal(resp.GetStatus(), rpc.LibrarySearchStatus_LIBRARY_SEARCH_STATUS_SUCCESS) assert.Equal(len(resp.GetLibraries()), 2) @@ -42,11 +38,7 @@ func TestSearchLibrarySimilar(t *testing.T) { Query: "arduino", } - resp, err := searchLibrary(req, lm) - if err != nil { - t.Fatal(err) - } - + resp := searchLibrary(req, lm) assert := assert.New(t) assert.Equal(resp.GetStatus(), rpc.LibrarySearchStatus_LIBRARY_SEARCH_STATUS_SUCCESS) assert.Equal(len(resp.GetLibraries()), 2) diff --git a/commands/lib/uninstall.go b/commands/lib/uninstall.go index 47f27fb879c..b8628e45a89 100644 --- a/commands/lib/uninstall.go +++ b/commands/lib/uninstall.go @@ -21,16 +21,14 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // LibraryUninstall FIXMEDOC -func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallRequest, taskCB commands.TaskProgressCB) *status.Status { +func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallRequest, taskCB commands.TaskProgressCB) error { lm := commands.GetLibraryManager(req.GetInstance().GetId()) ref, err := createLibIndexReference(lm, req) if err != nil { - return status.New(codes.InvalidArgument, err.Error()) + return &commands.InvalidLibraryError{Cause: err} } lib := lm.FindByReference(ref) diff --git a/commands/lib/upgrade.go b/commands/lib/upgrade.go index c0f2ee32384..b181d38253b 100644 --- a/commands/lib/upgrade.go +++ b/commands/lib/upgrade.go @@ -19,45 +19,42 @@ import ( "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "google.golang.org/grpc/status" ) // LibraryUpgradeAll upgrades all the available libraries -func LibraryUpgradeAll(instanceID int32, downloadCB commands.DownloadProgressCB, - taskCB commands.TaskProgressCB) *status.Status { - // get the library manager +func LibraryUpgradeAll(instanceID int32, downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) error { lm := commands.GetLibraryManager(instanceID) + if lm == nil { + return &commands.InvalidInstanceError{} + } if err := upgrade(lm, listLibraries(lm, true, true), downloadCB, taskCB); err != nil { - return status.Convert(err) + return err } - stat := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: instanceID}}, nil) - if stat != nil { - return status.Newf(stat.Code(), tr("Error rescanning libraries: %s", stat.Err())) + if err := commands.Init(&rpc.InitRequest{Instance: &rpc.Instance{Id: instanceID}}, nil); err != nil { + return err } return nil } // LibraryUpgrade upgrades only the given libraries -func LibraryUpgrade(instanceID int32, libraryNames []string, downloadCB commands.DownloadProgressCB, - taskCB commands.TaskProgressCB) *status.Status { - // get the library manager +func LibraryUpgrade(instanceID int32, libraryNames []string, downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) error { lm := commands.GetLibraryManager(instanceID) + if lm == nil { + return &commands.InvalidInstanceError{} + } // get the libs to upgrade libs := filterByName(listLibraries(lm, true, true), libraryNames) // do it - return status.Convert(upgrade(lm, libs, downloadCB, taskCB)) + return upgrade(lm, libs, downloadCB, taskCB) } -func upgrade(lm *librariesmanager.LibrariesManager, libs []*installedLib, downloadCB commands.DownloadProgressCB, - taskCB commands.TaskProgressCB) error { - +func upgrade(lm *librariesmanager.LibrariesManager, libs []*installedLib, downloadCB commands.DownloadProgressCB, taskCB commands.TaskProgressCB) error { // Go through the list and download them - for _, lib := range libs { if err := downloadLibrary(lm, lib.Available, downloadCB, taskCB); err != nil { return err diff --git a/commands/lib/utils.go b/commands/lib/utils.go index 0ed26a4031e..4f6df05623c 100644 --- a/commands/lib/utils.go +++ b/commands/lib/utils.go @@ -16,8 +16,6 @@ package lib import ( - "fmt" - "github.com/arduino/arduino-cli/arduino/libraries/librariesindex" "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/commands" @@ -31,7 +29,7 @@ type libraryReferencer interface { func createLibIndexReference(lm *librariesmanager.LibrariesManager, req libraryReferencer) (*librariesindex.Reference, error) { version, err := commands.ParseVersion(req) if err != nil { - return nil, fmt.Errorf(tr("invalid version: %s"), err) + return nil, &commands.InvalidVersionError{Cause: err} } return &librariesindex.Reference{Name: req.GetName(), Version: version}, nil @@ -44,7 +42,7 @@ func findLibraryIndexRelease(lm *librariesmanager.LibrariesManager, req libraryR } lib := lm.Index.FindRelease(ref) if lib == nil { - return nil, fmt.Errorf(tr("library %s not found"), ref) + return nil, &commands.LibraryNotFound{Library: ref.String()} } return lib, nil } From 1e770ca11fea8df6d1c9dbe73c649d9660d1b3c1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 26 Aug 2021 16:21:16 +0200 Subject: [PATCH 13/19] Refactoring 'sketch' commands --- commands/daemon/daemon.go | 2 +- commands/sketch/archive.go | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index 18056ed4929..e2907f83ead 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -438,7 +438,7 @@ func (s *ArduinoCoreServerImpl) LibraryList(ctx context.Context, req *rpc.Librar // ArchiveSketch FIXMEDOC func (s *ArduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { resp, err := sketch.ArchiveSketch(ctx, req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } //ZipLibraryInstall FIXMEDOC diff --git a/commands/sketch/archive.go b/commands/sketch/archive.go index 3561497169c..f14a33f65fd 100644 --- a/commands/sketch/archive.go +++ b/commands/sketch/archive.go @@ -23,17 +23,16 @@ import ( "strings" "github.com/arduino/arduino-cli/arduino/sketch" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) var tr = i18n.Tr // ArchiveSketch FIXMEDOC -func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, *status.Status) { +func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { // sketchName is the name of the sketch without extension, for example "MySketch" var sketchName string @@ -44,7 +43,7 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc s, err := sketch.New(sketchPath) if err != nil { - return nil, status.Convert(err) + return nil, &commands.SketchNotFoundError{Cause: err} } sketchPath = s.FullPath @@ -57,7 +56,7 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc archivePath, err = archivePath.Clean().Abs() if err != nil { - return nil, status.Newf(codes.Unknown, tr("Error getting absolute archive path %v"), err) + return nil, &commands.PermissionDeniedError{Message: tr("Error getting absolute path of sketch archive"), Cause: err} } // Makes archivePath point to a zip file @@ -68,18 +67,18 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc } if archivePath.Exist() { - return nil, status.New(codes.InvalidArgument, tr("Archive already exists")) + return nil, &commands.InvalidArgumentError{Message: tr("Archive already exists")} } filesToZip, err := sketchPath.ReadDirRecursive() if err != nil { - return nil, status.Newf(codes.Unknown, tr("Error retrieving sketch files: %v"), err) + return nil, &commands.PermissionDeniedError{Message: tr("Error reading sketch files"), Cause: err} } filesToZip.FilterOutDirs() archive, err := archivePath.Create() if err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Error creating archive: %v"), err) + return nil, &commands.PermissionDeniedError{Message: tr("Error creating sketch archive"), Cause: err} } defer archive.Close() @@ -91,7 +90,7 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc if !req.IncludeBuildDir { filePath, err := sketchPath.Parent().RelTo(f) if err != nil { - return nil, status.Newf(codes.Unknown, tr("Error calculating relative file path: %v"), err) + return nil, &commands.PermissionDeniedError{Message: tr("Error calculating relative file path"), Cause: err} } // Skips build folder @@ -102,9 +101,8 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc // We get the parent path since we want the archive to unpack as a folder. // If we don't do this the archive would contain all the sketch files as top level. - err = addFileToSketchArchive(zipWriter, f, sketchPath.Parent()) - if err != nil { - return nil, status.Newf(codes.Unknown, tr("Error adding file to archive: %v"), err) + if err := addFileToSketchArchive(zipWriter, f, sketchPath.Parent()); err != nil { + return nil, &commands.PermissionDeniedError{Message: tr("Error adding file to sketch archive"), Cause: err} } } From 677fd55310e9538e5aedb4f659f622f0acff029e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 27 Aug 2021 09:23:54 +0200 Subject: [PATCH 14/19] Refactoring 'commands' commands --- cli/instance/instance.go | 16 ++-- commands/core/install.go | 5 +- commands/daemon/daemon.go | 26 +++---- commands/download.go | 12 +-- commands/errors.go | 69 ++++++++++++++++ commands/instances.go | 160 +++++++++++++++++++------------------- 6 files changed, 172 insertions(+), 116 deletions(-) diff --git a/cli/instance/instance.go b/cli/instance/instance.go index b0a9532014f..7d5bde944d7 100644 --- a/cli/instance/instance.go +++ b/cli/instance/instance.go @@ -17,6 +17,7 @@ package instance import ( "context" + "errors" "os" "github.com/arduino/arduino-cli/cli/errorcodes" @@ -27,7 +28,6 @@ import ( "github.com/arduino/arduino-cli/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" - "google.golang.org/grpc/status" ) var tr = i18n.Tr @@ -49,7 +49,7 @@ func CreateAndInit() *rpc.Instance { } // Create and return a new Instance. -func Create() (*rpc.Instance, *status.Status) { +func Create() (*rpc.Instance, error) { res, err := commands.Create(&rpc.CreateRequest{}) if err != nil { return nil, err @@ -58,12 +58,12 @@ func Create() (*rpc.Instance, *status.Status) { } // Init initializes instance by loading installed libraries and platforms. -// In case of loading failures return a list gRPC Status errors for each +// In case of loading failures return a list of errors for each // platform or library that we failed to load. // Package and library indexes files are automatically updated if the // CLI is run for the first time. -func Init(instance *rpc.Instance) []*status.Status { - errs := []*status.Status{} +func Init(instance *rpc.Instance) []error { + errs := []error{} // In case the CLI is executed for the first time if err := FirstUpdate(instance); err != nil { @@ -76,8 +76,8 @@ func Init(instance *rpc.Instance) []*status.Status { err := commands.Init(&rpc.InitRequest{ Instance: instance, }, func(res *rpc.InitResponse) { - if err := res.GetError(); err != nil { - errs = append(errs, status.FromProto(err)) + if st := res.GetError(); st != nil { + errs = append(errs, errors.New(st.Message)) } if progress := res.GetInitProgress(); progress != nil { @@ -98,7 +98,7 @@ func Init(instance *rpc.Instance) []*status.Status { // FirstUpdate downloads libraries and packages indexes if they don't exist. // This ideally is only executed the first time the CLI is run. -func FirstUpdate(instance *rpc.Instance) *status.Status { +func FirstUpdate(instance *rpc.Instance) error { // Gets the data directory to verify if library_index.json and package_index.json exist dataDir := paths.New(configuration.Settings.GetString("directories.data")) diff --git a/commands/core/install.go b/commands/core/install.go index 1e8c049ba5b..2299aee477e 100644 --- a/commands/core/install.go +++ b/commands/core/install.go @@ -54,9 +54,8 @@ func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest, return nil, err } - status := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil) - if status != nil { - return nil, status.Err() + if err := commands.Init(&rpc.InitRequest{Instance: req.Instance}, nil); err != nil { + return nil, err } return &rpc.PlatformInstallResponse{}, nil diff --git a/commands/daemon/daemon.go b/commands/daemon/daemon.go index e2907f83ead..1d919025b6f 100644 --- a/commands/daemon/daemon.go +++ b/commands/daemon/daemon.go @@ -153,7 +153,7 @@ func (s *ArduinoCoreServerImpl) BoardAttach(req *rpc.BoardAttachRequest, stream // Destroy FIXMEDOC func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { resp, err := commands.Destroy(ctx, req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // UpdateIndex FIXMEDOC @@ -162,7 +162,7 @@ func (s *ArduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream func(p *rpc.DownloadProgress) { stream.Send(&rpc.UpdateIndexResponse{DownloadProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(resp) } @@ -173,7 +173,7 @@ func (s *ArduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd func(p *rpc.DownloadProgress) { stream.Send(&rpc.UpdateLibrariesIndexResponse{DownloadProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(&rpc.UpdateLibrariesIndexResponse{}) } @@ -184,7 +184,7 @@ func (s *ArduinoCoreServerImpl) UpdateCoreLibrariesIndex(req *rpc.UpdateCoreLibr func(p *rpc.DownloadProgress) { stream.Send(&rpc.UpdateCoreLibrariesIndexResponse{DownloadProgress: p}) }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(&rpc.UpdateCoreLibrariesIndexResponse{}) } @@ -192,7 +192,7 @@ func (s *ArduinoCoreServerImpl) UpdateCoreLibrariesIndex(req *rpc.UpdateCoreLibr // Outdated FIXMEDOC func (s *ArduinoCoreServerImpl) Outdated(ctx context.Context, req *rpc.OutdatedRequest) (*rpc.OutdatedResponse, error) { resp, err := commands.Outdated(ctx, req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // Upgrade FIXMEDOC @@ -210,18 +210,15 @@ func (s *ArduinoCoreServerImpl) Upgrade(req *rpc.UpgradeRequest, stream rpc.Ardu }, ) if err != nil { - return err.Err() + return convertErrorToRPCStatus(err) } return stream.Send(&rpc.UpgradeResponse{}) } // Create FIXMEDOC func (s *ArduinoCoreServerImpl) Create(_ context.Context, req *rpc.CreateRequest) (*rpc.CreateResponse, error) { - res, status := commands.Create(req) - if status != nil { - return nil, status.Err() - } - return res, nil + res, err := commands.Create(req) + return res, convertErrorToRPCStatus(err) } // Init FIXMEDOC @@ -229,10 +226,7 @@ func (s *ArduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor err := commands.Init(req, func(message *rpc.InitResponse) { stream.Send(message) }) - if err != nil { - return err.Err() - } - return nil + return convertErrorToRPCStatus(err) } // Version FIXMEDOC @@ -243,7 +237,7 @@ func (s *ArduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionReq // LoadSketch FIXMEDOC func (s *ArduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { resp, err := commands.LoadSketch(ctx, req) - return resp, err.Err() + return resp, convertErrorToRPCStatus(err) } // Compile FIXMEDOC diff --git a/commands/download.go b/commands/download.go index 5e8f623a9e5..a6265de9dc8 100644 --- a/commands/download.go +++ b/commands/download.go @@ -16,7 +16,6 @@ package commands import ( - "errors" "time" "github.com/arduino/arduino-cli/httpclient" @@ -27,16 +26,13 @@ import ( // GetDownloaderConfig returns the downloader configuration based on // current settings. func GetDownloaderConfig() (*downloader.Config, error) { - httpClient, err := httpclient.New() if err != nil { - return nil, err + return nil, &InvalidArgumentError{Message: tr("Could not connect via HTTP"), Cause: err} } - - res := &downloader.Config{ + return &downloader.Config{ HttpClient: *httpClient, - } - return res, nil + }, nil } // Download performs a download loop using the provided downloader.Downloader. @@ -63,7 +59,7 @@ func Download(d *downloader.Downloader, label string, downloadCB DownloadProgres } // The URL is not reachable for some reason if d.Resp.StatusCode >= 400 && d.Resp.StatusCode <= 599 { - return errors.New(d.Resp.Status) + return &FailedDownloadError{Message: tr("Server responded with: %s", d.Resp.Status)} } downloadCB(&rpc.DownloadProgress{Completed: true}) return nil diff --git a/commands/errors.go b/commands/errors.go index 49ef394c0b8..870e6877a7e 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -63,6 +63,23 @@ func (e *InvalidFQBNError) Unwrap() error { return e.Cause } +// InvalidURLError is returned when the URL has syntax errors +type InvalidURLError struct { + Cause error +} + +func (e *InvalidURLError) Error() string { + return composeErrorMsg(tr("Invalid URL"), e.Cause) +} + +func (e *InvalidURLError) ToRPCStatus() *status.Status { + return status.New(codes.InvalidArgument, e.Error()) +} + +func (e *InvalidURLError) Unwrap() error { + return e.Cause +} + // InvalidLibraryError is returned when the library has syntax errors type InvalidLibraryError struct { Cause error @@ -500,3 +517,55 @@ func (e *UnavailableError) Unwrap() error { func (e *UnavailableError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } + +// TempDirCreationFailedError is returned if a temp dir could not be created +type TempDirCreationFailedError struct { + Cause error +} + +func (e *TempDirCreationFailedError) Error() string { + return composeErrorMsg(tr("Cannot create temp dir"), e.Cause) +} + +func (e *TempDirCreationFailedError) Unwrap() error { + return e.Cause +} + +func (e *TempDirCreationFailedError) ToRPCStatus() *status.Status { + return status.New(codes.Unavailable, e.Error()) +} + +// TempFileCreationFailedError is returned if a temp file could not be created +type TempFileCreationFailedError struct { + Cause error +} + +func (e *TempFileCreationFailedError) Error() string { + return composeErrorMsg(tr("Cannot create temp file"), e.Cause) +} + +func (e *TempFileCreationFailedError) Unwrap() error { + return e.Cause +} + +func (e *TempFileCreationFailedError) ToRPCStatus() *status.Status { + return status.New(codes.Unavailable, e.Error()) +} + +// SignatureVerificationFailedError is returned if a signature verification fails +type SignatureVerificationFailedError struct { + File string + Cause error +} + +func (e *SignatureVerificationFailedError) Error() string { + return composeErrorMsg(tr("'%s' has an invalid signature", e.File), e.Cause) +} + +func (e *SignatureVerificationFailedError) Unwrap() error { + return e.Cause +} + +func (e *SignatureVerificationFailedError) ToRPCStatus() *status.Status { + return status.New(codes.Unavailable, e.Error()) +} diff --git a/commands/instances.go b/commands/instances.go index 9b83731dff2..fedcc8ec91b 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -36,7 +36,6 @@ import ( "github.com/arduino/arduino-cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "go.bug.st/downloader/v2" "google.golang.org/grpc/codes" @@ -102,7 +101,7 @@ func (instance *CoreInstance) installToolIfMissing(tool *cores.ToolRelease, down } // Create a new CoreInstance ready to be initialized, supporting directories are also created. -func Create(req *rpc.CreateRequest) (*rpc.CreateResponse, *status.Status) { +func Create(req *rpc.CreateRequest) (*rpc.CreateResponse, error) { instance := &CoreInstance{} // Setup downloads directory @@ -110,8 +109,7 @@ func Create(req *rpc.CreateRequest) (*rpc.CreateResponse, *status.Status) { if downloadsDir.NotExist() { err := downloadsDir.MkdirAll() if err != nil { - s := status.Newf(codes.FailedPrecondition, err.Error()) - return nil, s + return nil, &PermissionDeniedError{Message: tr("Failed to create downloads directory"), Cause: err} } } @@ -121,8 +119,7 @@ func Create(req *rpc.CreateRequest) (*rpc.CreateResponse, *status.Status) { if packagesDir.NotExist() { err := packagesDir.MkdirAll() if err != nil { - s := status.Newf(codes.FailedPrecondition, err.Error()) - return nil, s + return nil, &PermissionDeniedError{Message: tr("Failed to create data directory"), Cause: err} } } @@ -166,13 +163,13 @@ func Create(req *rpc.CreateRequest) (*rpc.CreateResponse, *status.Status) { // All responses are sent through responseCallback, can be nil to ignore all responses. // Failures don't stop the loading process, in case of loading failure the Platform or library // is simply skipped and an error gRPC status is sent to responseCallback. -func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) *status.Status { +func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) error { if responseCallback == nil { responseCallback = func(r *rpc.InitResponse) {} } instance := instances[req.Instance.Id] if instance == nil { - return status.Newf(codes.InvalidArgument, tr("Invalid instance ID")) + return &InvalidInstanceError{} } // We need to clear the PackageManager currently in use by this instance @@ -338,10 +335,10 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) *sta } // Destroy FIXMEDOC -func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, *status.Status) { +func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { id := req.GetInstance().GetId() if _, ok := instances[id]; !ok { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &InvalidInstanceError{} } delete(instances, id) @@ -349,25 +346,25 @@ func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse } // UpdateLibrariesIndex updates the library_index.json -func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequest, downloadCB func(*rpc.DownloadProgress)) *status.Status { +func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequest, downloadCB func(*rpc.DownloadProgress)) error { logrus.Info("Updating libraries index") lm := GetLibraryManager(req.GetInstance().GetId()) if lm == nil { - return status.New(codes.InvalidArgument, tr("Invalid instance")) + return &InvalidInstanceError{} } config, err := GetDownloaderConfig() if err != nil { - return status.New(codes.FailedPrecondition, err.Error()) + return err } if err := lm.IndexFile.Parent().MkdirAll(); err != nil { - return status.New(codes.PermissionDenied, err.Error()) + return &PermissionDeniedError{Message: tr("Could not create index directory"), Cause: err} } // Create a temp dir to stage all downloads tmp, err := paths.MkTempDir("", "library_index_download") if err != nil { - return status.New(codes.PermissionDenied, err.Error()) + return &TempDirCreationFailedError{Cause: err} } defer tmp.RemoveAll() @@ -375,54 +372,54 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequ tmpIndexGz := tmp.Join("library_index.json.gz") if d, err := downloader.DownloadWithConfig(tmpIndexGz.String(), librariesmanager.LibraryIndexGZURL.String(), *config, downloader.NoResume); err == nil { if err := Download(d, tr("Updating index: library_index.json.gz"), downloadCB); err != nil { - return status.New(codes.Unavailable, errors.Wrap(err, tr("Error downloading library_index.json.gz")).Error()) + return &FailedDownloadError{Message: tr("Error downloading library_index.json.gz"), Cause: err} } } else { - return status.New(codes.Unavailable, err.Error()) + return &FailedDownloadError{Message: tr("Error downloading library_index.json.gz"), Cause: err} } // Download signature tmpSignature := tmp.Join("library_index.json.sig") if d, err := downloader.DownloadWithConfig(tmpSignature.String(), librariesmanager.LibraryIndexSignature.String(), *config, downloader.NoResume); err == nil { if err := Download(d, tr("Updating index: library_index.json.sig"), downloadCB); err != nil { - return status.New(codes.Unavailable, errors.Wrap(err, tr("Error downloading library_index.json.sig")).Error()) + return &FailedDownloadError{Message: tr("Error downloading library_index.json.sig"), Cause: err} } } else { - return status.New(codes.Unavailable, err.Error()) + return &FailedDownloadError{Message: tr("Error downloading library_index.json.sig"), Cause: err} } // Extract the real library_index tmpIndex := tmp.Join("library_index.json") if err := paths.GUnzip(tmpIndexGz, tmpIndex); err != nil { - return status.New(codes.Unknown, errors.Wrap(err, tr("Error extracting library_index.json.gz")).Error()) + return &PermissionDeniedError{Message: tr("Error extracting library_index.json.gz"), Cause: err} } // Check signature if ok, _, err := security.VerifyArduinoDetachedSignature(tmpIndex, tmpSignature); err != nil { - return status.New(codes.Unknown, errors.Wrap(err, tr("Error verifying signature")).Error()) + return &PermissionDeniedError{Message: tr("Error verifying signature"), Cause: err} } else if !ok { - return status.New(codes.Unavailable, errors.New(tr("library_index.json has an invalid signature")).Error()) + return &SignatureVerificationFailedError{File: "library_index.json"} } // Copy extracted library_index and signature to final destination lm.IndexFile.Remove() lm.IndexFileSignature.Remove() if err := tmpIndex.CopyTo(lm.IndexFile); err != nil { - return status.New(codes.PermissionDenied, errors.Wrap(err, tr("Error writing library_index.json")).Error()) + return &PermissionDeniedError{Message: tr("Error writing library_index.json"), Cause: err} } if err := tmpSignature.CopyTo(lm.IndexFileSignature); err != nil { - return status.New(codes.PermissionDenied, errors.Wrap(err, tr("Error writing library_index.json.sig")).Error()) + return &PermissionDeniedError{Message: tr("Error writing library_index.json.sig"), Cause: err} } return nil } // UpdateIndex FIXMEDOC -func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB DownloadProgressCB) (*rpc.UpdateIndexResponse, *status.Status) { +func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB DownloadProgressCB) (*rpc.UpdateIndexResponse, error) { id := req.GetInstance().GetId() _, ok := instances[id] if !ok { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + return nil, &InvalidInstanceError{} } indexpath := paths.New(configuration.Settings.GetString("directories.Data")) @@ -442,7 +439,7 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do if URL.Scheme == "file" { path := paths.New(URL.Path) if _, err := packageindex.LoadIndexNoSign(path); err != nil { - return nil, status.Newf(codes.FailedPrecondition, tr("Invalid package index in %[1]s: %[2]s"), path, err) + return nil, &InvalidArgumentError{Message: tr("Invalid package index in %s", path), Cause: err} } fi, _ := os.Stat(path.String()) @@ -456,9 +453,9 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do var tmp *paths.Path if tmpFile, err := ioutil.TempFile("", ""); err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Error creating temp file for index download: %s"), err) + return nil, &TempFileCreationFailedError{Cause: err} } else if err := tmpFile.Close(); err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Error creating temp file for index download: %s"), err) + return nil, &TempFileCreationFailedError{Cause: err} } else { tmp = paths.New(tmpFile.Name()) } @@ -466,16 +463,16 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do config, err := GetDownloaderConfig() if err != nil { - return nil, status.Newf(codes.FailedPrecondition, tr("Error downloading index %[1]s: %[2]s"), URL, err) + return nil, &FailedDownloadError{Message: tr("Error downloading index '%s'", URL), Cause: err} } d, err := downloader.DownloadWithConfig(tmp.String(), URL.String(), *config) if err != nil { - return nil, status.Newf(codes.Unavailable, tr("Error downloading index %[1]s: %[2]s"), URL, err) + return nil, &FailedDownloadError{Message: tr("Error downloading index '%s'", URL), Cause: err} } coreIndexPath := indexpath.Join(path.Base(URL.Path)) err = Download(d, fmt.Sprintf(tr("Updating index: %s"), coreIndexPath.Base()), downloadCB) if err != nil { - return nil, status.Newf(codes.Unavailable, tr("Error downloading index %[1]s: %[2]s"), URL, err) + return nil, &FailedDownloadError{Message: tr("Error downloading index '%s'", URL), Cause: err} } // Check for signature @@ -484,14 +481,14 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do if URL.Hostname() == "downloads.arduino.cc" { URLSig, err := url.Parse(URL.String()) if err != nil { - return nil, status.Newf(codes.FailedPrecondition, tr("Error parsing url for index signature check: %s"), err) + return nil, &InvalidURLError{Cause: err} } URLSig.Path += ".sig" if t, err := ioutil.TempFile("", ""); err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Error creating temp file for index signature download: %s"), err) + return nil, &TempFileCreationFailedError{Cause: err} } else if err := t.Close(); err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Error creating temp file for index signature download: %s"), err) + return nil, &TempFileCreationFailedError{Cause: err} } else { tmpSig = paths.New(t.Name()) } @@ -499,38 +496,36 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do d, err := downloader.DownloadWithConfig(tmpSig.String(), URLSig.String(), *config) if err != nil { - return nil, status.Newf(codes.Unavailable, "downloading index signature %s: %s", URLSig, err) + return nil, &FailedDownloadError{Message: tr("Error downloading index signature '%s'", URLSig), Cause: err} } coreIndexSigPath = indexpath.Join(path.Base(URLSig.Path)) Download(d, fmt.Sprintf(tr("Updating index: %s"), coreIndexSigPath.Base()), downloadCB) if d.Error() != nil { - return nil, status.Newf(codes.Unavailable, tr("Error downloading index signature %[1]s: %[2]s"), URL, d.Error()) + return nil, &FailedDownloadError{Message: tr("Error downloading index signature '%s'", URLSig), Cause: err} } - valid, _, err := security.VerifyArduinoDetachedSignature(tmp, tmpSig) - if err != nil { - return nil, status.Newf(codes.Unknown, tr("Signature verification error: %s"), err) - } - if !valid { - return nil, status.Newf(codes.FailedPrecondition, tr("Index '%s' has an invalid signature"), URL) + if valid, _, err := security.VerifyArduinoDetachedSignature(tmp, tmpSig); err != nil { + return nil, &PermissionDeniedError{Message: tr("Error verifying signature"), Cause: err} + } else if !valid { + return nil, &SignatureVerificationFailedError{File: URL.String()} } } if _, err := packageindex.LoadIndex(tmp); err != nil { - return nil, status.Newf(codes.FailedPrecondition, tr("Invalid package index in %[1]s: %[2]s"), URL, err) + return nil, &InvalidArgumentError{Message: tr("Invalid package index in %s", URL), Cause: err} } if err := indexpath.MkdirAll(); err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Can't create data directory %[1]s: %[2]s"), indexpath, err) + return nil, &PermissionDeniedError{Message: tr("Can't create data directory %s", indexpath), Cause: err} } if err := tmp.CopyTo(coreIndexPath); err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Error saving downloaded index %[1]s: %[2]s"), URL, err) + return nil, &PermissionDeniedError{Message: tr("Error saving downloaded index %s", URL), Cause: err} } if tmpSig != nil { if err := tmpSig.CopyTo(coreIndexSigPath); err != nil { - return nil, status.Newf(codes.PermissionDenied, tr("Error saving downloaded index signature: %s"), err) + return nil, &PermissionDeniedError{Message: tr("Error saving downloaded index signature"), Cause: err} } } } @@ -539,7 +534,7 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB Do } // UpdateCoreLibrariesIndex updates both Cores and Libraries indexes -func UpdateCoreLibrariesIndex(ctx context.Context, req *rpc.UpdateCoreLibrariesIndexRequest, downloadCB DownloadProgressCB) *status.Status { +func UpdateCoreLibrariesIndex(ctx context.Context, req *rpc.UpdateCoreLibrariesIndexRequest, downloadCB DownloadProgressCB) error { _, err := UpdateIndex(ctx, &rpc.UpdateIndexRequest{ Instance: req.Instance, }, downloadCB) @@ -558,21 +553,21 @@ func UpdateCoreLibrariesIndex(ctx context.Context, req *rpc.UpdateCoreLibrariesI } // Outdated returns a list struct containing both Core and Libraries that can be updated -func Outdated(ctx context.Context, req *rpc.OutdatedRequest) (*rpc.OutdatedResponse, *status.Status) { +func Outdated(ctx context.Context, req *rpc.OutdatedRequest) (*rpc.OutdatedResponse, error) { id := req.GetInstance().GetId() - libraryManager := GetLibraryManager(id) - if libraryManager == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + lm := GetLibraryManager(id) + if lm == nil { + return nil, &InvalidInstanceError{} } outdatedLibraries := []*rpc.InstalledLibrary{} - for _, libAlternatives := range libraryManager.Libraries { + for _, libAlternatives := range lm.Libraries { for _, library := range libAlternatives.Alternatives { if library.Location != libraries.User { continue } - available := libraryManager.Index.FindLibraryUpdate(library) + available := lm.Index.FindLibraryUpdate(library) if available == nil { continue } @@ -584,15 +579,15 @@ func Outdated(ctx context.Context, req *rpc.OutdatedRequest) (*rpc.OutdatedRespo } } - packageManager := GetPackageManager(id) - if packageManager == nil { - return nil, status.New(codes.InvalidArgument, tr("Invalid instance")) + pm := GetPackageManager(id) + if pm == nil { + return nil, &InvalidInstanceError{} } outdatedPlatforms := []*rpc.Platform{} - for _, targetPackage := range packageManager.Packages { + for _, targetPackage := range pm.Packages { for _, installed := range targetPackage.Platforms { - if installedRelease := packageManager.GetInstalledPlatformRelease(installed); installedRelease != nil { + if installedRelease := pm.GetInstalledPlatformRelease(installed); installedRelease != nil { latest := installed.GetLatestRelease() if latest == nil || latest == installedRelease { continue @@ -676,15 +671,15 @@ func getOutputRelease(lib *librariesindex.Release) *rpc.LibraryRelease { } // Upgrade downloads and installs outdated Cores and Libraries -func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadProgressCB, taskCB TaskProgressCB) *status.Status { +func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadProgressCB, taskCB TaskProgressCB) error { downloaderConfig, err := GetDownloaderConfig() if err != nil { - return status.Newf(codes.FailedPrecondition, err.Error()) + return err } lm := GetLibraryManager(req.Instance.Id) if lm == nil { - return status.New(codes.InvalidArgument, tr("Invalid instance")) + return &InvalidInstanceError{} } for _, libAlternatives := range lm.Libraries { @@ -700,9 +695,9 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr // Downloads latest library release taskCB(&rpc.TaskProgress{Name: fmt.Sprintf(tr("Downloading %s"), available)}) if d, err := available.Resource.Download(lm.DownloadsDir, downloaderConfig); err != nil { - return status.Convert(err) + return &FailedDownloadError{Message: tr("Error downloading library"), Cause: err} } else if err := Download(d, available.String(), downloadCB); err != nil { - return status.New(codes.Unavailable, err.Error()) + return &FailedDownloadError{Message: tr("Error downloading library"), Cause: err} } // Installs downloaded library @@ -712,7 +707,7 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr taskCB(&rpc.TaskProgress{Message: tr("Already installed %s", available), Completed: true}) continue } else if err != nil { - return status.Newf(codes.Unknown, tr("Error checking lib install prerequisites: %s"), err) + return &FailedLibraryInstallError{Cause: err} } if libReplaced != nil { @@ -720,7 +715,7 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr } if err := lm.Install(available, libPath); err != nil { - return status.Convert(err) + return &FailedLibraryInstallError{Cause: err} } taskCB(&rpc.TaskProgress{Message: tr("Installed %s", available), Completed: true}) @@ -729,7 +724,7 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr pm := GetPackageManager(req.Instance.Id) if pm == nil { - return status.New(codes.InvalidArgument, tr("Invalid instance")) + return &InvalidInstanceError{} } for _, targetPackage := range pm.Packages { @@ -748,7 +743,7 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr // Get list of installed tools needed by the currently installed version _, installedTools, err := pm.FindPlatformReleaseDependencies(ref) if err != nil { - return status.Convert(err) + return &NotFoundError{Message: tr("Can't find dependencies for platform %s", ref), Cause: err} } ref = &packagemanager.PlatformReference{ @@ -760,7 +755,7 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr taskCB(&rpc.TaskProgress{Name: tr("Downloading %s", latest)}) _, tools, err := pm.FindPlatformReleaseDependencies(ref) if err != nil { - return status.Newf(codes.Unknown, tr("Platform %s is not installed", ref)) + return &NotFoundError{Message: tr("Can't find dependencies for platform %s", ref), Cause: err} } toolsToInstall := []*cores.ToolRelease{} @@ -777,15 +772,15 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr for _, tool := range toolsToInstall { if err := DownloadToolRelease(pm, tool, downloadCB); err != nil { taskCB(&rpc.TaskProgress{Message: tr("Error downloading tool %s", tool)}) - return status.Convert(err) + return &FailedDownloadError{Message: tr("Error downloading tool %s", tool), Cause: err} } } // Downloads platform if d, err := pm.DownloadPlatformRelease(latest, downloaderConfig); err != nil { - return status.Convert(err) + return &FailedDownloadError{Message: tr("Error downloading platform %s", latest), Cause: err} } else if err := Download(d, latest.String(), downloadCB); err != nil { - return status.New(codes.Unavailable, err.Error()) + return &FailedDownloadError{Message: tr("Error downloading platform %s", latest), Cause: err} } logrus.Info("Updating platform " + installed.String()) @@ -794,8 +789,9 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr // Installs tools for _, tool := range toolsToInstall { if err := InstallToolRelease(pm, tool, taskCB); err != nil { - taskCB(&rpc.TaskProgress{Message: tr("Error installing tool %s", tool)}) - return status.Convert(err) + msg := tr("Error installing tool %s", tool) + taskCB(&rpc.TaskProgress{Message: msg}) + return &FailedInstallError{Message: msg, Cause: err} } } @@ -803,8 +799,9 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr err = pm.InstallPlatform(latest) if err != nil { logrus.WithError(err).Error("Cannot install platform") - taskCB(&rpc.TaskProgress{Message: tr("Error installing platform %s", latest)}) - return status.Convert(err) + msg := tr("Error installing platform %s", latest) + taskCB(&rpc.TaskProgress{Message: msg}) + return &FailedInstallError{Message: msg, Cause: err} } // Uninstall previously installed release @@ -818,8 +815,9 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr // Rollback if err := pm.UninstallPlatform(latest); err != nil { logrus.WithError(err).Error("Error rolling-back changes.") - taskCB(&rpc.TaskProgress{Message: tr("Error rolling-back changes: %s", err)}) - return status.Convert(err) + msg := tr("Error rolling-back changes") + taskCB(&rpc.TaskProgress{Message: fmt.Sprintf("%s: %s", msg, err)}) + return &FailedInstallError{Message: msg, Cause: err} } } @@ -833,7 +831,7 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr if err := pm.UninstallTool(toolRelease); err != nil { log.WithError(err).Error("Error uninstalling") - return status.Convert(err) + return &FailedInstallError{Message: tr("Error uninstalling tool %s", toolRelease), Cause: err} } log.Info("Tool uninstalled") @@ -860,11 +858,11 @@ func Upgrade(ctx context.Context, req *rpc.UpgradeRequest, downloadCB DownloadPr } // LoadSketch collects and returns all files composing a sketch -func LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, *status.Status) { +func LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { // TODO: This should be a ToRpc function for the Sketch struct sketch, err := sk.New(paths.New(req.SketchPath)) if err != nil { - return nil, status.Newf(codes.Unknown, tr("Error loading sketch %[1]v: %[2]v"), req.SketchPath, err) + return nil, &SketchNotFoundError{Cause: err} } otherSketchFiles := make([]string, sketch.OtherSketchFiles.Len()) From 763fcb82a4fd1d12f3e9900652aa0ceed1363bd3 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 27 Aug 2021 14:27:26 +0200 Subject: [PATCH 15/19] updated tests and fixed some error wording --- commands/board/attach.go | 2 +- commands/compile/compile.go | 2 +- commands/debug/debug_info.go | 2 +- commands/errors.go | 12 ++++++------ commands/instances.go | 2 +- commands/sketch/archive.go | 2 +- commands/upload/upload.go | 2 +- test/test_board.py | 2 +- test/test_compile.py | 16 ++++++++-------- test/test_core.py | 7 +++++-- test/test_lib.py | 10 +++------- test/test_sketch.py | 4 ++-- test/test_update.py | 10 ++++++++-- 13 files changed, 39 insertions(+), 34 deletions(-) diff --git a/commands/board/attach.go b/commands/board/attach.go index 459bbc89b74..9bba157f726 100644 --- a/commands/board/attach.go +++ b/commands/board/attach.go @@ -46,7 +46,7 @@ func Attach(ctx context.Context, req *rpc.BoardAttachRequest, taskCB commands.Ta } sk, err := sketch.New(sketchPath) if err != nil { - return nil, &commands.SketchNotFoundError{Cause: err} + return nil, &commands.CantOpenSketchError{Cause: err} } boardURI := req.GetBoardUri() diff --git a/commands/compile/compile.go b/commands/compile/compile.go index 6a84acc3fbd..72fce77a932 100644 --- a/commands/compile/compile.go +++ b/commands/compile/compile.go @@ -99,7 +99,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil { - return nil, &commands.SketchNotFoundError{Cause: err} + return nil, &commands.CantOpenSketchError{Cause: err} } fqbnIn := req.GetFqbn() diff --git a/commands/debug/debug_info.go b/commands/debug/debug_info.go index 0e5c22625d5..b49cab74bef 100644 --- a/commands/debug/debug_info.go +++ b/commands/debug/debug_info.go @@ -44,7 +44,7 @@ func getDebugProperties(req *debug.DebugConfigRequest, pm *packagemanager.Packag sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil { - return nil, &commands.SketchNotFoundError{Cause: err} + return nil, &commands.CantOpenSketchError{Cause: err} } // XXX Remove this code duplication!! diff --git a/commands/errors.go b/commands/errors.go index 870e6877a7e..2e7eb5cc02a 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -304,20 +304,20 @@ func (e *MissingSketchPathError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } -// SketchNotFoundError is returned when the sketch is not found -type SketchNotFoundError struct { +// CantOpenSketchError is returned when the sketch is not found or cannot be opened +type CantOpenSketchError struct { Cause error } -func (e *SketchNotFoundError) Error() string { - return composeErrorMsg(tr("Sketch not found"), e.Cause) +func (e *CantOpenSketchError) Error() string { + return composeErrorMsg(tr("Can't open sketch"), e.Cause) } -func (e *SketchNotFoundError) Unwrap() error { +func (e *CantOpenSketchError) Unwrap() error { return e.Cause } -func (e *SketchNotFoundError) ToRPCStatus() *status.Status { +func (e *CantOpenSketchError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } diff --git a/commands/instances.go b/commands/instances.go index fedcc8ec91b..20e1d65c9e9 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -862,7 +862,7 @@ func LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketc // TODO: This should be a ToRpc function for the Sketch struct sketch, err := sk.New(paths.New(req.SketchPath)) if err != nil { - return nil, &SketchNotFoundError{Cause: err} + return nil, &CantOpenSketchError{Cause: err} } otherSketchFiles := make([]string, sketch.OtherSketchFiles.Len()) diff --git a/commands/sketch/archive.go b/commands/sketch/archive.go index f14a33f65fd..8c99ea0944c 100644 --- a/commands/sketch/archive.go +++ b/commands/sketch/archive.go @@ -43,7 +43,7 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc s, err := sketch.New(sketchPath) if err != nil { - return nil, &commands.SketchNotFoundError{Cause: err} + return nil, &commands.CantOpenSketchError{Cause: err} } sketchPath = s.FullPath diff --git a/commands/upload/upload.go b/commands/upload/upload.go index efed27a5c0a..cd856c65a3c 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -123,7 +123,7 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil && req.GetImportDir() == "" && req.GetImportFile() == "" { - return nil, &commands.SketchNotFoundError{Cause: err} + return nil, &commands.CantOpenSketchError{Cause: err} } pm := commands.GetPackageManager(req.GetInstance().GetId()) diff --git a/test/test_board.py b/test/test_board.py index 02efedc9ab1..868865f839c 100644 --- a/test/test_board.py +++ b/test/test_board.py @@ -528,7 +528,7 @@ def test_board_details_no_flags(run_command): run_command("core install arduino:samd@1.8.6") result = run_command("board details") assert not result.ok - assert "Error getting board details: parsing fqbn: invalid fqbn:" in result.stderr + assert "Error getting board details: Invalid FQBN:" in result.stderr assert result.stdout == "" diff --git a/test/test_compile.py b/test/test_compile.py index 8fd8996154c..adef6ca39a7 100644 --- a/test/test_compile.py +++ b/test/test_compile.py @@ -132,7 +132,7 @@ def test_compile_with_sketch_with_symlink_selfloop(run_command, data_dir): result = run_command("compile -b {fqbn} {sketch_path}".format(fqbn=fqbn, sketch_path=sketch_path)) # The assertion is a bit relaxed in this case because win behaves differently from macOs and linux # returning a different error detailed message - assert "Error during build: opening sketch" in result.stderr + assert "Error during build: Can't open sketch:" in result.stderr assert not result.ok sketch_name = "CompileIntegrationTestSymlinkDirLoop" @@ -154,7 +154,7 @@ def test_compile_with_sketch_with_symlink_selfloop(run_command, data_dir): result = run_command("compile -b {fqbn} {sketch_path}".format(fqbn=fqbn, sketch_path=sketch_path)) # The assertion is a bit relaxed in this case because win behaves differently from macOs and linux # returning a different error detailed message - assert "Error during build: opening sketch" in result.stderr + assert "Error during build: Can't open sketch:" in result.stderr assert not result.ok @@ -685,17 +685,17 @@ def test_compile_sketch_with_multiple_main_files(run_command, data_dir): # Build sketch from folder res = run_command(f"compile --clean -b {fqbn} {sketch_path}") assert res.failed - assert "Error during build: opening sketch: multiple main sketch files found" in res.stderr + assert "Error during build: Can't open sketch: multiple main sketch files found" in res.stderr # Build sketch from .ino file res = run_command(f"compile --clean -b {fqbn} {sketch_ino_file}") assert res.failed - assert "Error during build: opening sketch: multiple main sketch files found" in res.stderr + assert "Error during build: Can't open sketch: multiple main sketch files found" in res.stderr # Build sketch from .pde file res = run_command(f"compile --clean -b {fqbn} {sketch_pde_file}") assert res.failed - assert "Error during build: opening sketch: multiple main sketch files found" in res.stderr + assert "Error during build: Can't open sketch: multiple main sketch files found" in res.stderr def test_compile_sketch_case_mismatch_fails(run_command, data_dir): @@ -718,15 +718,15 @@ def test_compile_sketch_case_mismatch_fails(run_command, data_dir): # * Compiling with sketch path res = run_command(f"compile --clean -b {fqbn} {sketch_path}") assert res.failed - assert "Error during build: opening sketch: no valid sketch found" in res.stderr + assert "Error during build: Can't open sketch: no valid sketch found" in res.stderr # * Compiling with sketch main file res = run_command(f"compile --clean -b {fqbn} {sketch_main_file}") assert res.failed - assert "Error during build: opening sketch: no valid sketch found" in res.stderr + assert "Error during build: Can't open sketch: no valid sketch found" in res.stderr # * Compiling in sketch path res = run_command(f"compile --clean -b {fqbn}", custom_working_dir=sketch_path) assert res.failed - assert "Error during build: opening sketch: no valid sketch found" in res.stderr + assert "Error during build: Can't open sketch: no valid sketch found" in res.stderr def test_compile_with_only_compilation_database_flag(run_command, data_dir): diff --git a/test/test_core.py b/test/test_core.py index 66748b327e5..9f43d023f9a 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -177,7 +177,7 @@ def test_core_updateindex_url_not_found(run_command, httpserver): result = run_command(f"core update-index --additional-urls={url}") assert result.failed lines = [l.strip() for l in result.stderr.splitlines()] - assert f"Error updating index: downloading index {url}: 404 NOT FOUND" in lines + assert f"Error updating index: Error downloading index '{url}': Server responded with: 404 NOT FOUND" in lines def test_core_updateindex_internal_server_error(run_command, httpserver): @@ -190,7 +190,10 @@ def test_core_updateindex_internal_server_error(run_command, httpserver): result = run_command(f"core update-index --additional-urls={url}") assert result.failed lines = [l.strip() for l in result.stderr.splitlines()] - assert f"Error updating index: downloading index {url}: 500 INTERNAL SERVER ERROR" in lines + assert ( + f"Error updating index: Error downloading index '{url}': Server responded with: 500 INTERNAL SERVER ERROR" + in lines + ) def test_core_install_without_updateindex(run_command): diff --git a/test/test_lib.py b/test/test_lib.py index a470ee8a50d..254ab9262d6 100644 --- a/test/test_lib.py +++ b/test/test_lib.py @@ -117,18 +117,14 @@ def test_list_exit_code(run_command): # Verify lib list command fails because specified platform is not installed result = run_command("lib list -b arduino:samd:mkr1000") assert result.failed - assert ( - result.stderr.strip() == "Error listing Libraries: loading board data: platform arduino:samd is not installed" - ) + assert result.stderr.strip() == "Error listing Libraries: Unknown FQBN: platform arduino:samd is not installed" assert run_command('lib install "AllThingsTalk LoRaWAN SDK"') # Verifies lib list command keeps failing result = run_command("lib list -b arduino:samd:mkr1000") assert result.failed - assert ( - result.stderr.strip() == "Error listing Libraries: loading board data: platform arduino:samd is not installed" - ) + assert result.stderr.strip() == "Error listing Libraries: Unknown FQBN: platform arduino:samd is not installed" assert run_command("core install arduino:samd") @@ -224,7 +220,7 @@ def test_install(run_command): # (https://github.com/arduino/arduino-cli/issues/534) res = run_command("lib install MD_Parola@3.2.0") assert res.failed - assert "Error resolving dependencies for MD_Parola@3.2.0: dependency 'MD_MAX72xx' is not available" in res.stderr + assert "No valid dependencies solution found: dependency 'MD_MAX72xx' is not available" in res.stderr def test_install_library_with_dependencies(run_command): diff --git a/test/test_sketch.py b/test/test_sketch.py index 35e8b4fd615..b03b484ee63 100644 --- a/test/test_sketch.py +++ b/test/test_sketch.py @@ -845,7 +845,7 @@ def test_sketch_archive_with_multiple_main_files(run_command, copy_sketch, worki assert res.failed assert "Sketches with .pde extension are deprecated, please rename the following files to .ino" in res.stderr assert str(sketch_file.relative_to(sketch_dir)) in res.stderr - assert "Error archiving: multiple main sketch files found" in res.stderr + assert "Error archiving: Can't open sketch: multiple main sketch files found" in res.stderr def test_sketch_archive_case_mismatch_fails(run_command, data_dir): @@ -859,4 +859,4 @@ def test_sketch_archive_case_mismatch_fails(run_command, data_dir): res = run_command(f'sketch archive "{sketch_path}"') assert res.failed - assert "Error archiving: no valid sketch found" in res.stderr + assert "Error archiving: Can't open sketch: no valid sketch found" in res.stderr diff --git a/test/test_update.py b/test/test_update.py index 582ef51aa6d..4b92194078a 100644 --- a/test/test_update.py +++ b/test/test_update.py @@ -63,7 +63,10 @@ def test_update_with_url_not_found(run_command, httpserver): res = run_command(f"update --additional-urls={url}") assert res.failed lines = [l.strip() for l in res.stderr.splitlines()] - assert f"Error updating core and libraries index: downloading index {url}: 404 NOT FOUND" in lines + assert ( + f"Error updating core and libraries index: Error downloading index '{url}':" + " Server responded with: 404 NOT FOUND" in lines + ) def test_update_with_url_internal_server_error(run_command, httpserver): @@ -76,7 +79,10 @@ def test_update_with_url_internal_server_error(run_command, httpserver): res = run_command(f"update --additional-urls={url}") assert res.failed lines = [l.strip() for l in res.stderr.splitlines()] - assert f"Error updating core and libraries index: downloading index {url}: 500 INTERNAL SERVER ERROR" in lines + assert ( + f"Error updating core and libraries index: Error downloading index '{url}':" + " Server responded with: 500 INTERNAL SERVER ERROR" in lines + ) def test_update_showing_outdated_using_library_with_invalid_version(run_command, data_dir): From 50d17c466ece5e5f28206ef2ebda5feecf7c033e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 27 Aug 2021 15:19:25 +0200 Subject: [PATCH 16/19] fixed go lint warnings --- commands/errors.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/commands/errors.go b/commands/errors.go index 2e7eb5cc02a..9aa552dcdc4 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -32,6 +32,7 @@ func composeErrorMsg(msg string, cause error) string { // CommandError is an error that may be converted into a gRPC status. type CommandError interface { + // ToRPCStatus convertes the error into a *status.Status ToRPCStatus() *status.Status } @@ -42,6 +43,7 @@ func (e *InvalidInstanceError) Error() string { return tr("Invalid instance") } +// ToRPCStatus convertes the error into a *status.Status func (e *InvalidInstanceError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -55,6 +57,7 @@ func (e *InvalidFQBNError) Error() string { return composeErrorMsg(tr("Invalid FQBN"), e.Cause) } +// ToRPCStatus convertes the error into a *status.Status func (e *InvalidFQBNError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -72,6 +75,7 @@ func (e *InvalidURLError) Error() string { return composeErrorMsg(tr("Invalid URL"), e.Cause) } +// ToRPCStatus convertes the error into a *status.Status func (e *InvalidURLError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -89,6 +93,7 @@ func (e *InvalidLibraryError) Error() string { return composeErrorMsg(tr("Invalid library"), e.Cause) } +// ToRPCStatus convertes the error into a *status.Status func (e *InvalidLibraryError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -106,6 +111,7 @@ func (e *InvalidVersionError) Error() string { return composeErrorMsg(tr("Invalid version"), e.Cause) } +// ToRPCStatus convertes the error into a *status.Status func (e *InvalidVersionError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -121,6 +127,7 @@ func (e *MissingFQBNError) Error() string { return tr("Missing FQBN (Fully Qualified Board Name)") } +// ToRPCStatus convertes the error into a *status.Status func (e *MissingFQBNError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -138,6 +145,7 @@ func (e *UnknownFQBNError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *UnknownFQBNError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -149,6 +157,7 @@ func (e *MissingPortProtocolError) Error() string { return tr("Missing port protocol") } +// ToRPCStatus convertes the error into a *status.Status func (e *MissingPortProtocolError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -160,6 +169,7 @@ func (e *MissingProgrammerError) Error() string { return tr("Missing programmer") } +// ToRPCStatus convertes the error into a *status.Status func (e *MissingProgrammerError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -171,6 +181,7 @@ func (e *ProgreammerRequiredForUploadError) Error() string { return tr("A programmer is required to upload") } +// ToRPCStatus convertes the error into a *status.Status func (e *ProgreammerRequiredForUploadError) ToRPCStatus() *status.Status { st, _ := status. New(codes.InvalidArgument, e.Error()). @@ -192,6 +203,7 @@ func (e *ProgrammerNotFoundError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *ProgrammerNotFoundError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -206,6 +218,7 @@ func (e *InvalidPlatformPropertyError) Error() string { return tr("Invalid '%[1]s' property: %[2]s", e.Property, e.Value) } +// ToRPCStatus convertes the error into a *status.Status func (e *InvalidPlatformPropertyError) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -219,6 +232,7 @@ func (e *MissingPlatformPropertyError) Error() string { return tr("Property '%s' is undefined", e.Property) } +// ToRPCStatus convertes the error into a *status.Status func (e *MissingPlatformPropertyError) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -233,6 +247,7 @@ func (e *PlatformNotFound) Error() string { return composeErrorMsg(tr("Platform '%s' not found", e.Platform), e.Cause) } +// ToRPCStatus convertes the error into a *status.Status func (e *PlatformNotFound) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -251,6 +266,7 @@ func (e *LibraryNotFound) Error() string { return composeErrorMsg(tr("Library '%s' not found", e.Library), e.Cause) } +// ToRPCStatus convertes the error into a *status.Status func (e *LibraryNotFound) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -269,6 +285,7 @@ func (e *LibraryDependenciesResolutionFailedError) Error() string { return composeErrorMsg(tr("No valid dependencies solution found"), e.Cause) } +// ToRPCStatus convertes the error into a *status.Status func (e *LibraryDependenciesResolutionFailedError) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -286,6 +303,7 @@ func (e *PlatformAlreadyAtTheLatestVersionError) Error() string { return tr("Platform '%s' is already at the latest version", e.Platform) } +// ToRPCStatus convertes the error into a *status.Status func (e *PlatformAlreadyAtTheLatestVersionError) ToRPCStatus() *status.Status { st, _ := status. New(codes.AlreadyExists, e.Error()). @@ -300,6 +318,7 @@ func (e *MissingSketchPathError) Error() string { return tr("Missing sketch path") } +// ToRPCStatus convertes the error into a *status.Status func (e *MissingSketchPathError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -317,6 +336,7 @@ func (e *CantOpenSketchError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *CantOpenSketchError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -335,6 +355,7 @@ func (e *FailedInstallError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *FailedInstallError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -352,6 +373,7 @@ func (e *FailedLibraryInstallError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *FailedLibraryInstallError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -370,6 +392,7 @@ func (e *FailedUninstallError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *FailedUninstallError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -388,6 +411,7 @@ func (e *FailedDownloadError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *FailedDownloadError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -406,6 +430,7 @@ func (e *FailedUploadError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *FailedUploadError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -424,6 +449,7 @@ func (e *FailedDebugError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *FailedDebugError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -442,6 +468,7 @@ func (e *CompileFailedError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *CompileFailedError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -460,6 +487,7 @@ func (e *InvalidArgumentError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *InvalidArgumentError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -478,6 +506,7 @@ func (e *NotFoundError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *NotFoundError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -496,6 +525,7 @@ func (e *PermissionDeniedError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *PermissionDeniedError) ToRPCStatus() *status.Status { return status.New(codes.PermissionDenied, e.Error()) } @@ -514,6 +544,7 @@ func (e *UnavailableError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *UnavailableError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -531,6 +562,7 @@ func (e *TempDirCreationFailedError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *TempDirCreationFailedError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -548,6 +580,7 @@ func (e *TempFileCreationFailedError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *TempFileCreationFailedError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -566,6 +599,7 @@ func (e *SignatureVerificationFailedError) Unwrap() error { return e.Cause } +// ToRPCStatus convertes the error into a *status.Status func (e *SignatureVerificationFailedError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } From 89a61df4e7946718cdb3f8e69fb433619ad50aef Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sat, 28 Aug 2021 19:42:57 +0200 Subject: [PATCH 17/19] Apply suggestions from code review Co-authored-by: per1234 --- arduino/cores/fqbn.go | 2 +- commands/core/uninstall.go | 2 +- commands/errors.go | 74 +++++++++++++++++++------------------- commands/upload/upload.go | 2 +- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/arduino/cores/fqbn.go b/arduino/cores/fqbn.go index 68391781220..f85d9af476c 100644 --- a/arduino/cores/fqbn.go +++ b/arduino/cores/fqbn.go @@ -51,7 +51,7 @@ func ParseFQBN(fqbnIn string) (*FQBN, error) { for _, pair := range strings.Split(fqbnParts[3], ",") { parts := strings.SplitN(pair, "=", 2) if len(parts) != 2 { - return nil, fmt.Errorf(tr("invalid config oprion: %s"), pair) + return nil, fmt.Errorf(tr("invalid config option: %s"), pair) } k := strings.TrimSpace(parts[0]) v := strings.TrimSpace(parts[1]) diff --git a/commands/core/uninstall.go b/commands/core/uninstall.go index 804ba02b755..0a4af5a2ee9 100644 --- a/commands/core/uninstall.go +++ b/commands/core/uninstall.go @@ -82,7 +82,7 @@ func uninstallPlatformRelease(pm *packagemanager.PackageManager, platformRelease } log.Info("Platform uninstalled") - taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Platofrm %s uninstalled"), platformRelease), Completed: true}) + taskCB(&rpc.TaskProgress{Message: fmt.Sprintf(tr("Platform %s uninstalled"), platformRelease), Completed: true}) return nil } diff --git a/commands/errors.go b/commands/errors.go index 9aa552dcdc4..e2570fa9e4d 100644 --- a/commands/errors.go +++ b/commands/errors.go @@ -43,7 +43,7 @@ func (e *InvalidInstanceError) Error() string { return tr("Invalid instance") } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *InvalidInstanceError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -57,7 +57,7 @@ func (e *InvalidFQBNError) Error() string { return composeErrorMsg(tr("Invalid FQBN"), e.Cause) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *InvalidFQBNError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -75,7 +75,7 @@ func (e *InvalidURLError) Error() string { return composeErrorMsg(tr("Invalid URL"), e.Cause) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *InvalidURLError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -93,7 +93,7 @@ func (e *InvalidLibraryError) Error() string { return composeErrorMsg(tr("Invalid library"), e.Cause) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *InvalidLibraryError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -111,7 +111,7 @@ func (e *InvalidVersionError) Error() string { return composeErrorMsg(tr("Invalid version"), e.Cause) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *InvalidVersionError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -127,7 +127,7 @@ func (e *MissingFQBNError) Error() string { return tr("Missing FQBN (Fully Qualified Board Name)") } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *MissingFQBNError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -145,7 +145,7 @@ func (e *UnknownFQBNError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *UnknownFQBNError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -157,7 +157,7 @@ func (e *MissingPortProtocolError) Error() string { return tr("Missing port protocol") } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *MissingPortProtocolError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -169,20 +169,20 @@ func (e *MissingProgrammerError) Error() string { return tr("Missing programmer") } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *MissingProgrammerError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } -// ProgreammerRequiredForUploadError is returned then the upload can be done only using a programmer -type ProgreammerRequiredForUploadError struct{} +// ProgrammerRequiredForUploadError is returned then the upload can be done only using a programmer +type ProgrammerRequiredForUploadError struct{} -func (e *ProgreammerRequiredForUploadError) Error() string { +func (e *ProgrammerRequiredForUploadError) Error() string { return tr("A programmer is required to upload") } -// ToRPCStatus convertes the error into a *status.Status -func (e *ProgreammerRequiredForUploadError) ToRPCStatus() *status.Status { +// ToRPCStatus converts the error into a *status.Status +func (e *ProgrammerRequiredForUploadError) ToRPCStatus() *status.Status { st, _ := status. New(codes.InvalidArgument, e.Error()). WithDetails(&rpc.ProgrammerIsRequiredForUploadError{}) @@ -203,7 +203,7 @@ func (e *ProgrammerNotFoundError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *ProgrammerNotFoundError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -218,7 +218,7 @@ func (e *InvalidPlatformPropertyError) Error() string { return tr("Invalid '%[1]s' property: %[2]s", e.Property, e.Value) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *InvalidPlatformPropertyError) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -232,7 +232,7 @@ func (e *MissingPlatformPropertyError) Error() string { return tr("Property '%s' is undefined", e.Property) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *MissingPlatformPropertyError) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -247,7 +247,7 @@ func (e *PlatformNotFound) Error() string { return composeErrorMsg(tr("Platform '%s' not found", e.Platform), e.Cause) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *PlatformNotFound) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -266,7 +266,7 @@ func (e *LibraryNotFound) Error() string { return composeErrorMsg(tr("Library '%s' not found", e.Library), e.Cause) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *LibraryNotFound) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -285,7 +285,7 @@ func (e *LibraryDependenciesResolutionFailedError) Error() string { return composeErrorMsg(tr("No valid dependencies solution found"), e.Cause) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *LibraryDependenciesResolutionFailedError) ToRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -303,7 +303,7 @@ func (e *PlatformAlreadyAtTheLatestVersionError) Error() string { return tr("Platform '%s' is already at the latest version", e.Platform) } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *PlatformAlreadyAtTheLatestVersionError) ToRPCStatus() *status.Status { st, _ := status. New(codes.AlreadyExists, e.Error()). @@ -318,7 +318,7 @@ func (e *MissingSketchPathError) Error() string { return tr("Missing sketch path") } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *MissingSketchPathError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -336,7 +336,7 @@ func (e *CantOpenSketchError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *CantOpenSketchError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -355,7 +355,7 @@ func (e *FailedInstallError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *FailedInstallError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -373,7 +373,7 @@ func (e *FailedLibraryInstallError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *FailedLibraryInstallError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -392,7 +392,7 @@ func (e *FailedUninstallError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *FailedUninstallError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -411,7 +411,7 @@ func (e *FailedDownloadError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *FailedDownloadError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -430,7 +430,7 @@ func (e *FailedUploadError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *FailedUploadError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -449,7 +449,7 @@ func (e *FailedDebugError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *FailedDebugError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -468,7 +468,7 @@ func (e *CompileFailedError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *CompileFailedError) ToRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -487,7 +487,7 @@ func (e *InvalidArgumentError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *InvalidArgumentError) ToRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -506,7 +506,7 @@ func (e *NotFoundError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *NotFoundError) ToRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -525,7 +525,7 @@ func (e *PermissionDeniedError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *PermissionDeniedError) ToRPCStatus() *status.Status { return status.New(codes.PermissionDenied, e.Error()) } @@ -544,7 +544,7 @@ func (e *UnavailableError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *UnavailableError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -562,7 +562,7 @@ func (e *TempDirCreationFailedError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *TempDirCreationFailedError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -580,7 +580,7 @@ func (e *TempFileCreationFailedError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *TempFileCreationFailedError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -599,7 +599,7 @@ func (e *SignatureVerificationFailedError) Unwrap() error { return e.Cause } -// ToRPCStatus convertes the error into a *status.Status +// ToRPCStatus converts the error into a *status.Status func (e *SignatureVerificationFailedError) ToRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } diff --git a/commands/upload/upload.go b/commands/upload/upload.go index cd856c65a3c..975bb2558f2 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -304,7 +304,7 @@ func runProgramAction(pm *packagemanager.PackageManager, } if !uploadProperties.ContainsKey("upload.protocol") && programmer == nil { - return &commands.ProgreammerRequiredForUploadError{} + return &commands.ProgrammerRequiredForUploadError{} } // Set properties for verbose upload From 4bcaf9c92b2c49bdab82906946a0655d3e8df567 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 30 Aug 2021 10:40:28 +0200 Subject: [PATCH 18/19] Apply changes from code review Co-authored-by: Silvano Cerza <3314350+silvanocerza@users.noreply.github.com> --- cli/lib/check_deps.go | 4 ++-- commands/board/list.go | 8 ++++---- commands/upload/upload.go | 6 +++--- commands/upload/upload_test.go | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/cli/lib/check_deps.go b/cli/lib/check_deps.go index 87e556d4bd1..effc09063e9 100644 --- a/cli/lib/check_deps.go +++ b/cli/lib/check_deps.go @@ -51,12 +51,12 @@ func runDepsCommand(cmd *cobra.Command, args []string) { os.Exit(errorcodes.ErrBadArgument) } - deps, stat := lib.LibraryResolveDependencies(context.Background(), &rpc.LibraryResolveDependenciesRequest{ + deps, err := lib.LibraryResolveDependencies(context.Background(), &rpc.LibraryResolveDependenciesRequest{ Instance: instance, Name: libRef.Name, Version: libRef.Version, }) - if stat != nil { + if err != nil { feedback.Errorf(tr("Error resolving dependencies for %[1]s: %[2]s", libRef, err)) } diff --git a/commands/board/list.go b/commands/board/list.go index 84d1fff773b..099e79a045e 100644 --- a/commands/board/list.go +++ b/commands/board/list.go @@ -187,10 +187,10 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e error) { dm := pm.DiscoveryManager() if errs := dm.RunAll(); len(errs) > 0 { - return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: errs[0]} + return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: fmt.Errorf("%v", errs)} } if errs := dm.StartAll(); len(errs) > 0 { - return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: errs[0]} + return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: fmt.Errorf("%v", errs)} } defer func() { if errs := dm.StopAll(); len(errs) > 0 { @@ -202,7 +202,7 @@ func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, e error) { retVal := []*rpc.DetectedPort{} ports, errs := pm.DiscoveryManager().List() if len(errs) > 0 { - return nil, &commands.UnavailableError{Message: tr("Error getting board list"), Cause: errs[0]} + return nil, &commands.UnavailableError{Message: tr("Error getting board list"), Cause: fmt.Errorf("%v", errs)} } for _, port := range ports { boards, err := identify(pm, port) @@ -231,7 +231,7 @@ func Watch(instanceID int32, interrupt <-chan bool) (<-chan *rpc.BoardListWatchR runErrs := dm.RunAll() if len(runErrs) == len(dm.IDs()) { // All discoveries failed to run, we can't do anything - return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: runErrs[0]} + return nil, &commands.UnavailableError{Message: tr("Error starting board discoveries"), Cause: fmt.Errorf("%v", runErrs)} } eventsChan, errs := dm.StartSyncAll() diff --git a/commands/upload/upload.go b/commands/upload/upload.go index 975bb2558f2..bdc54edb2fd 100644 --- a/commands/upload/upload.go +++ b/commands/upload/upload.go @@ -237,9 +237,9 @@ func runProgramAction(pm *packagemanager.PackageManager, } else if programmer != nil { action = "program" } - uploadToolID, st := getToolID(props, action, port.Protocol) - if st != nil { - return st + uploadToolID, err := getToolID(props, action, port.Protocol) + if err != nil { + return err } var uploadToolPlatform *cores.PlatformRelease diff --git a/commands/upload/upload_test.go b/commands/upload/upload_test.go index 9f7b04a6d3a..3f69337565c 100644 --- a/commands/upload/upload_test.go +++ b/commands/upload/upload_test.go @@ -180,7 +180,7 @@ func TestUploadPropertiesComposition(t *testing.T) { testRunner := func(t *testing.T, test test, verboseVerify bool) { outStream := &bytes.Buffer{} errStream := &bytes.Buffer{} - status := runProgramAction( + err := runProgramAction( pm, nil, // sketch "", // importFile @@ -201,9 +201,9 @@ func TestUploadPropertiesComposition(t *testing.T) { verboseVerifyOutput = "quiet noverify" } if test.expectedOutput == "FAIL" { - require.NotNil(t, status) + require.NotNil(t, err) } else { - require.Nil(t, status) + require.Nil(t, err) outFiltered := strings.ReplaceAll(outStream.String(), "\r", "") outFiltered = strings.ReplaceAll(outFiltered, "\\", "/") require.Contains(t, outFiltered, strings.ReplaceAll(test.expectedOutput, "$$VERBOSE-VERIFY$$", verboseVerifyOutput)) From 6bf77b9b1375918a25d36a648d5e34666873eef1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 27 Aug 2021 09:33:14 +0200 Subject: [PATCH 19/19] fix i18n --- i18n/data/en.po | 1084 ++++++++++++++++++++++------------------------ i18n/rice-box.go | 8 +- 2 files changed, 527 insertions(+), 565 deletions(-) diff --git a/i18n/data/en.po b/i18n/data/en.po index 1b785de8fa8..2ae076af86c 100644 --- a/i18n/data/en.po +++ b/i18n/data/en.po @@ -41,11 +41,11 @@ msgstr "%[1]s, protocol version: %[2]d" msgid "%s already downloaded" msgstr "%s already downloaded" -#: commands/upload/upload.go:528 +#: commands/upload/upload.go:533 msgid "%s and %s cannot be used together" msgstr "%s and %s cannot be used together" -#: cli/debug/debug.go:159 +#: cli/debug/debug.go:154 msgid "%s custom configurations" msgstr "%s custom configurations" @@ -54,7 +54,6 @@ msgid "%s downloaded" msgstr "%s downloaded" #: commands/bundled_tools.go:57 -#: commands/core/install.go:181 msgid "%s installed" msgstr "%s installed" @@ -83,12 +82,14 @@ msgstr "%s must be installed." msgid "%s pattern is missing" msgstr "%s pattern is missing" -#: commands/core/uninstall.go:90 -#: commands/core/uninstall.go:106 -#: commands/instances.go:840 +#: commands/instances.go:838 msgid "%s uninstalled" msgstr "%s uninstalled" +#: commands/errors.go:595 +msgid "'%s' has an invalid signature" +msgstr "'%s' has an invalid signature" + #: cli/board/listall.go:88 #: cli/board/search.go:90 msgid "(hidden)" @@ -110,10 +111,14 @@ msgstr "--git-url and --zip-path are disabled by default, for more information s msgid "--git-url and --zip-path flags allow installing untrusted files, use it at your own risk." msgstr "--git-url and --zip-path flags allow installing untrusted files, use it at your own risk." +#: commands/errors.go:181 +msgid "A programmer is required to upload" +msgstr "A programmer is required to upload" + #: cli/core/download.go:36 #: cli/core/install.go:37 #: cli/core/uninstall.go:36 -#: cli/core/upgrade.go:36 +#: cli/core/upgrade.go:38 msgid "ARCH" msgstr "ARCH" @@ -134,12 +139,12 @@ msgstr "Adds one or more values to a setting." msgid "Aliases:" msgstr "Aliases:" -#: cli/core/upgrade.go:66 +#: cli/core/upgrade.go:68 msgid "All the cores are already at the latest version" msgstr "All the cores are already at the latest version" -#: commands/instances.go:712 -#: commands/lib/install.go:92 +#: commands/instances.go:707 +#: commands/lib/install.go:96 msgid "Already installed %s" msgstr "Already installed %s" @@ -147,10 +152,14 @@ msgstr "Already installed %s" msgid "Alternatives for %[1]s: %[2]s" msgstr "Alternatives for %[1]s: %[2]s" -#: cli/lib/search.go:170 +#: cli/lib/search.go:171 msgid "Architecture: %s" msgstr "Architecture: %s" +#: commands/sketch/archive.go:70 +msgid "Archive already exists" +msgstr "Archive already exists" + #: legacy/builder/constants/constants.go:93 msgid "Archiving built core (caching) in: {0}" msgstr "Archiving built core (caching) in: {0}" @@ -207,7 +216,7 @@ msgstr "Attach board error: %v" msgid "Attaches a sketch to a board." msgstr "Attaches a sketch to a board." -#: cli/lib/search.go:161 +#: cli/lib/search.go:162 msgid "Author: %s" msgstr "Author: %s" @@ -230,7 +239,7 @@ msgstr "Binary file to upload." msgid "Board Name" msgstr "Board Name" -#: commands/board/attach.go:94 +#: commands/board/attach.go:93 msgid "Board found: %s" msgstr "Board found: %s" @@ -258,6 +267,27 @@ msgstr "Build options changed" msgid "Builds of 'core.a' are saved into this path to be cached and reused." msgstr "Builds of 'core.a' are saved into this path to be cached and reused." +#: commands/instances.go:520 +msgid "Can't create data directory %s" +msgstr "Can't create data directory %s" + +#: commands/lib/download.go:61 +#: commands/lib/download.go:64 +#: commands/lib/download.go:66 +msgid "Can't download library" +msgstr "Can't download library" + +#: commands/core/install.go:127 +#: commands/core/uninstall.go:53 +#: commands/instances.go:746 +#: commands/instances.go:758 +msgid "Can't find dependencies for platform %s" +msgstr "Can't find dependencies for platform %s" + +#: commands/errors.go:332 +msgid "Can't open sketch" +msgstr "Can't open sketch" + #: cli/config/set.go:54 msgid "Can't set multiple values in key %v" msgstr "Can't set multiple values in key %v" @@ -272,6 +302,14 @@ msgstr "Can't use both --dest-file and --dest-dir flags at the same time." msgid "Can't write config file: %v" msgstr "Can't write config file: %v" +#: commands/compile/compile.go:180 +msgid "Cannot create build cache directory" +msgstr "Cannot create build cache directory" + +#: commands/compile/compile.go:150 +msgid "Cannot create build directory" +msgstr "Cannot create build directory" + #: cli/config/init.go:97 msgid "Cannot create config file directory: %v" msgstr "Cannot create config file directory: %v" @@ -280,29 +318,49 @@ msgstr "Cannot create config file directory: %v" msgid "Cannot create config file: %v" msgstr "Cannot create config file: %v" -#: commands/debug/debug.go:67 +#: commands/errors.go:558 +msgid "Cannot create temp dir" +msgstr "Cannot create temp dir" + +#: commands/errors.go:576 +msgid "Cannot create temp file" +msgstr "Cannot create temp file" + +#: commands/debug/debug.go:66 msgid "Cannot execute debug tool" msgstr "Cannot execute debug tool" +#: commands/board/attach.go:106 +msgid "Cannot export sketch metadata" +msgstr "Cannot export sketch metadata" + #: cli/config/init.go:72 #: cli/config/init.go:83 msgid "Cannot find absolute path: %v" msgstr "Cannot find absolute path: %v" -#: commands/debug/debug.go:51 -msgid "Cannot get command line for tool" -msgstr "Cannot get command line for tool" - #: configuration/configuration.go:147 #: configuration/configuration.go:153 msgid "Cannot get executable path: %v" msgstr "Cannot get executable path: %v" -#: commands/upload/upload.go:418 +#: commands/core/install.go:134 +msgid "Cannot install platform" +msgstr "Cannot install platform" + +#: commands/bundled_tools.go:54 +msgid "Cannot install tool %s" +msgstr "Cannot install tool %s" + +#: commands/upload/upload.go:423 msgid "Cannot perform port reset: %s" msgstr "Cannot perform port reset: %s" -#: cli/lib/search.go:169 +#: commands/core/install.go:152 +msgid "Cannot upgrade platform" +msgstr "Cannot upgrade platform" + +#: cli/lib/search.go:170 msgid "Category: %s" msgstr "Category: %s" @@ -311,6 +369,10 @@ msgstr "Category: %s" msgid "Check dependencies status for the specified library." msgstr "Check dependencies status for the specified library." +#: commands/lib/install.go:101 +msgid "Checking lib install prerequisites" +msgstr "Checking lib install prerequisites" + #: legacy/builder/builder_utils/utils.go:280 msgid "Checking previous results for {0} (result = {1}, dep = {2})" msgstr "Checking previous results for {0} (result = {1}, dep = {2})" @@ -335,6 +397,11 @@ msgstr "Comma-separated list of additional URLs for the Boards Manager." msgid "Command keeps running and prints list of connected boards whenever there is a change." msgstr "Command keeps running and prints list of connected boards whenever there is a change." +#: commands/debug/debug_info.go:118 +#: commands/upload/upload.go:358 +msgid "Compiled sketch not found in %s" +msgstr "Compiled sketch not found in %s" + #: cli/compile/compile.go:74 #: cli/compile/compile.go:75 msgid "Compiles Arduino sketches." @@ -364,11 +431,14 @@ msgstr "Config file already exists, use --overwrite to discard the existing one. msgid "Config file written to: %s" msgstr "Config file written to: %s" -#: commands/core/install.go:171 -#: commands/instances.go:847 +#: commands/instances.go:845 msgid "Configuring platform" msgstr "Configuring platform" +#: commands/core/install.go:167 +msgid "Configuring platform." +msgstr "Configuring platform." + #: cli/board/list.go:183 msgid "Connected" msgstr "Connected" @@ -382,6 +452,14 @@ msgstr "Core" msgid "Core name" msgstr "Core name" +#: commands/download.go:31 +msgid "Could not connect via HTTP" +msgstr "Could not connect via HTTP" + +#: commands/instances.go:361 +msgid "Could not create index directory" +msgstr "Could not create index directory" + #: cli/sketch/new.go:58 msgid "Could not create sketch directory: %v" msgstr "Could not create sketch directory: %v" @@ -413,18 +491,22 @@ msgstr "Creates a zip file containing all sketch files." msgid "Creates or updates the configuration file in the data directory or custom directory with the current configuration settings." msgstr "Creates or updates the configuration file in the data directory or custom directory with the current configuration settings." -#: cli/debug/debug.go:56 +#: cli/debug/debug.go:55 msgid "Debug Arduino sketches." msgstr "Debug Arduino sketches." -#: cli/debug/debug.go:57 +#: cli/debug/debug.go:56 msgid "Debug Arduino sketches. (this command opens an interactive gdb session)" msgstr "Debug Arduino sketches. (this command opens an interactive gdb session)" -#: cli/debug/debug.go:66 +#: cli/debug/debug.go:65 msgid "Debug interpreter e.g.: %s, %s, %s, %s, %s" msgstr "Debug interpreter e.g.: %s, %s, %s, %s, %s" +#: commands/debug/debug_info.go:141 +msgid "Debugging not supported for board %s" +msgstr "Debugging not supported for board %s" + #: cli/board/details.go:124 msgid "Debugging supported:" msgstr "Debugging supported:" @@ -442,7 +524,7 @@ msgstr "Delete contents of the `directories.downloads` folder, where archive fil msgid "Deletes a settings key and all its sub keys." msgstr "Deletes a settings key and all its sub keys." -#: cli/lib/search.go:177 +#: cli/lib/search.go:178 msgid "Dependencies: %s" msgstr "Dependencies: %s" @@ -462,7 +544,7 @@ msgstr "Detecting libraries used..." msgid "Detects and displays a list of boards connected to the current computer." msgstr "Detects and displays a list of boards connected to the current computer." -#: cli/debug/debug.go:67 +#: cli/debug/debug.go:66 msgid "Directory containing binaries for debug." msgstr "Directory containing binaries for debug." @@ -495,17 +577,17 @@ msgstr "Do not perform the actual upload, just log out actions" msgid "Do not terminate daemon process if the parent process dies" msgstr "Do not terminate daemon process if the parent process dies" -#: commands/instances.go:701 -#: commands/instances.go:760 -#: commands/lib/download.go:55 +#: commands/instances.go:696 +#: commands/instances.go:755 +#: commands/lib/download.go:58 msgid "Downloading %s" msgstr "Downloading %s" -#: commands/instances.go:93 +#: commands/instances.go:92 msgid "Downloading missing tool %s" msgstr "Downloading missing tool %s" -#: commands/core/install.go:88 +#: commands/core/install.go:87 msgid "Downloading packages" msgstr "Downloading packages" @@ -527,9 +609,9 @@ msgstr "Enter a path to zip file" msgid "Enter git url for libraries hosted on repositories" msgstr "Enter git url for libraries hosted on repositories" -#: commands/sketch/archive.go:106 -msgid "Error adding file to archive: %v" -msgstr "Error adding file to archive: %v" +#: commands/sketch/archive.go:105 +msgid "Error adding file to sketch archive" +msgstr "Error adding file to sketch archive" #: legacy/builder/constants/constants.go:94 msgid "Error archiving built core (caching) in {0}: {1}" @@ -540,26 +622,34 @@ msgid "Error archiving: %v" msgstr "Error archiving: %v" #: commands/sketch/archive.go:93 -msgid "Error calculating relative file path: %v" -msgstr "Error calculating relative file path: %v" +msgid "Error calculating relative file path" +msgstr "Error calculating relative file path" #: cli/cache/clean.go:46 msgid "Error cleaning caches: %v" msgstr "Error cleaning caches: %v" -#: commands/sketch/archive.go:81 -msgid "Error creating archive: %v" -msgstr "Error creating archive: %v" +#: commands/compile/compile.go:280 +msgid "Error copying output file %s" +msgstr "Error copying output file %s" #: cli/core/search.go:66 #: cli/core/update_index.go:52 -#: cli/instance/instance.go:43 +#: cli/instance/instance.go:42 #: cli/lib/search.go:57 #: cli/lib/update_index.go:45 #: cli/update/update.go:62 msgid "Error creating instance: %v" msgstr "Error creating instance: %v" +#: commands/compile/compile.go:260 +msgid "Error creating output dir" +msgstr "Error creating output dir" + +#: commands/sketch/archive.go:81 +msgid "Error creating sketch archive" +msgstr "Error creating sketch archive" + #: cli/sketch/new.go:54 #: cli/sketch/new.go:64 msgid "Error creating sketch: %v" @@ -575,13 +665,49 @@ msgstr "Error detecting boards: %v" msgid "Error downloading %[1]s: %[2]v" msgstr "Error downloading %[1]s: %[2]v" -#: commands/instances.go:779 +#: commands/instances.go:466 +#: commands/instances.go:470 +#: commands/instances.go:475 +msgid "Error downloading index '%s'" +msgstr "Error downloading index '%s'" + +#: commands/instances.go:499 +#: commands/instances.go:505 +msgid "Error downloading index signature '%s'" +msgstr "Error downloading index signature '%s'" + +#: commands/instances.go:698 +#: commands/instances.go:700 +msgid "Error downloading library" +msgstr "Error downloading library" + +#: commands/instances.go:375 +#: commands/instances.go:378 +msgid "Error downloading library_index.json.gz" +msgstr "Error downloading library_index.json.gz" + +#: commands/instances.go:385 +#: commands/instances.go:388 +msgid "Error downloading library_index.json.sig" +msgstr "Error downloading library_index.json.sig" + +#: commands/core/download.go:70 +#: commands/core/download.go:74 +#: commands/instances.go:781 +#: commands/instances.go:783 +msgid "Error downloading platform %s" +msgstr "Error downloading platform %s" + +#: commands/core/download.go:83 +#: commands/core/download.go:88 +#: commands/instances.go:774 +#: commands/instances.go:775 msgid "Error downloading tool %s" msgstr "Error downloading tool %s" -#: cli/debug/debug.go:83 -#: cli/debug/debug.go:88 -#: cli/debug/debug.go:121 +#: cli/debug/debug.go:82 +#: cli/debug/debug.go:87 +#: cli/debug/debug.go:116 msgid "Error during Debug: %v" msgstr "Error during Debug: %v" @@ -594,7 +720,7 @@ msgstr "Error during JSON encoding of the output: %v" #: cli/compile/compile.go:196 #: cli/compile/compile.go:202 #: cli/compile/compile.go:212 -#: cli/compile/compile.go:242 +#: cli/compile/compile.go:244 #: cli/upload/upload.go:96 #: cli/upload/upload.go:101 #: cli/upload/upload.go:111 @@ -602,7 +728,7 @@ msgstr "Error during JSON encoding of the output: %v" msgid "Error during Upload: %v" msgstr "Error during Upload: %v" -#: cli/compile/compile.go:254 +#: cli/compile/compile.go:256 msgid "Error during build: %v" msgstr "Error during build: %v" @@ -614,27 +740,47 @@ msgstr "Error during install: %v" msgid "Error during uninstall: %v" msgstr "Error during uninstall: %v" -#: cli/core/upgrade.go:101 +#: cli/core/upgrade.go:105 msgid "Error during upgrade: %v" msgstr "Error during upgrade: %v" -#: cli/debug/debug.go:105 -#: cli/debug/debug.go:108 +#: commands/instances.go:394 +msgid "Error extracting library_index.json.gz" +msgstr "Error extracting library_index.json.gz" + +#: commands/upload/upload.go:355 +msgid "Error finding build artifacts" +msgstr "Error finding build artifacts" + +#: cli/debug/debug.go:103 msgid "Error getting Debug info: %v" msgstr "Error getting Debug info: %v" #: commands/sketch/archive.go:59 -msgid "Error getting absolute archive path %v" -msgstr "Error getting absolute archive path %v" +msgid "Error getting absolute path of sketch archive" +msgstr "Error getting absolute path of sketch archive" #: cli/board/details.go:71 msgid "Error getting board details: %v" msgstr "Error getting board details: %v" +#: commands/board/list.go:140 +msgid "Error getting board info from Arduino Cloud" +msgstr "Error getting board info from Arduino Cloud" + +#: commands/board/list.go:205 +msgid "Error getting board list" +msgstr "Error getting board list" + #: arduino/builder/compilation_database.go:78 msgid "Error getting current directory for compilation database: %s" msgstr "Error getting current directory for compilation database: %s" +#: commands/compile/compile.go:289 +#: commands/lib/list.go:106 +msgid "Error getting information for library %s" +msgstr "Error getting information for library %s" + #: cli/lib/examples.go:69 msgid "Error getting libraries info: %v" msgstr "Error getting libraries info: %v" @@ -644,16 +790,12 @@ msgid "Error in FQBN: %s" msgstr "Error in FQBN: %s" #: cli/core/search.go:81 -#: cli/instance/instance.go:47 -#: cli/lib/search.go:70 +#: cli/instance/instance.go:46 +#: cli/lib/search.go:71 #: cli/update/update.go:87 msgid "Error initializing instance: %v" msgstr "Error initializing instance: %v" -#: commands/instances.go:806 -msgid "Error installing %s" -msgstr "Error installing %s" - #: cli/lib/install.go:130 msgid "Error installing %s: %v" msgstr "Error installing %s: %v" @@ -666,7 +808,11 @@ msgstr "Error installing Git Library: %v" msgid "Error installing Zip Library: %v" msgstr "Error installing Zip Library: %v" -#: commands/instances.go:797 +#: commands/instances.go:802 +msgid "Error installing platform %s" +msgstr "Error installing platform %s" + +#: commands/instances.go:792 msgid "Error installing tool %s" msgstr "Error installing tool %s" @@ -686,10 +832,18 @@ msgstr "Error listing platforms: %v" msgid "Error opening source code overrides data file: %v" msgstr "Error opening source code overrides data file: %v" +#: commands/compile/compile.go:270 +msgid "Error reading build directory" +msgstr "Error reading build directory" + #: configuration/configuration.go:69 msgid "Error reading config file: %v" msgstr "Error reading config file: %v" +#: commands/sketch/archive.go:75 +msgid "Error reading sketch files" +msgstr "Error reading sketch files" + #: legacy/builder/target_board_resolver.go:33 msgid "Error resolving FQBN: {0}" msgstr "Error resolving FQBN: {0}" @@ -698,11 +852,7 @@ msgstr "Error resolving FQBN: {0}" msgid "Error resolving dependencies for %[1]s: %[2]s" msgstr "Error resolving dependencies for %[1]s: %[2]s" -#: commands/lib/install.go:48 -msgid "Error resolving dependencies for %[1]s@%[2]s: %[3]s" -msgstr "Error resolving dependencies for %[1]s@%[2]s: %[3]s" - -#: cli/core/upgrade.go:61 +#: cli/core/upgrade.go:63 msgid "Error retrieving core list: %v" msgstr "Error retrieving core list: %v" @@ -711,20 +861,27 @@ msgstr "Error retrieving core list: %v" msgid "Error retrieving outdated cores and libraries: %v" msgstr "Error retrieving outdated cores and libraries: %v" -#: commands/sketch/archive.go:75 -msgid "Error retrieving sketch files: %v" -msgstr "Error retrieving sketch files: %v" +#: commands/instances.go:818 +msgid "Error rolling-back changes" +msgstr "Error rolling-back changes" -#: commands/core/install.go:153 -#: commands/instances.go:821 +#: commands/core/install.go:149 msgid "Error rolling-back changes: %s" msgstr "Error rolling-back changes: %s" +#: commands/instances.go:524 +msgid "Error saving downloaded index %s" +msgstr "Error saving downloaded index %s" + +#: commands/instances.go:528 +msgid "Error saving downloaded index signature" +msgstr "Error saving downloaded index signature" + #: cli/board/search.go:63 msgid "Error searching boards: %v" msgstr "Error searching boards: %v" -#: cli/lib/search.go:79 +#: cli/lib/search.go:80 msgid "Error searching for Library: %v" msgstr "Error searching for Library: %v" @@ -736,10 +893,25 @@ msgstr "Error searching for platforms: %v" msgid "Error serializing compilation database: %s" msgstr "Error serializing compilation database: %s" +#: commands/board/list.go:190 +#: commands/board/list.go:193 +#: commands/board/list.go:234 +msgid "Error starting board discoveries" +msgstr "Error starting board discoveries" + #: cli/lib/uninstall.go:62 msgid "Error uninstalling %[1]s: %[2]v" msgstr "Error uninstalling %[1]s: %[2]v" +#: commands/core/uninstall.go:81 +msgid "Error uninstalling platform %s" +msgstr "Error uninstalling platform %s" + +#: commands/core/uninstall.go:97 +#: commands/instances.go:834 +msgid "Error uninstalling tool %s" +msgstr "Error uninstalling tool %s" + #: cli/update/update.go:79 msgid "Error updating core and libraries index: %v" msgstr "Error updating core and libraries index: %v" @@ -755,7 +927,7 @@ msgstr "Error updating index: %v" msgid "Error updating indexes: %v" msgstr "Error updating indexes: %v" -#: cli/lib/search.go:65 +#: cli/lib/search.go:66 #: cli/lib/update_index.go:62 msgid "Error updating library index: %v" msgstr "Error updating library index: %v" @@ -765,8 +937,8 @@ msgstr "Error updating library index: %v" msgid "Error upgrading libraries: %v" msgstr "Error upgrading libraries: %v" -#: commands/core/install.go:148 -#: commands/instances.go:816 +#: commands/core/install.go:144 +#: commands/instances.go:813 msgid "Error upgrading platform: %s" msgstr "Error upgrading platform: %s" @@ -774,6 +946,11 @@ msgstr "Error upgrading platform: %s" msgid "Error upgrading: %v" msgstr "Error upgrading: %v" +#: commands/instances.go:399 +#: commands/instances.go:509 +msgid "Error verifying signature" +msgstr "Error verifying signature" + #: legacy/builder/constants/constants.go:104 msgid "Error while detecting libraries included by {0}" msgstr "Error while detecting libraries included by {0}" @@ -787,6 +964,14 @@ msgstr "Error while determining sketch size: %s" msgid "Error writing compilation database: %s" msgstr "Error writing compilation database: %s" +#: commands/instances.go:408 +msgid "Error writing library_index.json" +msgstr "Error writing library_index.json" + +#: commands/instances.go:411 +msgid "Error writing library_index.json.sig" +msgstr "Error writing library_index.json.sig" + #: cli/completion/completion.go:51 msgid "Error: command description is not supported by %v" msgstr "Error: command description is not supported by %v" @@ -807,10 +992,15 @@ msgstr "Examples for library %s" msgid "Examples:" msgstr "Examples:" -#: cli/debug/debug.go:140 +#: cli/debug/debug.go:135 msgid "Executable to debug" msgstr "Executable to debug" +#: commands/debug/debug_info.go:121 +#: commands/upload/upload.go:361 +msgid "Expected compiled sketch in directory %s, but is a file instead" +msgstr "Expected compiled sketch in directory %s, but is a file instead" + #: cli/board/attach.go:35 #: cli/board/details.go:41 #: cli/board/list.go:87 @@ -824,6 +1014,26 @@ msgstr "FQBN" msgid "FQBN:" msgstr "FQBN:" +#: commands/upload/upload.go:454 +msgid "Failed chip erase" +msgstr "Failed chip erase" + +#: commands/upload/upload.go:461 +msgid "Failed programming" +msgstr "Failed programming" + +#: commands/upload/upload.go:457 +msgid "Failed to burn bootloader" +msgstr "Failed to burn bootloader" + +#: commands/instances.go:122 +msgid "Failed to create data directory" +msgstr "Failed to create data directory" + +#: commands/instances.go:112 +msgid "Failed to create downloads directory" +msgstr "Failed to create downloads directory" + #: cli/daemon/daemon.go:114 msgid "Failed to listen on TCP port: %[1]s. %[2]s is an invalid port." msgstr "Failed to listen on TCP port: %[1]s. %[2]s is an invalid port." @@ -844,6 +1054,10 @@ msgstr "Failed to listen on TCP port: %s. Address already in use." msgid "Failed to read: {0}" msgstr "Failed to read: {0}" +#: commands/upload/upload.go:465 +msgid "Failed uploading" +msgstr "Failed uploading" + #: cli/board/details.go:166 msgid "File:" msgstr "File:" @@ -867,19 +1081,23 @@ msgstr "Force skip of post-install scripts (if the CLI is running interactively) #: cli/board/details.go:50 #: cli/burnbootloader/burnbootloader.go:53 #: cli/compile/compile.go:85 -#: cli/debug/debug.go:63 +#: cli/debug/debug.go:62 #: cli/upload/upload.go:58 msgid "Fully Qualified Board Name, e.g.: arduino:avr:uno" msgstr "Fully Qualified Board Name, e.g.: arduino:avr:uno" -#: cli/debug/debug.go:154 +#: cli/debug/debug.go:149 msgid "GDB Server path" msgstr "GDB Server path" -#: cli/debug/debug.go:153 +#: cli/debug/debug.go:148 msgid "GDB Server type" msgstr "GDB Server type" +#: commands/debug/debug.go:172 +msgid "GDB server '%s' is not supported" +msgstr "GDB server '%s' is not supported" + #: cli/generatedocs/generatedocs.go:38 #: cli/generatedocs/generatedocs.go:39 msgid "Generates bash completion and command manpages." @@ -945,19 +1163,11 @@ msgstr "Includes %s directory in the archive." msgid "Installed" msgstr "Installed" -#: commands/instances.go:726 -#: commands/lib/install.go:108 +#: commands/instances.go:721 +#: commands/lib/install.go:112 msgid "Installed %s" msgstr "Installed %s" -#: commands/lib/install.go:118 -msgid "Installed Archived Library" -msgstr "Installed Archived Library" - -#: commands/lib/install.go:128 -msgid "Installed Library from Git URL" -msgstr "Installed Library from Git URL" - #: cli/outdated/outdated.go:62 #: cli/outdated/outdated.go:72 #: cli/update/update.go:99 @@ -966,12 +1176,15 @@ msgid "Installed version" msgstr "Installed version" #: commands/bundled_tools.go:50 -#: commands/core/install.go:113 -#: commands/instances.go:709 -#: commands/lib/install.go:88 +#: commands/instances.go:704 +#: commands/lib/install.go:92 msgid "Installing %s" msgstr "Installing %s" +#: commands/core/install.go:110 +msgid "Installing platform %s" +msgstr "Installing platform %s" + #: cli/core/install.go:38 #: cli/core/install.go:39 msgid "Installs one or more cores and corresponding tool dependencies." @@ -986,18 +1199,34 @@ msgstr "Installs one or more specified libraries into the system." msgid "Internal error in cache" msgstr "Internal error in cache" +#: commands/errors.go:218 +msgid "Invalid '%[1]s' property: %[2]s" +msgstr "Invalid '%[1]s' property: %[2]s" + #: cli/cli.go:224 msgid "Invalid Call : should show Help, but it is available only in TEXT mode." msgstr "Invalid Call : should show Help, but it is available only in TEXT mode." -#: commands/instances.go:194 +#: commands/board/attach.go:65 +msgid "Invalid Device URL format" +msgstr "Invalid Device URL format" + +#: commands/errors.go:57 +msgid "Invalid FQBN" +msgstr "Invalid FQBN" + +#: commands/errors.go:75 +msgid "Invalid URL" +msgstr "Invalid URL" + +#: commands/instances.go:191 msgid "Invalid additional URL: %v" msgstr "Invalid additional URL: %v" #: cli/core/download.go:55 #: cli/core/install.go:92 #: cli/core/uninstall.go:51 -#: cli/core/upgrade.go:79 +#: cli/core/upgrade.go:81 #: cli/lib/download.go:50 #: cli/lib/uninstall.go:51 msgid "Invalid argument passed: %v" @@ -1007,18 +1236,26 @@ msgstr "Invalid argument passed: %v" msgid "Invalid data size regexp: %s" msgstr "Invalid data size regexp: %s" +#: commands/board/attach.go:75 +msgid "Invalid device port type provided" +msgstr "Invalid device port type provided" + #: legacy/builder/phases/sizer.go:166 msgid "Invalid eeprom size regexp: %s" msgstr "Invalid eeprom size regexp: %s" -#: commands/instances.go:175 -msgid "Invalid instance ID" -msgstr "Invalid instance ID" +#: commands/errors.go:43 +msgid "Invalid instance" +msgstr "Invalid instance" -#: cli/core/upgrade.go:85 +#: cli/core/upgrade.go:87 msgid "Invalid item %s" msgstr "Invalid item %s" +#: commands/errors.go:93 +msgid "Invalid library" +msgstr "Invalid library" + #: httpclient/httpclient_config.go:44 msgid "Invalid network.proxy '%[1]s': %[2]s" msgstr "Invalid network.proxy '%[1]s': %[2]s" @@ -1031,6 +1268,11 @@ msgstr "Invalid option for --log-level: %s" msgid "Invalid output format: %s" msgstr "Invalid output format: %s" +#: commands/instances.go:442 +#: commands/instances.go:516 +msgid "Invalid package index in %s" +msgstr "Invalid package index in %s" + #: cli/core/uninstall.go:57 msgid "Invalid parameter %s: version not allowed" msgstr "Invalid parameter %s: version not allowed" @@ -1043,6 +1285,10 @@ msgstr "Invalid pid value: '%s'" msgid "Invalid size regexp: %s" msgstr "Invalid size regexp: %s" +#: commands/errors.go:111 +msgid "Invalid version" +msgstr "Invalid version" + #: commands/board/list.go:48 msgid "Invalid vid value: '%s'" msgstr "Invalid vid value: '%s'" @@ -1075,10 +1321,23 @@ msgstr "Latest" msgid "Library %s is not installed" msgstr "Library %s is not installed" +#: commands/errors.go:266 +msgid "Library '%s' not found" +msgstr "Library '%s' not found" + #: legacy/builder/constants/constants.go:109 msgid "Library can't use both '%[1]s' and '%[2]s' folders. Double check {0}" msgstr "Library can't use both '%[1]s' and '%[2]s' folders. Double check {0}" +#: commands/errors.go:369 +msgid "Library install failed" +msgstr "Library install failed" + +#: commands/lib/install.go:122 +#: commands/lib/install.go:132 +msgid "Library installed" +msgstr "Library installed" + #: cli/outdated/outdated.go:72 #: cli/update/update.go:109 msgid "Library name" @@ -1088,7 +1347,7 @@ msgstr "Library name" msgid "Library {0} has been declared precompiled:" msgstr "Library {0} has been declared precompiled:" -#: cli/lib/search.go:167 +#: cli/lib/search.go:168 msgid "License: %s" msgstr "License: %s" @@ -1140,13 +1399,13 @@ msgstr "Lists all connected boards." msgid "Lists cores and libraries that can be upgraded" msgstr "Lists cores and libraries that can be upgraded" -#: commands/instances.go:208 -#: commands/instances.go:219 -#: commands/instances.go:320 +#: commands/instances.go:205 +#: commands/instances.go:216 +#: commands/instances.go:317 msgid "Loading index file: %v" msgstr "Loading index file: %v" -#: commands/instances.go:329 +#: commands/instances.go:326 msgid "Loading libraries: %v" msgstr "Loading libraries: %v" @@ -1162,7 +1421,7 @@ msgstr "Looking for recipes like {0}*{1}" msgid "Low memory available, stability problems may occur." msgstr "Low memory available, stability problems may occur." -#: cli/lib/search.go:162 +#: cli/lib/search.go:163 msgid "Maintainer: %s" msgstr "Maintainer: %s" @@ -1178,10 +1437,26 @@ msgstr "Messages with this level and above will be logged. Valid levels are: %s, msgid "Missing '{0}' from library in {1}" msgstr "Missing '{0}' from library in {1}" +#: commands/errors.go:127 +msgid "Missing FQBN (Fully Qualified Board Name)" +msgstr "Missing FQBN (Fully Qualified Board Name)" + +#: commands/errors.go:157 +msgid "Missing port protocol" +msgstr "Missing port protocol" + +#: commands/errors.go:169 +msgid "Missing programmer" +msgstr "Missing programmer" + #: legacy/builder/phases/sizer.go:154 msgid "Missing size regexp" msgstr "Missing size regexp" +#: commands/errors.go:318 +msgid "Missing sketch path" +msgstr "Missing sketch path" + #: legacy/builder/constants/constants.go:106 msgid "Multiple libraries were found for \"{0}\"" msgstr "Multiple libraries were found for \"{0}\"" @@ -1194,7 +1469,7 @@ msgstr "Multiple libraries were found for \"{0}\"" msgid "Name" msgstr "Name" -#: cli/lib/search.go:141 +#: cli/lib/search.go:142 msgid "Name: \"%s\"" msgstr "Name: \"%s\"" @@ -1221,11 +1496,11 @@ msgstr "No libraries found." msgid "No libraries installed." msgstr "No libraries installed." -#: cli/lib/search.go:125 +#: cli/lib/search.go:126 msgid "No libraries matching your search." msgstr "No libraries matching your search." -#: cli/lib/search.go:136 +#: cli/lib/search.go:137 msgid "No libraries matching your search.\n" "Did you mean...\n" "" @@ -1237,14 +1512,22 @@ msgstr "No libraries matching your search.\n" msgid "No platforms matching your search." msgstr "No platforms matching your search." +#: commands/board/attach.go:91 +msgid "No supported board found at %s" +msgstr "No supported board found at %s" + #: cli/lib/list.go:115 msgid "No updates available." msgstr "No updates available." -#: commands/upload/upload.go:407 +#: commands/upload/upload.go:412 msgid "No upload port found, using %s as fallback" msgstr "No upload port found, using %s as fallback" +#: commands/errors.go:285 +msgid "No valid dependencies solution found" +msgstr "No valid dependencies solution found" + #: legacy/builder/constants/constants.go:125 msgid "Not enough memory; see %s for tips on reducing your footprint." msgstr "Not enough memory; see %s for tips on reducing your footprint." @@ -1316,7 +1599,7 @@ msgstr "Overwrite existing config file." #: cli/core/download.go:36 #: cli/core/install.go:37 #: cli/core/uninstall.go:36 -#: cli/core/upgrade.go:36 +#: cli/core/upgrade.go:38 msgid "PACKAGER" msgstr "PACKAGER" @@ -1340,7 +1623,7 @@ msgstr "Package online help:" msgid "Package website:" msgstr "Package website:" -#: cli/lib/search.go:164 +#: cli/lib/search.go:165 msgid "Paragraph: %s" msgstr "Paragraph: %s" @@ -1352,17 +1635,29 @@ msgstr "Path to the file where logs will be written." msgid "Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS." msgstr "Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS." -#: commands/upload/upload.go:386 +#: commands/upload/upload.go:391 msgid "Performing 1200-bps touch reset on serial port %s" msgstr "Performing 1200-bps touch reset on serial port %s" -#: commands/core/install.go:74 +#: commands/core/install.go:73 msgid "Platform %s already installed" msgstr "Platform %s already installed" -#: cli/core/upgrade.go:99 -msgid "Platform %s is already at the latest version" -msgstr "Platform %s is already at the latest version" +#: commands/core/install.go:177 +msgid "Platform %s installed" +msgstr "Platform %s installed" + +#: commands/core/uninstall.go:85 +msgid "Platform %s uninstalled" +msgstr "Platform %s uninstalled" + +#: commands/errors.go:303 +msgid "Platform '%s' is already at the latest version" +msgstr "Platform '%s' is already at the latest version" + +#: commands/errors.go:247 +msgid "Platform '%s' not found" +msgstr "Platform '%s' not found" #: cli/board/search.go:86 msgid "Platform ID" @@ -1430,11 +1725,15 @@ msgstr "Prints the current configuration" msgid "Prints the current configuration." msgstr "Prints the current configuration." +#: commands/errors.go:199 +msgid "Programmer '%s' not found" +msgstr "Programmer '%s' not found" + #: cli/board/details.go:93 msgid "Programmer name" msgstr "Programmer name" -#: cli/debug/debug.go:65 +#: cli/debug/debug.go:64 msgid "Programmer to use for debugging" msgstr "Programmer to use for debugging" @@ -1446,11 +1745,15 @@ msgstr "Programmers:" msgid "Progress {0}" msgstr "Progress {0}" +#: commands/errors.go:232 +msgid "Property '%s' is undefined" +msgstr "Property '%s' is undefined" + #: cli/board/list.go:125 msgid "Protocol" msgstr "Protocol" -#: cli/lib/search.go:174 +#: cli/lib/search.go:175 msgid "Provides includes: %s" msgstr "Provides includes: %s" @@ -1459,8 +1762,8 @@ msgstr "Provides includes: %s" msgid "Removes one or more values from a setting." msgstr "Removes one or more values from a setting." -#: commands/instances.go:719 -#: commands/lib/install.go:101 +#: commands/instances.go:714 +#: commands/lib/install.go:105 msgid "Replacing %[1]s with %[2]s" msgstr "Replacing %[1]s with %[2]s" @@ -1508,14 +1811,18 @@ msgstr "Searches for one or more libraries data." msgid "Selected board depends on '{0}' core (not installed)." msgstr "Selected board depends on '{0}' core (not installed)." -#: commands/board/attach.go:109 +#: commands/board/attach.go:108 msgid "Selected fqbn: %s" msgstr "Selected fqbn: %s" -#: cli/lib/search.go:163 +#: cli/lib/search.go:164 msgid "Sentence: %s" msgstr "Sentence: %s" +#: commands/download.go:62 +msgid "Server responded with: %s" +msgstr "Server responded with: %s" + #: cli/config/set.go:32 #: cli/config/set.go:33 msgid "Sets a setting value." @@ -1569,7 +1876,7 @@ msgstr "Show library names only." msgid "Show list of available programmers" msgstr "Show list of available programmers" -#: cli/debug/debug.go:68 +#: cli/debug/debug.go:67 msgid "Show metadata about the debug session instead of starting the debugger." msgstr "Show metadata about the debug session instead of starting the debugger." @@ -1644,7 +1951,7 @@ msgstr "Sketches with .pde extension are deprecated, please rename the following msgid "Skip linking of final executable." msgstr "Skip linking of final executable." -#: commands/upload/upload.go:379 +#: commands/upload/upload.go:384 msgid "Skipping 1200-bps touch reset: no serial port selected!" msgstr "Skipping 1200-bps touch reset: no serial port selected!" @@ -1660,11 +1967,14 @@ msgstr "Skipping compile of: {0}" msgid "Skipping dependencies detection for precompiled library {0}" msgstr "Skipping dependencies detection for precompiled library {0}" -#: commands/core/install.go:177 -#: commands/instances.go:853 +#: commands/instances.go:851 msgid "Skipping platform configuration" msgstr "Skipping platform configuration" +#: commands/core/install.go:173 +msgid "Skipping platform configuration." +msgstr "Skipping platform configuration." + #: legacy/builder/recipe_runner.go:58 msgid "Skipping: {0}" msgstr "Skipping: {0}" @@ -1728,24 +2038,32 @@ msgstr "This commands shows a list of installed cores and/or libraries\n" "that can be upgraded. If nothing needs to be updated the output is empty." #: commands/bundled_tools.go:45 -#: commands/core/install.go:81 -#: commands/instances.go:770 +#: commands/core/install.go:80 +#: commands/instances.go:765 msgid "Tool %s already installed" msgstr "Tool %s already installed" -#: cli/debug/debug.go:148 +#: commands/core/uninstall.go:101 +msgid "Tool %s uninstalled" +msgstr "Tool %s uninstalled" + +#: commands/debug/debug.go:133 +msgid "Toolchain '%s' is not supported" +msgstr "Toolchain '%s' is not supported" + +#: cli/debug/debug.go:143 msgid "Toolchain custom configurations" msgstr "Toolchain custom configurations" -#: cli/debug/debug.go:142 +#: cli/debug/debug.go:137 msgid "Toolchain path" msgstr "Toolchain path" -#: cli/debug/debug.go:143 +#: cli/debug/debug.go:138 msgid "Toolchain prefix" msgstr "Toolchain prefix" -#: cli/debug/debug.go:141 +#: cli/debug/debug.go:136 msgid "Toolchain type" msgstr "Toolchain type" @@ -1762,7 +2080,7 @@ msgstr "Turns on verbose mode." msgid "Type" msgstr "Type" -#: cli/lib/search.go:171 +#: cli/lib/search.go:172 msgid "Types: %s" msgstr "Types: %s" @@ -1795,16 +2113,19 @@ msgstr "Unable to get user home dir: %v" msgid "Unable to open file for logging: %s" msgstr "Unable to open file for logging: %s" -#: commands/core/uninstall.go:82 +#: commands/core/uninstall.go:77 #: commands/lib/uninstall.go:39 msgid "Uninstalling %s" msgstr "Uninstalling %s" -#: commands/core/uninstall.go:98 -#: commands/instances.go:832 +#: commands/core/uninstall.go:93 msgid "Uninstalling %s, tool is no more required" msgstr "Uninstalling %s, tool is no more required" +#: commands/instances.go:830 +msgid "Uninstalling %s: tool is no more required" +msgstr "Uninstalling %s: tool is no more required" + #: cli/core/uninstall.go:37 #: cli/core/uninstall.go:38 msgid "Uninstalls one or more cores and corresponding tool dependencies if no longer used." @@ -1819,6 +2140,10 @@ msgstr "Uninstalls one or more libraries." msgid "Unknown" msgstr "Unknown" +#: commands/errors.go:141 +msgid "Unknown FQBN" +msgstr "Unknown FQBN" + #: legacy/builder/constants/constants.go:129 msgid "Unknown sketch file extension: {0}" msgstr "Unknown sketch file extension: {0}" @@ -1847,24 +2172,28 @@ msgstr "Updates the libraries index to the latest version." msgid "Updates the libraries index." msgstr "Updates the libraries index." -#: commands/instances.go:792 -msgid "Updating %s" -msgstr "Updating %s" - -#: commands/instances.go:450 -#: commands/instances.go:476 -#: commands/instances.go:506 +#: commands/instances.go:447 +#: commands/instances.go:473 +#: commands/instances.go:503 msgid "Updating index: %s" msgstr "Updating index: %s" -#: commands/instances.go:377 +#: commands/instances.go:374 msgid "Updating index: library_index.json.gz" msgstr "Updating index: library_index.json.gz" -#: commands/instances.go:387 +#: commands/instances.go:384 msgid "Updating index: library_index.json.sig" msgstr "Updating index: library_index.json.sig" +#: commands/instances.go:787 +msgid "Updating platform %s" +msgstr "Updating platform %s" + +#: commands/core/upgrade.go:54 +msgid "Upgrade doesn't accept parameters with version" +msgstr "Upgrade doesn't accept parameters with version" + #: cli/upgrade/upgrade.go:40 msgid "Upgrades installed cores and libraries to latest version." msgstr "Upgrades installed cores and libraries to latest version." @@ -1877,14 +2206,14 @@ msgstr "Upgrades installed cores and libraries." msgid "Upgrades installed libraries." msgstr "Upgrades installed libraries." -#: cli/core/upgrade.go:37 -#: cli/core/upgrade.go:38 +#: cli/core/upgrade.go:39 +#: cli/core/upgrade.go:40 msgid "Upgrades one or all installed platforms to the latest version." msgstr "Upgrades one or all installed platforms to the latest version." -#: commands/core/install.go:117 -msgid "Upgrading %[1]s with %[2]s" -msgstr "Upgrading %[1]s with %[2]s" +#: commands/core/install.go:114 +msgid "Upgrading platform %[1]s with %[2]s" +msgstr "Upgrading platform %[1]s with %[2]s" #: cli/upload/upload.go:50 msgid "Upload Arduino sketches." @@ -1898,7 +2227,7 @@ msgstr "Upload Arduino sketches. This does NOT compile the sketch prior to uploa msgid "Upload port address, e.g.: COM3 or /dev/ttyACM2" msgstr "Upload port address, e.g.: COM3 or /dev/ttyACM2" -#: commands/upload/upload.go:404 +#: commands/upload/upload.go:409 msgid "Upload port found on %s" msgstr "Upload port found on %s" @@ -1995,10 +2324,14 @@ msgstr "Verify uploaded binary after the upload." msgid "Version" msgstr "Version" -#: cli/lib/search.go:172 +#: cli/lib/search.go:173 msgid "Versions: %s" msgstr "Versions: %s" +#: commands/core/install.go:169 +msgid "WARNING cannot configure platform: %s" +msgstr "WARNING cannot configure platform: %s" + #: legacy/builder/constants/constants.go:136 msgid "WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'" msgstr "WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'" @@ -2007,8 +2340,7 @@ msgstr "WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'" msgid "WARNING: Spurious {0} folder in '{1}' library" msgstr "WARNING: Spurious {0} folder in '{1}' library" -#: commands/core/install.go:173 -#: commands/instances.go:849 +#: commands/instances.go:847 msgid "WARNING: cannot run post install: %s" msgstr "WARNING: cannot run post install: %s" @@ -2016,7 +2348,7 @@ msgstr "WARNING: cannot run post install: %s" msgid "WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s)." msgstr "WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s)." -#: commands/upload/upload.go:393 +#: commands/upload/upload.go:398 msgid "Waiting for upload port..." msgstr "Waiting for upload port..." @@ -2028,11 +2360,11 @@ msgstr "Warning: Board {0}:{1}:{2} doesn''t define a %s preference. Auto-set to: msgid "Warning: platform.txt from core '{0}' contains deprecated {1}, automatically converted to {2}. Consider upgrading this core." msgstr "Warning: platform.txt from core '{0}' contains deprecated {1}, automatically converted to {2}. Consider upgrading this core." -#: commands/upload/upload.go:288 +#: commands/upload/upload.go:293 msgid "Warning: tool '%s' is not installed. It might not be available for your OS." msgstr "Warning: tool '%s' is not installed. It might not be available for your OS." -#: cli/lib/search.go:165 +#: cli/lib/search.go:166 msgid "Website: %s" msgstr "Website: %s" @@ -2057,14 +2389,6 @@ msgstr "Writing config file: %v" msgid "[DEPRECATED] %s" msgstr "[DEPRECATED] %s" -#: commands/upload/upload.go:302 -msgid "a programmer is required to upload for this board" -msgstr "a programmer is required to upload for this board" - -#: commands/sketch/archive.go:70 -msgid "archive already exists" -msgstr "archive already exists" - #: arduino/resources/checksums.go:80 msgid "archive hash differs from hash in index" msgstr "archive hash differs from hash in index" @@ -2081,11 +2405,11 @@ msgstr "archivePath" msgid "arduino-preprocessor pattern is missing" msgstr "arduino-preprocessor pattern is missing" -#: commands/upload/upload.go:553 +#: commands/upload/upload.go:558 msgid "autodetect build artifact: %s" msgstr "autodetect build artifact: %s" -#: commands/upload/upload.go:538 +#: commands/upload/upload.go:543 msgid "binary file not found in %s" msgstr "binary file not found in %s" @@ -2102,10 +2426,6 @@ msgstr "board not found" msgid "boardname" msgstr "boardname" -#: commands/upload/upload.go:452 -msgid "burn bootloader error: %s" -msgstr "burn bootloader error: %s" - #: arduino/discovery/discovery.go:297 #: arduino/discovery/discovery.go:318 #: arduino/discovery/discovery.go:338 @@ -2115,22 +2435,10 @@ msgstr "burn bootloader error: %s" msgid "calling %[1]s: %[2]w" msgstr "calling %[1]s: %[2]w" -#: commands/instances.go:525 -msgid "can't create data directory %[1]s: %[2]s" -msgstr "can't create data directory %[1]s: %[2]s" - -#: commands/core/install.go:130 -msgid "can't find dependencies for platform %[1]s: %[2]w" -msgstr "can't find dependencies for platform %[1]s: %[2]w" - #: arduino/cores/status.go:123 msgid "can't find latest release of %s" msgstr "can't find latest release of %s" -#: commands/core/list.go:64 -msgid "can't find latest release of core %s" -msgstr "can't find latest release of core %s" - #: arduino/sketch/sketch.go:101 msgid "can't find main Sketch file in %s" msgstr "can't find main Sketch file in %s" @@ -2147,40 +2455,15 @@ msgstr "can't retrieve standard error stream: %s" msgid "can't retrieve standard output stream: %s" msgstr "can't retrieve standard output stream: %s" -#: commands/compile/compile.go:181 -msgid "cannot create build cache directory: %s" -msgstr "cannot create build cache directory: %s" - -#: commands/compile/compile.go:151 -msgid "cannot create build directory: %s" -msgstr "cannot create build directory: %s" - -#: commands/upload/upload.go:495 -#: commands/upload/upload.go:502 +#: commands/upload/upload.go:500 +#: commands/upload/upload.go:507 msgid "cannot execute upload tool: %s" msgstr "cannot execute upload tool: %s" -#: commands/board/attach.go:107 -msgid "cannot export sketch metadata: %s" -msgstr "cannot export sketch metadata: %s" - -#: commands/upload/upload.go:87 -msgid "cannot find tool: undefined '%s' property" -msgstr "cannot find tool: undefined '%s' property" - -#: commands/instances.go:715 -#: commands/lib/install.go:97 -msgid "checking lib install prerequisites: %s" -msgstr "checking lib install prerequisites: %s" - #: arduino/resources/install.go:39 msgid "checking local archive integrity" msgstr "checking local archive integrity" -#: commands/upload/upload.go:449 -msgid "chip erase error: %s" -msgstr "chip erase error: %s" - #: legacy/builder/wipeout_build_path_if_build_options_changed.go:85 #: legacy/builder/wipeout_build_path_if_build_options_changed.go:89 msgid "cleaning build path" @@ -2223,25 +2506,11 @@ msgstr "communication out of sync, expected 'start_sync', received '%s'" msgid "communication out of sync, expected 'stop', received '%s'" msgstr "communication out of sync, expected 'stop', received '%s'" -#: commands/debug/debug_info.go:123 -#: commands/upload/upload.go:353 -msgid "compiled sketch not found in %s" -msgstr "compiled sketch not found in %s" - #: arduino/resources/checksums.go:76 msgid "computing hash: %s" msgstr "computing hash: %s" -#: commands/compile/compile.go:282 -#: commands/lib/list.go:108 -msgid "converting library %[1]s to rpc struct: %[2]w" -msgstr "converting library %[1]s to rpc struct: %[2]w" - -#: commands/compile/compile.go:273 -msgid "copying output file %s" -msgstr "copying output file %s" - -#: commands/upload/upload.go:610 +#: commands/upload/upload.go:615 msgid "could not find a valid build artifact" msgstr "could not find a valid build artifact" @@ -2253,38 +2522,20 @@ msgstr "creating discovery: %s" msgid "creating installed.json in %[1]s: %[2]s" msgstr "creating installed.json in %[1]s: %[2]s" -#: commands/compile/compile.go:253 -msgid "creating output dir" -msgstr "creating output dir" - #: arduino/resources/install.go:44 #: arduino/resources/install.go:48 msgid "creating temp dir for extraction: %s" msgstr "creating temp dir for extraction: %s" -#: commands/instances.go:459 -#: commands/instances.go:461 -msgid "creating temp file for index download: %s" -msgstr "creating temp file for index download: %s" - -#: commands/instances.go:492 -#: commands/instances.go:494 -msgid "creating temp file for index signature download: %s" -msgstr "creating temp file for index signature download: %s" - #: legacy/builder/phases/sizer.go:116 msgid "data section exceeds available space in board" msgstr "data section exceeds available space in board" -#: commands/debug/debug_info.go:146 -msgid "debugging not supported for board %s" -msgstr "debugging not supported for board %s" - #: arduino/sketch/sketch.go:207 msgid "decoding sketch metadata: %s" msgstr "decoding sketch metadata: %s" -#: commands/lib/resolve_deps.go:51 +#: commands/lib/resolve_deps.go:54 msgid "dependency '%s' is not available" msgstr "dependency '%s' is not available" @@ -2324,56 +2575,22 @@ msgstr "download a specific version (in this case 1.6.9)." msgid "download the latest version of Arduino SAMD core." msgstr "download the latest version of Arduino SAMD core." -#: commands/instances.go:95 +#: commands/instances.go:94 msgid "downloading %[1]s tool: %[2]s" msgstr "downloading %[1]s tool: %[2]s" -#: commands/instances.go:469 -#: commands/instances.go:473 -#: commands/instances.go:478 -msgid "downloading index %[1]s: %[2]s" -msgstr "downloading index %[1]s: %[2]s" - -#: commands/instances.go:508 -msgid "downloading index signature %[1]s: %[2]s" -msgstr "downloading index signature %[1]s: %[2]s" - -#: commands/lib/install.go:72 -msgid "downloading library: %s" -msgstr "downloading library: %s" - -#: commands/instances.go:378 -msgid "downloading library_index.json.gz" -msgstr "downloading library_index.json.gz" - -#: commands/instances.go:388 -msgid "downloading library_index.json.sig" -msgstr "downloading library_index.json.sig" - -#: commands/core/download.go:61 -msgid "downloading tool %[1]s: %[2]s" -msgstr "downloading tool %[1]s: %[2]s" +#: arduino/cores/fqbn.go:48 +msgid "empty board identifier" +msgstr "empty board identifier" #: arduino/sketch/sketch.go:196 msgid "encoding sketch metadata: %s" msgstr "encoding sketch metadata: %s" -#: commands/board/list.go:140 -msgid "error getting board info from Arduino Cloud" -msgstr "error getting board info from Arduino Cloud" - -#: commands/instances.go:867 -msgid "error loading sketch %[1]v: %[2]v" -msgstr "error loading sketch %[1]v: %[2]v" - #: arduino/monitors/serial.go:44 msgid "error opening serial monitor" msgstr "error opening serial monitor" -#: commands/debug/debug_info.go:65 -msgid "error parsing FQBN" -msgstr "error parsing FQBN" - #: cli/config/set.go:68 msgid "error parsing value: %v" msgstr "error parsing value: %v" @@ -2386,19 +2603,10 @@ msgstr "error processing response from server" msgid "error querying Arduino Cloud Api" msgstr "error querying Arduino Cloud Api" -#: commands/debug/debug_info.go:71 -msgid "error resolving FQBN" -msgstr "error resolving FQBN" - #: cli/upload/upload.go:72 msgid "error: %s and %s flags cannot be used together" msgstr "error: %s and %s flags cannot be used together" -#: commands/debug/debug_info.go:126 -#: commands/upload/upload.go:356 -msgid "expected compiled sketch in directory %s, but is a file instead" -msgstr "expected compiled sketch in directory %s, but is a file instead" - #: arduino/resources/install.go:67 msgid "extracting archive: %s" msgstr "extracting archive: %s" @@ -2427,15 +2635,6 @@ msgstr "files in archive must be placed in a subdirectory" msgid "find abs path: %s" msgstr "find abs path: %s" -#: commands/core/download.go:50 -msgid "find platform dependencies: %s" -msgstr "find platform dependencies: %s" - -#: commands/core/install.go:49 -#: commands/core/uninstall.go:56 -msgid "finding platform dependencies: %s" -msgstr "finding platform dependencies: %s" - #: commands/daemon/monitor.go:45 msgid "first message must contain monitor configuration, not data" msgstr "first message must contain monitor configuration, not data" @@ -2467,10 +2666,6 @@ msgstr "for the latest version." msgid "for the specific version." msgstr "for the specific version." -#: arduino/libraries/libraries.go:114 -msgid "gathering library headers: %w" -msgstr "gathering library headers: %w" - #: inventory/inventory.go:67 msgid "generating installation.id: %w" msgstr "generating installation.id: %w" @@ -2515,23 +2710,11 @@ msgstr "getting tool dependencies for platform %[1]s: %[2]s" msgid "importing sketch metadata: %s" msgstr "importing sketch metadata: %s" -#: commands/compile/compile.go:115 -#: commands/upload/programmers_list.go:37 -#: commands/upload/programmers_list.go:43 -#: commands/upload/upload.go:194 -#: commands/upload/upload.go:201 -msgid "incorrect FQBN: %s" -msgstr "incorrect FQBN: %s" - -#: commands/instances.go:516 -msgid "index has an invalid signature" -msgstr "index has an invalid signature" - #: arduino/libraries/librariesmanager/install.go:86 msgid "install directory not set" msgstr "install directory not set" -#: commands/instances.go:99 +#: commands/instances.go:98 msgid "installing %[1]s tool: %[2]s" msgstr "installing %[1]s tool: %[2]s" @@ -2539,10 +2722,6 @@ msgstr "installing %[1]s tool: %[2]s" msgid "installing platform %[1]s: %[2]s" msgstr "installing platform %[1]s: %[2]s" -#: commands/bundled_tools.go:54 -msgid "installing tool %[1]s: %[2]s" -msgstr "installing tool %[1]s: %[2]s" - #: arduino/discovery/discovery.go:184 msgid "invalid 'add' message: missing port" msgstr "invalid 'add' message: missing port" @@ -2551,21 +2730,14 @@ msgstr "invalid 'add' message: missing port" msgid "invalid 'remove' message: missing port" msgstr "invalid 'remove' message: missing port" -#: commands/upload/upload.go:254 -msgid "invalid 'upload.tool' property: %s" -msgstr "invalid 'upload.tool' property: %s" - -#: commands/board/attach.go:66 -msgid "invalid Device URL format: %s" -msgstr "invalid Device URL format: %s" - #: arduino/resources/checksums.go:45 msgid "invalid checksum format: %s" msgstr "invalid checksum format: %s" -#: commands/board/attach.go:76 -msgid "invalid device port type provided" -msgstr "invalid device port type provided" +#: arduino/cores/fqbn.go:54 +#: arduino/cores/fqbn.go:59 +msgid "invalid config option: %s" +msgstr "invalid config option: %s" #: cli/arguments/reference.go:82 msgid "invalid empty core architecture '%s'" @@ -2599,52 +2771,14 @@ msgstr "invalid empty library version: %s" msgid "invalid empty option found" msgstr "invalid empty option found" -#: arduino/cores/fqbn.go:54 -#: arduino/cores/fqbn.go:59 -msgid "invalid fqbn config: %s" -msgstr "invalid fqbn config: %s" - -#: arduino/cores/fqbn.go:48 -msgid "invalid fqbn: empty board identifier" -msgstr "invalid fqbn: empty board identifier" - #: arduino/libraries/librariesmanager/install.go:250 msgid "invalid git url" msgstr "invalid git url" -#: commands/instances.go:344 -#: commands/instances.go:356 -#: commands/instances.go:425 -#: commands/instances.go:687 -#: commands/instances.go:732 -msgid "invalid handle" -msgstr "invalid handle" - #: arduino/resources/checksums.go:49 msgid "invalid hash '%[1]s': %[2]s" msgstr "invalid hash '%[1]s': %[2]s" -#: commands/board/attach.go:42 -#: commands/board/details.go:33 -#: commands/board/list.go:185 -#: commands/board/listall.go:32 -#: commands/board/search.go:36 -#: commands/compile/compile.go:93 -#: commands/core/download.go:36 -#: commands/core/install.go:35 -#: commands/core/list.go:39 -#: commands/core/search.go:40 -#: commands/core/uninstall.go:33 -#: commands/core/upgrade.go:40 -#: commands/instances.go:566 -#: commands/instances.go:589 -#: commands/lib/list.go:41 -#: commands/lib/list.go:46 -#: commands/lib/search.go:34 -#: commands/upload/upload.go:51 -msgid "invalid instance" -msgstr "invalid instance" - #: cli/arguments/reference.go:75 msgid "invalid item %s" msgstr "invalid item %s" @@ -2669,11 +2803,6 @@ msgstr "invalid library location: %s" msgid "invalid option '%s'" msgstr "invalid option '%s'" -#: commands/instances.go:445 -#: commands/instances.go:521 -msgid "invalid package index in %[1]s: %[2]s" -msgstr "invalid package index in %[1]s: %[2]s" - #: inventory/inventory.go:85 msgid "invalid path creating config dir: %[1]s error: %[2]w" msgstr "invalid path creating config dir: %[1]s error: %[2]w" @@ -2686,7 +2815,7 @@ msgstr "invalid path writing inventory file: %[1]s error: %[2]w" msgid "invalid platform archive size: %s" msgstr "invalid platform archive size: %s" -#: commands/upload/upload.go:482 +#: commands/upload/upload.go:487 msgid "invalid recipe '%[1]s': %[2]s" msgstr "invalid recipe '%[1]s': %[2]s" @@ -2698,12 +2827,6 @@ msgstr "invalid value '%[1]s' for option '%[2]s'" msgid "invalid version dir %[1]s: %[2]s" msgstr "invalid version dir %[1]s: %[2]s" -#: commands/core/download.go:41 -#: commands/core/install.go:40 -#: commands/lib/utils.go:34 -msgid "invalid version: %s" -msgstr "invalid version: %s" - #: commands/daemon/settings.go:108 msgid "key not found in settings" msgstr "key not found in settings" @@ -2717,10 +2840,6 @@ msgstr "keywords" msgid "library %s already installed" msgstr "library %s already installed" -#: commands/lib/utils.go:47 -msgid "library %s not found" -msgstr "library %s not found" - #: arduino/libraries/librariesmanager/install.go:38 msgid "library already installed" msgstr "library already installed" @@ -2737,10 +2856,6 @@ msgstr "library is not valid: missing header file \"%s\"" msgid "library path does not exist: %s" msgstr "library path does not exist: %s" -#: commands/instances.go:404 -msgid "library_index.json has an invalid signature" -msgstr "library_index.json has an invalid signature" - #: arduino/discovery/discoverymanager/discoverymanager.go:222 msgid "listing ports from discovery %[1]s: %[2]w" msgstr "listing ports from discovery %[1]s: %[2]w" @@ -2755,12 +2870,6 @@ msgstr "listing serial ports" msgid "loading %[1]s: %[2]s" msgstr "loading %[1]s: %[2]s" -#: commands/board/details.go:44 -#: commands/lib/list.go:60 -#: commands/upload/upload.go:61 -msgid "loading board data: %s" -msgstr "loading board data: %s" - #: arduino/cores/packagemanager/loader.go:356 msgid "loading boards: %s" msgstr "loading boards: %s" @@ -2800,20 +2909,10 @@ msgstr "loading tool release in %[1]s: %[2]s" msgid "looking for boards.txt in %[1]s: %[2]s" msgstr "looking for boards.txt in %[1]s: %[2]s" -#: commands/lib/download.go:42 -#: commands/lib/install.go:68 -#: commands/lib/resolve_deps.go:34 -msgid "looking for library: %s" -msgstr "looking for library: %s" - #: legacy/builder/container_setup.go:74 msgid "main file missing from sketch" msgstr "main file missing from sketch" -#: commands/compile/compile.go:259 -msgid "missing 'build.project_name' build property" -msgstr "missing 'build.project_name' build property" - #: arduino/resources/checksums.go:41 msgid "missing checksum for: %s" msgstr "missing checksum for: %s" @@ -2830,21 +2929,12 @@ msgstr "missing platform %[1]s:%[2]s referenced by board %[3]s" msgid "missing platform release %[1]s:%[2]s referenced by board %[3]s" msgstr "missing platform release %[1]s:%[2]s referenced by board %[3]s" -#: commands/upload/upload.go:46 -msgid "missing protocol" -msgstr "missing protocol" - -#: commands/compile/compile.go:98 -#: commands/debug/debug_info.go:47 -msgid "missing sketchPath" -msgstr "missing sketchPath" - #: arduino/libraries/librariesmanager/install.go:174 #: arduino/resources/install.go:94 msgid "moving extracted archive to destination dir: %s" msgstr "moving extracted archive to destination dir: %s" -#: commands/upload/upload.go:605 +#: commands/upload/upload.go:610 msgid "multiple build artifacts found: '%[1]s' and '%[2]s'" msgstr "multiple build artifacts found: '%[1]s' and '%[2]s'" @@ -2852,16 +2942,6 @@ msgstr "multiple build artifacts found: '%[1]s' and '%[2]s'" msgid "multiple main sketch files found (%[1]v, %[2]v)" msgstr "multiple main sketch files found (%[1]v, %[2]v)" -#: commands/compile/compile.go:111 -msgid "no FQBN provided" -msgstr "no FQBN provided" - -#: commands/debug/debug_info.go:61 -#: commands/upload/programmers_list.go:33 -#: commands/upload/upload.go:190 -msgid "no Fully Qualified Board Name provided" -msgstr "no Fully Qualified Board Name provided" - #: arduino/cores/packagemanager/install_uninstall.go:127 msgid "no compatible version of %s tools found for the current os" msgstr "no compatible version of %s tools found for the current os" @@ -2870,27 +2950,19 @@ msgstr "no compatible version of %s tools found for the current os" msgid "no executable specified" msgstr "no executable specified" -#: commands/daemon/daemon.go:82 +#: commands/daemon/daemon.go:94 msgid "no instance specified" msgstr "no instance specified" -#: commands/upload/upload.go:181 -msgid "no programmer specified for burning bootloader" -msgstr "no programmer specified for burning bootloader" - -#: commands/upload/upload.go:560 +#: commands/upload/upload.go:565 msgid "no sketch or build directory/file specified" msgstr "no sketch or build directory/file specified" -#: commands/board/attach.go:92 -msgid "no supported board found at %s" -msgstr "no supported board found at %s" - #: arduino/resources/install.go:128 msgid "no unique root dir in archive, found '%[1]s' and '%[2]s'" msgstr "no unique root dir in archive, found '%[1]s' and '%[2]s'" -#: commands/upload/upload.go:477 +#: commands/upload/upload.go:482 msgid "no upload port provided" msgstr "no upload port provided" @@ -2898,9 +2970,9 @@ msgstr "no upload port provided" msgid "no valid sketch found in %[1]s: missing %[2]s" msgstr "no valid sketch found in %[1]s: missing %[2]s" -#: commands/lib/resolve_deps.go:56 -msgid "no valid solution found" -msgstr "no valid solution found" +#: commands/core/download.go:84 +msgid "no versions available for the current OS" +msgstr "no versions available for the current OS" #: arduino/resources/checksums.go:72 #: arduino/resources/install.go:59 @@ -2919,16 +2991,6 @@ msgstr "opening port at 1200bps" msgid "opening signature file: %s" msgstr "opening signature file: %s" -#: commands/debug/debug_info.go:52 -msgid "opening sketch" -msgstr "opening sketch" - -#: commands/board/attach.go:50 -#: commands/compile/compile.go:103 -#: commands/upload/upload.go:123 -msgid "opening sketch: %s" -msgstr "opening sketch: %s" - #: arduino/security/signatures.go:76 msgid "opening target file: %s" msgstr "opening target file: %s" @@ -2953,9 +3015,6 @@ msgstr "parsing IDE bundled index: %s" #: arduino/cores/board.go:139 #: arduino/cores/packagemanager/package_manager.go:136 -#: commands/board/details.go:38 -#: commands/lib/list.go:56 -#: commands/upload/upload.go:56 msgid "parsing fqbn: %s" msgstr "parsing fqbn: %s" @@ -2963,10 +3022,6 @@ msgstr "parsing fqbn: %s" msgid "parsing library_index.json: %s" msgstr "parsing library_index.json: %s" -#: commands/instances.go:487 -msgid "parsing url for index signature check: %s" -msgstr "parsing url for index signature check: %s" - #: arduino/cores/packagemanager/loader.go:189 msgid "path is not a platform directory: %s" msgstr "path is not a platform directory: %s" @@ -2980,35 +3035,16 @@ msgid "platform %s has no available releases" msgstr "platform %s has no available releases" #: arduino/cores/packagemanager/package_manager.go:182 -#: commands/core/upgrade.go:74 -#: commands/core/upgrade.go:84 -#: commands/instances.go:763 msgid "platform %s is not installed" msgstr "platform %s is not installed" -#: commands/core/upgrade.go:70 -msgid "platform %s not found" -msgstr "platform %s not found" - -#: commands/core/upgrade.go:31 -msgid "platform already at latest version" -msgstr "platform already at latest version" - -#: commands/core/uninstall.go:43 -msgid "platform not found: %s" -msgstr "platform not found: %s" - #: arduino/cores/packagemanager/install_uninstall.go:65 #: arduino/cores/packagemanager/install_uninstall.go:108 #: arduino/cores/packagemanager/loader.go:433 -#: commands/compile/compile.go:128 +#: commands/compile/compile.go:127 msgid "platform not installed" msgstr "platform not installed" -#: commands/core/uninstall.go:48 -msgid "platform not installed: %s" -msgstr "platform not installed: %s" - #: cli/compile/compile.go:121 msgid "please use --build-property instead." msgstr "please use --build-property instead." @@ -3025,22 +3061,6 @@ msgstr "port" msgid "port not found: %[1]s %[2]s" msgstr "port not found: %[1]s %[2]s" -#: commands/upload/upload.go:218 -msgid "programmer '%s' not available" -msgstr "programmer '%s' not available" - -#: commands/debug/debug_info.go:114 -msgid "programmer '%s' not found" -msgstr "programmer '%s' not found" - -#: commands/upload/upload.go:155 -msgid "programmer not specified" -msgstr "programmer not specified" - -#: commands/upload/upload.go:456 -msgid "programming error: %s" -msgstr "programming error: %s" - #: arduino/discovery/discovery.go:303 msgid "protocol version not supported: requested 1, got %d" msgstr "protocol version not supported: requested 1, got %d" @@ -3057,10 +3077,6 @@ msgstr "reading %[1]s directory: %[2]s" msgid "reading %[1]s: %[2]s" msgstr "reading %[1]s: %[2]s" -#: commands/compile/compile.go:263 -msgid "reading build directory: %s" -msgstr "reading build directory: %s" - #: arduino/cores/packagemanager/loader.go:267 #: arduino/libraries/librariesmanager/librariesmanager.go:196 msgid "reading dir %[1]s: %[2]s" @@ -3091,6 +3107,10 @@ msgstr "reading lib headers: %s" msgid "reading lib src dir: %s" msgstr "reading lib src dir: %s" +#: arduino/libraries/libraries.go:114 +msgid "reading library headers: %w" +msgstr "reading library headers: %w" + #: arduino/libraries/librariesindex/json.go:63 msgid "reading library_index.json: %s" msgstr "reading library_index.json: %s" @@ -3103,7 +3123,7 @@ msgstr "reading package root dir: %s" msgid "reading sketch metadata %[1]s: %[2]s" msgstr "reading sketch metadata %[1]s: %[2]s" -#: commands/upload/upload.go:471 +#: commands/upload/upload.go:476 msgid "recipe not found '%s'" msgstr "recipe not found '%s'" @@ -3140,27 +3160,10 @@ msgstr "removing tool files: %s" msgid "required version %[1]s not found for platform %[2]s" msgstr "required version %[1]s not found for platform %[2]s" -#: commands/lib/install.go:82 -#: commands/lib/upgrade.go:38 -msgid "rescanning libraries: %s" -msgstr "rescanning libraries: %s" - #: arduino/security/signatures.go:72 msgid "retrieving Arduino public keys: %s" msgstr "retrieving Arduino public keys: %s" -#: commands/upload/upload.go:350 -msgid "retrieving build artifacts: %s" -msgstr "retrieving build artifacts: %s" - -#: commands/instances.go:529 -msgid "saving downloaded index %[1]s: %[2]s" -msgstr "saving downloaded index %[1]s: %[2]s" - -#: commands/instances.go:533 -msgid "saving downloaded index signature: %s" -msgstr "saving downloaded index signature: %s" - #: arduino/libraries/loader.go:109 #: arduino/libraries/loader.go:140 msgid "scanning examples: %s" @@ -3178,10 +3181,6 @@ msgstr "searching package root dir: %s" msgid "setting DTR to OFF" msgstr "setting DTR to OFF" -#: commands/instances.go:513 -msgid "signature verification error: %s" -msgstr "signature verification error: %s" - #: cli/board/attach.go:35 #: cli/sketch/archive.go:38 msgid "sketchPath" @@ -3235,6 +3234,10 @@ msgstr "text section exceeds available space in board" msgid "the library name is different from the set (%[1]s != %[2]s)" msgstr "the library name is different from the set (%[1]s != %[2]s)" +#: commands/core/list.go:57 +msgid "the platform has no releases" +msgstr "the platform has no releases" + #: commands/board/list.go:72 msgid "the server responded with status %s" msgstr "the server responded with status %s" @@ -3253,10 +3256,6 @@ msgstr "to download the latest version of Arduino SAMD core.\n" msgid "tool %s is not managed by package manager" msgstr "tool %s is not managed by package manager" -#: commands/core/download.go:84 -msgid "tool %s not available for the current OS" -msgstr "tool %s not available for the current OS" - #: arduino/cores/status.go:92 #: arduino/cores/status.go:117 msgid "tool %s not found" @@ -3287,7 +3286,7 @@ msgstr "tool release not found: %s" msgid "tool version %s not found" msgstr "tool version %s not found" -#: commands/lib/install.go:54 +#: commands/lib/install.go:58 msgid "two different versions of the library %[1]s are required: %[2]s and %[3]s" msgstr "two different versions of the library %[1]s are required: %[2]s and %[3]s" @@ -3308,10 +3307,6 @@ msgstr "unable to create a folder to save the sketch files" msgid "unable to create the folder containing the item" msgstr "unable to create the folder containing the item" -#: commands/core/list.go:34 -msgid "unable to find an instance with ID: %d" -msgstr "unable to find an instance with ID: %d" - #: cli/config/dump.go:53 msgid "unable to marshal config to YAML: %v" msgstr "unable to marshal config to YAML: %v" @@ -3344,55 +3339,22 @@ msgstr "unknown platform %s:%s" msgid "unknown sketch file extension '%s'" msgstr "unknown sketch file extension '%s'" -#: commands/debug/debug.go:173 -msgid "unsupported gdb server '%s'" -msgstr "unsupported gdb server '%s'" - #: arduino/resources/checksums.go:62 msgid "unsupported hash algorithm: %s" msgstr "unsupported hash algorithm: %s" -#: commands/debug/debug.go:134 -msgid "unsupported toolchain '%s'" -msgstr "unsupported toolchain '%s'" - -#: commands/instances.go:397 -msgid "unzipping library_index.json.gz" -msgstr "unzipping library_index.json.gz" - -#: cli/core/upgrade.go:42 +#: cli/core/upgrade.go:44 msgid "upgrade arduino:samd to the latest version" msgstr "upgrade arduino:samd to the latest version" -#: commands/core/upgrade.go:64 -msgid "upgrade doesn't accept parameters with version" -msgstr "upgrade doesn't accept parameters with version" - -#: cli/core/upgrade.go:40 +#: cli/core/upgrade.go:42 msgid "upgrade everything to the latest version" msgstr "upgrade everything to the latest version" -#: commands/core/install.go:156 -msgid "upgrading platform: %s" -msgstr "upgrading platform: %s" - -#: commands/upload/upload.go:460 -#: commands/upload/upload.go:506 +#: commands/upload/upload.go:511 msgid "uploading error: %s" msgstr "uploading error: %s" -#: commands/instances.go:402 -msgid "verifying signature" -msgstr "verifying signature" - -#: commands/instances.go:411 -msgid "writing library_index.json" -msgstr "writing library_index.json" - -#: commands/instances.go:414 -msgid "writing library_index.json.sig" -msgstr "writing library_index.json.sig" - #: arduino/sketch/sketch.go:212 msgid "writing sketch metadata %[1]s: %[2]s" msgstr "writing sketch metadata %[1]s: %[2]s" diff --git a/i18n/rice-box.go b/i18n/rice-box.go index e2eb9892ee0..c682f8cdbfa 100644 --- a/i18n/rice-box.go +++ b/i18n/rice-box.go @@ -18,9 +18,9 @@ func init() { } file3 := &embedded.EmbeddedFile{ Filename: "en.po", - FileModTime: time.Unix(1629971830, 0), + FileModTime: time.Unix(1630310580, 0), - Content: string("msgid \"\"\nmsgstr \"\"\n\n#: legacy/builder/resolve_library.go:36\nmsgid \" -> candidates: %s\"\nmsgstr \" -> candidates: %s\"\n\n#: legacy/builder/constants/constants.go:107\nmsgid \" Not used: {0}\"\nmsgstr \" Not used: {0}\"\n\n#: legacy/builder/constants/constants.go:108\nmsgid \" Used: {0}\"\nmsgstr \" Used: {0}\"\n\n#: version/version.go:54\nmsgid \"%[1]s %[2]s Version: %[3]s Commit: %[4]s Date: %[5]s\"\nmsgstr \"%[1]s %[2]s Version: %[3]s Commit: %[4]s Date: %[5]s\"\n\n#: legacy/builder/constants/constants.go:92\nmsgid \"%[1]s folder is no longer supported! See %[2]s for more information\"\nmsgstr \"%[1]s folder is no longer supported! See %[2]s for more information\"\n\n#: arduino/discovery/discovery.go:74\nmsgid \"%[1]s, message: %[2]s\"\nmsgstr \"%[1]s, message: %[2]s\"\n\n#: arduino/discovery/discovery.go:83\nmsgid \"%[1]s, port: %[2]s\"\nmsgstr \"%[1]s, port: %[2]s\"\n\n#: arduino/discovery/discovery.go:80\nmsgid \"%[1]s, ports: %[2]s\"\nmsgstr \"%[1]s, ports: %[2]s\"\n\n#: arduino/discovery/discovery.go:77\nmsgid \"%[1]s, protocol version: %[2]d\"\nmsgstr \"%[1]s, protocol version: %[2]d\"\n\n#: cli/output/rpc_progress.go:64\nmsgid \"%s already downloaded\"\nmsgstr \"%s already downloaded\"\n\n#: commands/upload/upload.go:528\nmsgid \"%s and %s cannot be used together\"\nmsgstr \"%s and %s cannot be used together\"\n\n#: cli/debug/debug.go:159\nmsgid \"%s custom configurations\"\nmsgstr \"%s custom configurations\"\n\n#: cli/output/rpc_progress.go:76\nmsgid \"%s downloaded\"\nmsgstr \"%s downloaded\"\n\n#: commands/bundled_tools.go:57\n#: commands/core/install.go:181\nmsgid \"%s installed\"\nmsgstr \"%s installed\"\n\n#: cli/lib/check_deps.go:93\nmsgid \"%s is already installed.\"\nmsgstr \"%s is already installed.\"\n\n#: arduino/cores/packagemanager/loader.go:71\nmsgid \"%s is not a directory\"\nmsgstr \"%s is not a directory\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:113\nmsgid \"%s is not managed by package manager\"\nmsgstr \"%s is not managed by package manager\"\n\n#: cli/lib/check_deps.go:96\nmsgid \"%s is required but %s is currently installed.\"\nmsgstr \"%s is required but %s is currently installed.\"\n\n#: cli/lib/check_deps.go:90\nmsgid \"%s must be installed.\"\nmsgstr \"%s must be installed.\"\n\n#: legacy/builder/builder_utils/utils.go:530\n#: legacy/builder/ctags_runner.go:41\nmsgid \"%s pattern is missing\"\nmsgstr \"%s pattern is missing\"\n\n#: commands/core/uninstall.go:90\n#: commands/core/uninstall.go:106\n#: commands/instances.go:840\nmsgid \"%s uninstalled\"\nmsgstr \"%s uninstalled\"\n\n#: cli/board/listall.go:88\n#: cli/board/search.go:90\nmsgid \"(hidden)\"\nmsgstr \"(hidden)\"\n\n#: legacy/builder/constants/constants.go:105\nmsgid \"(legacy)\"\nmsgstr \"(legacy)\"\n\n#: legacy/builder/constants/constants.go:98\nmsgid \", rebuilding all\"\nmsgstr \", rebuilding all\"\n\n#: cli/lib/install.go:71\nmsgid \"--git-url and --zip-path are disabled by default, for more information see: %v\"\nmsgstr \"--git-url and --zip-path are disabled by default, for more information see: %v\"\n\n#: cli/lib/install.go:74\nmsgid \"--git-url and --zip-path flags allow installing untrusted files, use it at your own risk.\"\nmsgstr \"--git-url and --zip-path flags allow installing untrusted files, use it at your own risk.\"\n\n#: cli/core/download.go:36\n#: cli/core/install.go:37\n#: cli/core/uninstall.go:36\n#: cli/core/upgrade.go:36\nmsgid \"ARCH\"\nmsgstr \"ARCH\"\n\n#: cli/generatedocs/generatedocs.go:79\nmsgid \"ARDUINO COMMAND LINE MANUAL\"\nmsgstr \"ARDUINO COMMAND LINE MANUAL\"\n\n#: cli/usage.go:31\nmsgid \"Additional help topics:\"\nmsgstr \"Additional help topics:\"\n\n#: cli/config/add.go:31\n#: cli/config/add.go:32\nmsgid \"Adds one or more values to a setting.\"\nmsgstr \"Adds one or more values to a setting.\"\n\n#: cli/usage.go:26\nmsgid \"Aliases:\"\nmsgstr \"Aliases:\"\n\n#: cli/core/upgrade.go:66\nmsgid \"All the cores are already at the latest version\"\nmsgstr \"All the cores are already at the latest version\"\n\n#: commands/instances.go:712\n#: commands/lib/install.go:92\nmsgid \"Already installed %s\"\nmsgstr \"Already installed %s\"\n\n#: legacy/builder/resolve_library.go:34\nmsgid \"Alternatives for %[1]s: %[2]s\"\nmsgstr \"Alternatives for %[1]s: %[2]s\"\n\n#: cli/lib/search.go:170\nmsgid \"Architecture: %s\"\nmsgstr \"Architecture: %s\"\n\n#: legacy/builder/constants/constants.go:93\nmsgid \"Archiving built core (caching) in: {0}\"\nmsgstr \"Archiving built core (caching) in: {0}\"\n\n#: cli/sketch/sketch.go:31\n#: cli/sketch/sketch.go:32\nmsgid \"Arduino CLI sketch commands.\"\nmsgstr \"Arduino CLI sketch commands.\"\n\n#: cli/cli.go:67\nmsgid \"Arduino CLI.\"\nmsgstr \"Arduino CLI.\"\n\n#: cli/cli.go:68\nmsgid \"Arduino Command Line Interface (arduino-cli).\"\nmsgstr \"Arduino Command Line Interface (arduino-cli).\"\n\n#: cli/board/board.go:28\n#: cli/board/board.go:29\nmsgid \"Arduino board commands.\"\nmsgstr \"Arduino board commands.\"\n\n#: cli/cache/cache.go:31\n#: cli/cache/cache.go:32\nmsgid \"Arduino cache commands.\"\nmsgstr \"Arduino cache commands.\"\n\n#: cli/lib/lib.go:31\n#: cli/lib/lib.go:32\nmsgid \"Arduino commands about libraries.\"\nmsgstr \"Arduino commands about libraries.\"\n\n#: cli/config/config.go:31\nmsgid \"Arduino configuration commands.\"\nmsgstr \"Arduino configuration commands.\"\n\n#: cli/core/core.go:31\n#: cli/core/core.go:32\nmsgid \"Arduino core operations.\"\nmsgstr \"Arduino core operations.\"\n\n#: cli/lib/check_deps.go:50\n#: cli/lib/install.go:117\nmsgid \"Arguments error: %v\"\nmsgstr \"Arguments error: %v\"\n\n#: cli/board/attach.go:68\nmsgid \"Attach board error: %v\"\nmsgstr \"Attach board error: %v\"\n\n#: cli/board/attach.go:36\n#: cli/board/attach.go:37\n#: cli/board/board.go:32\nmsgid \"Attaches a sketch to a board.\"\nmsgstr \"Attaches a sketch to a board.\"\n\n#: cli/lib/search.go:161\nmsgid \"Author: %s\"\nmsgstr \"Author: %s\"\n\n#: cli/lib/list.go:125\nmsgid \"Available\"\nmsgstr \"Available\"\n\n#: cli/usage.go:28\nmsgid \"Available Commands:\"\nmsgstr \"Available Commands:\"\n\n#: cli/upload/upload.go:61\nmsgid \"Binary file to upload.\"\nmsgstr \"Binary file to upload.\"\n\n#: cli/board/list.go:87\n#: cli/board/list.go:125\n#: cli/board/listall.go:84\n#: cli/board/search.go:86\nmsgid \"Board Name\"\nmsgstr \"Board Name\"\n\n#: commands/board/attach.go:94\nmsgid \"Board found: %s\"\nmsgstr \"Board found: %s\"\n\n#: cli/board/details.go:120\nmsgid \"Board name:\"\nmsgstr \"Board name:\"\n\n#: cli/board/details.go:122\nmsgid \"Board version:\"\nmsgstr \"Board version:\"\n\n#: legacy/builder/constants/constants.go:96\nmsgid \"Board {0} (platform {1}, package {2}) is unknown\"\nmsgstr \"Board {0} (platform {1}, package {2}) is unknown\"\n\n#: legacy/builder/constants/constants.go:97\nmsgid \"Bootloader file specified but missing: {0}\"\nmsgstr \"Bootloader file specified but missing: {0}\"\n\n#: legacy/builder/constants/constants.go:99\nmsgid \"Build options changed\"\nmsgstr \"Build options changed\"\n\n#: cli/compile/compile.go:88\nmsgid \"Builds of 'core.a' are saved into this path to be cached and reused.\"\nmsgstr \"Builds of 'core.a' are saved into this path to be cached and reused.\"\n\n#: cli/config/set.go:54\nmsgid \"Can't set multiple values in key %v\"\nmsgstr \"Can't set multiple values in key %v\"\n\n#: cli/config/init.go:60\nmsgid \"Can't use both --dest-file and --dest-dir flags at the same time.\"\nmsgstr \"Can't use both --dest-file and --dest-dir flags at the same time.\"\n\n#: cli/config/add.go:60\n#: cli/config/delete.go:67\n#: cli/config/remove.go:69\nmsgid \"Can't write config file: %v\"\nmsgstr \"Can't write config file: %v\"\n\n#: cli/config/init.go:97\nmsgid \"Cannot create config file directory: %v\"\nmsgstr \"Cannot create config file directory: %v\"\n\n#: cli/config/init.go:106\nmsgid \"Cannot create config file: %v\"\nmsgstr \"Cannot create config file: %v\"\n\n#: commands/debug/debug.go:67\nmsgid \"Cannot execute debug tool\"\nmsgstr \"Cannot execute debug tool\"\n\n#: cli/config/init.go:72\n#: cli/config/init.go:83\nmsgid \"Cannot find absolute path: %v\"\nmsgstr \"Cannot find absolute path: %v\"\n\n#: commands/debug/debug.go:51\nmsgid \"Cannot get command line for tool\"\nmsgstr \"Cannot get command line for tool\"\n\n#: configuration/configuration.go:147\n#: configuration/configuration.go:153\nmsgid \"Cannot get executable path: %v\"\nmsgstr \"Cannot get executable path: %v\"\n\n#: commands/upload/upload.go:418\nmsgid \"Cannot perform port reset: %s\"\nmsgstr \"Cannot perform port reset: %s\"\n\n#: cli/lib/search.go:169\nmsgid \"Category: %s\"\nmsgstr \"Category: %s\"\n\n#: cli/lib/check_deps.go:35\n#: cli/lib/check_deps.go:36\nmsgid \"Check dependencies status for the specified library.\"\nmsgstr \"Check dependencies status for the specified library.\"\n\n#: legacy/builder/builder_utils/utils.go:280\nmsgid \"Checking previous results for {0} (result = {1}, dep = {2})\"\nmsgstr \"Checking previous results for {0} (result = {1}, dep = {2})\"\n\n#: arduino/resources/checksums.go:182\nmsgid \"Checksum differs from checksum in package.json\"\nmsgstr \"Checksum differs from checksum in package.json\"\n\n#: cli/board/details.go:168\nmsgid \"Checksum:\"\nmsgstr \"Checksum:\"\n\n#: cli/cache/cache.go:33\nmsgid \"Clean caches.\"\nmsgstr \"Clean caches.\"\n\n#: cli/cli.go:106\nmsgid \"Comma-separated list of additional URLs for the Boards Manager.\"\nmsgstr \"Comma-separated list of additional URLs for the Boards Manager.\"\n\n#: cli/board/list.go:47\nmsgid \"Command keeps running and prints list of connected boards whenever there is a change.\"\nmsgstr \"Command keeps running and prints list of connected boards whenever there is a change.\"\n\n#: cli/compile/compile.go:74\n#: cli/compile/compile.go:75\nmsgid \"Compiles Arduino sketches.\"\nmsgstr \"Compiles Arduino sketches.\"\n\n#: legacy/builder/builder.go:81\nmsgid \"Compiling core...\"\nmsgstr \"Compiling core...\"\n\n#: legacy/builder/builder.go:75\nmsgid \"Compiling libraries...\"\nmsgstr \"Compiling libraries...\"\n\n#: legacy/builder/phases/libraries_builder.go:135\nmsgid \"Compiling library \\\"{0}\\\"\"\nmsgstr \"Compiling library \\\"{0}\\\"\"\n\n#: legacy/builder/builder.go:70\nmsgid \"Compiling sketch...\"\nmsgstr \"Compiling sketch...\"\n\n#: cli/config/init.go:90\nmsgid \"Config file already exists, use --overwrite to discard the existing one.\"\nmsgstr \"Config file already exists, use --overwrite to discard the existing one.\"\n\n#: cli/config/init.go:110\nmsgid \"Config file written to: %s\"\nmsgstr \"Config file written to: %s\"\n\n#: commands/core/install.go:171\n#: commands/instances.go:847\nmsgid \"Configuring platform\"\nmsgstr \"Configuring platform\"\n\n#: cli/board/list.go:183\nmsgid \"Connected\"\nmsgstr \"Connected\"\n\n#: cli/board/list.go:87\n#: cli/board/list.go:125\nmsgid \"Core\"\nmsgstr \"Core\"\n\n#: cli/update/update.go:99\nmsgid \"Core name\"\nmsgstr \"Core name\"\n\n#: cli/sketch/new.go:58\nmsgid \"Could not create sketch directory: %v\"\nmsgstr \"Could not create sketch directory: %v\"\n\n#: legacy/builder/phases/core_builder.go:48\nmsgid \"Couldn't deeply cache core build: {0}\"\nmsgstr \"Couldn't deeply cache core build: {0}\"\n\n#: legacy/builder/constants/constants.go:127\nmsgid \"Couldn't determine program size\"\nmsgstr \"Couldn't determine program size\"\n\n#: cli/arguments/sketch.go:36\n#: cli/lib/install.go:97\nmsgid \"Couldn't get current working directory: %v\"\nmsgstr \"Couldn't get current working directory: %v\"\n\n#: cli/sketch/new.go:32\n#: cli/sketch/new.go:33\nmsgid \"Create a new Sketch\"\nmsgstr \"Create a new Sketch\"\n\n#: cli/sketch/archive.go:39\n#: cli/sketch/archive.go:40\nmsgid \"Creates a zip file containing all sketch files.\"\nmsgstr \"Creates a zip file containing all sketch files.\"\n\n#: cli/config/init.go:43\nmsgid \"Creates or updates the configuration file in the data directory or custom directory with the current configuration settings.\"\nmsgstr \"Creates or updates the configuration file in the data directory or custom directory with the current configuration settings.\"\n\n#: cli/debug/debug.go:56\nmsgid \"Debug Arduino sketches.\"\nmsgstr \"Debug Arduino sketches.\"\n\n#: cli/debug/debug.go:57\nmsgid \"Debug Arduino sketches. (this command opens an interactive gdb session)\"\nmsgstr \"Debug Arduino sketches. (this command opens an interactive gdb session)\"\n\n#: cli/debug/debug.go:66\nmsgid \"Debug interpreter e.g.: %s, %s, %s, %s, %s\"\nmsgstr \"Debug interpreter e.g.: %s, %s, %s, %s, %s\"\n\n#: cli/board/details.go:124\nmsgid \"Debugging supported:\"\nmsgstr \"Debugging supported:\"\n\n#: cli/cache/clean.go:31\nmsgid \"Delete Boards/Library Manager download cache.\"\nmsgstr \"Delete Boards/Library Manager download cache.\"\n\n#: cli/cache/clean.go:32\nmsgid \"Delete contents of the `directories.downloads` folder, where archive files are staged during installation of libraries and boards platforms.\"\nmsgstr \"Delete contents of the `directories.downloads` folder, where archive files are staged during installation of libraries and boards platforms.\"\n\n#: cli/config/delete.go:32\n#: cli/config/delete.go:33\nmsgid \"Deletes a settings key and all its sub keys.\"\nmsgstr \"Deletes a settings key and all its sub keys.\"\n\n#: cli/lib/search.go:177\nmsgid \"Dependencies: %s\"\nmsgstr \"Dependencies: %s\"\n\n#: legacy/builder/builder_utils/utils.go:358\nmsgid \"Depfile is about different file: {0}\"\nmsgstr \"Depfile is about different file: {0}\"\n\n#: cli/lib/list.go:125\nmsgid \"Description\"\nmsgstr \"Description\"\n\n#: legacy/builder/builder.go:62\nmsgid \"Detecting libraries used...\"\nmsgstr \"Detecting libraries used...\"\n\n#: cli/board/list.go:38\nmsgid \"Detects and displays a list of boards connected to the current computer.\"\nmsgstr \"Detects and displays a list of boards connected to the current computer.\"\n\n#: cli/debug/debug.go:67\nmsgid \"Directory containing binaries for debug.\"\nmsgstr \"Directory containing binaries for debug.\"\n\n#: cli/upload/upload.go:60\nmsgid \"Directory containing binaries to upload.\"\nmsgstr \"Directory containing binaries to upload.\"\n\n#: cli/generatedocs/generatedocs.go:45\nmsgid \"Directory where to save generated files. Default is './docs', the directory must exist.\"\nmsgstr \"Directory where to save generated files. Default is './docs', the directory must exist.\"\n\n#: cli/completion/completion.go:44\nmsgid \"Disable completion description for shells that support it\"\nmsgstr \"Disable completion description for shells that support it\"\n\n#: cli/board/list.go:184\nmsgid \"Disconnected\"\nmsgstr \"Disconnected\"\n\n#: cli/lib/install.go:49\nmsgid \"Do not install dependencies.\"\nmsgstr \"Do not install dependencies.\"\n\n#: cli/burnbootloader/burnbootloader.go:58\n#: cli/upload/upload.go:65\nmsgid \"Do not perform the actual upload, just log out actions\"\nmsgstr \"Do not perform the actual upload, just log out actions\"\n\n#: cli/daemon/daemon.go:58\nmsgid \"Do not terminate daemon process if the parent process dies\"\nmsgstr \"Do not terminate daemon process if the parent process dies\"\n\n#: commands/instances.go:701\n#: commands/instances.go:760\n#: commands/lib/download.go:55\nmsgid \"Downloading %s\"\nmsgstr \"Downloading %s\"\n\n#: commands/instances.go:93\nmsgid \"Downloading missing tool %s\"\nmsgstr \"Downloading missing tool %s\"\n\n#: commands/core/install.go:88\nmsgid \"Downloading packages\"\nmsgstr \"Downloading packages\"\n\n#: cli/core/download.go:37\n#: cli/core/download.go:38\nmsgid \"Downloads one or more cores and corresponding tool dependencies.\"\nmsgstr \"Downloads one or more cores and corresponding tool dependencies.\"\n\n#: cli/lib/download.go:35\n#: cli/lib/download.go:36\nmsgid \"Downloads one or more libraries without installing them.\"\nmsgstr \"Downloads one or more libraries without installing them.\"\n\n#: cli/lib/install.go:51\nmsgid \"Enter a path to zip file\"\nmsgstr \"Enter a path to zip file\"\n\n#: cli/lib/install.go:50\nmsgid \"Enter git url for libraries hosted on repositories\"\nmsgstr \"Enter git url for libraries hosted on repositories\"\n\n#: commands/sketch/archive.go:106\nmsgid \"Error adding file to archive: %v\"\nmsgstr \"Error adding file to archive: %v\"\n\n#: legacy/builder/constants/constants.go:94\nmsgid \"Error archiving built core (caching) in {0}: {1}\"\nmsgstr \"Error archiving built core (caching) in {0}: {1}\"\n\n#: cli/sketch/archive.go:85\nmsgid \"Error archiving: %v\"\nmsgstr \"Error archiving: %v\"\n\n#: commands/sketch/archive.go:93\nmsgid \"Error calculating relative file path: %v\"\nmsgstr \"Error calculating relative file path: %v\"\n\n#: cli/cache/clean.go:46\nmsgid \"Error cleaning caches: %v\"\nmsgstr \"Error cleaning caches: %v\"\n\n#: commands/sketch/archive.go:81\nmsgid \"Error creating archive: %v\"\nmsgstr \"Error creating archive: %v\"\n\n#: cli/core/search.go:66\n#: cli/core/update_index.go:52\n#: cli/instance/instance.go:43\n#: cli/lib/search.go:57\n#: cli/lib/update_index.go:45\n#: cli/update/update.go:62\nmsgid \"Error creating instance: %v\"\nmsgstr \"Error creating instance: %v\"\n\n#: cli/sketch/new.go:54\n#: cli/sketch/new.go:64\nmsgid \"Error creating sketch: %v\"\nmsgstr \"Error creating sketch: %v\"\n\n#: cli/board/list.go:71\n#: cli/board/list.go:80\nmsgid \"Error detecting boards: %v\"\nmsgstr \"Error detecting boards: %v\"\n\n#: cli/core/download.go:68\n#: cli/lib/download.go:62\nmsgid \"Error downloading %[1]s: %[2]v\"\nmsgstr \"Error downloading %[1]s: %[2]v\"\n\n#: commands/instances.go:779\nmsgid \"Error downloading tool %s\"\nmsgstr \"Error downloading tool %s\"\n\n#: cli/debug/debug.go:83\n#: cli/debug/debug.go:88\n#: cli/debug/debug.go:121\nmsgid \"Error during Debug: %v\"\nmsgstr \"Error during Debug: %v\"\n\n#: cli/feedback/feedback.go:134\nmsgid \"Error during JSON encoding of the output: %v\"\nmsgstr \"Error during JSON encoding of the output: %v\"\n\n#: cli/burnbootloader/burnbootloader.go:70\n#: cli/burnbootloader/burnbootloader.go:83\n#: cli/compile/compile.go:196\n#: cli/compile/compile.go:202\n#: cli/compile/compile.go:212\n#: cli/compile/compile.go:242\n#: cli/upload/upload.go:96\n#: cli/upload/upload.go:101\n#: cli/upload/upload.go:111\n#: cli/upload/upload.go:134\nmsgid \"Error during Upload: %v\"\nmsgstr \"Error during Upload: %v\"\n\n#: cli/compile/compile.go:254\nmsgid \"Error during build: %v\"\nmsgstr \"Error during build: %v\"\n\n#: cli/core/install.go:106\nmsgid \"Error during install: %v\"\nmsgstr \"Error during install: %v\"\n\n#: cli/core/uninstall.go:68\nmsgid \"Error during uninstall: %v\"\nmsgstr \"Error during uninstall: %v\"\n\n#: cli/core/upgrade.go:101\nmsgid \"Error during upgrade: %v\"\nmsgstr \"Error during upgrade: %v\"\n\n#: cli/debug/debug.go:105\n#: cli/debug/debug.go:108\nmsgid \"Error getting Debug info: %v\"\nmsgstr \"Error getting Debug info: %v\"\n\n#: commands/sketch/archive.go:59\nmsgid \"Error getting absolute archive path %v\"\nmsgstr \"Error getting absolute archive path %v\"\n\n#: cli/board/details.go:71\nmsgid \"Error getting board details: %v\"\nmsgstr \"Error getting board details: %v\"\n\n#: arduino/builder/compilation_database.go:78\nmsgid \"Error getting current directory for compilation database: %s\"\nmsgstr \"Error getting current directory for compilation database: %s\"\n\n#: cli/lib/examples.go:69\nmsgid \"Error getting libraries info: %v\"\nmsgstr \"Error getting libraries info: %v\"\n\n#: legacy/builder/types/context.go:239\nmsgid \"Error in FQBN: %s\"\nmsgstr \"Error in FQBN: %s\"\n\n#: cli/core/search.go:81\n#: cli/instance/instance.go:47\n#: cli/lib/search.go:70\n#: cli/update/update.go:87\nmsgid \"Error initializing instance: %v\"\nmsgstr \"Error initializing instance: %v\"\n\n#: commands/instances.go:806\nmsgid \"Error installing %s\"\nmsgstr \"Error installing %s\"\n\n#: cli/lib/install.go:130\nmsgid \"Error installing %s: %v\"\nmsgstr \"Error installing %s: %v\"\n\n#: cli/lib/install.go:108\nmsgid \"Error installing Git Library: %v\"\nmsgstr \"Error installing Git Library: %v\"\n\n#: cli/lib/install.go:85\nmsgid \"Error installing Zip Library: %v\"\nmsgstr \"Error installing Zip Library: %v\"\n\n#: commands/instances.go:797\nmsgid \"Error installing tool %s\"\nmsgstr \"Error installing tool %s\"\n\n#: cli/lib/list.go:77\nmsgid \"Error listing Libraries: %v\"\nmsgstr \"Error listing Libraries: %v\"\n\n#: cli/board/listall.go:61\nmsgid \"Error listing boards: %v\"\nmsgstr \"Error listing boards: %v\"\n\n#: cli/core/list.go:61\nmsgid \"Error listing platforms: %v\"\nmsgstr \"Error listing platforms: %v\"\n\n#: cli/compile/compile.go:147\nmsgid \"Error opening source code overrides data file: %v\"\nmsgstr \"Error opening source code overrides data file: %v\"\n\n#: configuration/configuration.go:69\nmsgid \"Error reading config file: %v\"\nmsgstr \"Error reading config file: %v\"\n\n#: legacy/builder/target_board_resolver.go:33\nmsgid \"Error resolving FQBN: {0}\"\nmsgstr \"Error resolving FQBN: {0}\"\n\n#: cli/lib/check_deps.go:60\nmsgid \"Error resolving dependencies for %[1]s: %[2]s\"\nmsgstr \"Error resolving dependencies for %[1]s: %[2]s\"\n\n#: commands/lib/install.go:48\nmsgid \"Error resolving dependencies for %[1]s@%[2]s: %[3]s\"\nmsgstr \"Error resolving dependencies for %[1]s@%[2]s: %[3]s\"\n\n#: cli/core/upgrade.go:61\nmsgid \"Error retrieving core list: %v\"\nmsgstr \"Error retrieving core list: %v\"\n\n#: cli/outdated/outdated.go:57\n#: cli/update/update.go:94\nmsgid \"Error retrieving outdated cores and libraries: %v\"\nmsgstr \"Error retrieving outdated cores and libraries: %v\"\n\n#: commands/sketch/archive.go:75\nmsgid \"Error retrieving sketch files: %v\"\nmsgstr \"Error retrieving sketch files: %v\"\n\n#: commands/core/install.go:153\n#: commands/instances.go:821\nmsgid \"Error rolling-back changes: %s\"\nmsgstr \"Error rolling-back changes: %s\"\n\n#: cli/board/search.go:63\nmsgid \"Error searching boards: %v\"\nmsgstr \"Error searching boards: %v\"\n\n#: cli/lib/search.go:79\nmsgid \"Error searching for Library: %v\"\nmsgstr \"Error searching for Library: %v\"\n\n#: cli/core/search.go:93\nmsgid \"Error searching for platforms: %v\"\nmsgstr \"Error searching for platforms: %v\"\n\n#: arduino/builder/compilation_database.go:63\nmsgid \"Error serializing compilation database: %s\"\nmsgstr \"Error serializing compilation database: %s\"\n\n#: cli/lib/uninstall.go:62\nmsgid \"Error uninstalling %[1]s: %[2]v\"\nmsgstr \"Error uninstalling %[1]s: %[2]v\"\n\n#: cli/update/update.go:79\nmsgid \"Error updating core and libraries index: %v\"\nmsgstr \"Error updating core and libraries index: %v\"\n\n#: cli/core/search.go:75\n#: cli/core/update_index.go:69\nmsgid \"Error updating index: %v\"\nmsgstr \"Error updating index: %v\"\n\n#: cli/core/update_index.go:61\n#: cli/lib/update_index.go:54\n#: cli/update/update.go:71\nmsgid \"Error updating indexes: %v\"\nmsgstr \"Error updating indexes: %v\"\n\n#: cli/lib/search.go:65\n#: cli/lib/update_index.go:62\nmsgid \"Error updating library index: %v\"\nmsgstr \"Error updating library index: %v\"\n\n#: cli/lib/upgrade.go:50\n#: cli/lib/upgrade.go:56\nmsgid \"Error upgrading libraries: %v\"\nmsgstr \"Error upgrading libraries: %v\"\n\n#: commands/core/install.go:148\n#: commands/instances.go:816\nmsgid \"Error upgrading platform: %s\"\nmsgstr \"Error upgrading platform: %s\"\n\n#: cli/upgrade/upgrade.go:60\nmsgid \"Error upgrading: %v\"\nmsgstr \"Error upgrading: %v\"\n\n#: legacy/builder/constants/constants.go:104\nmsgid \"Error while detecting libraries included by {0}\"\nmsgstr \"Error while detecting libraries included by {0}\"\n\n#: legacy/builder/phases/sizer.go:135\n#: legacy/builder/phases/sizer.go:141\nmsgid \"Error while determining sketch size: %s\"\nmsgstr \"Error while determining sketch size: %s\"\n\n#: arduino/builder/compilation_database.go:66\nmsgid \"Error writing compilation database: %s\"\nmsgstr \"Error writing compilation database: %s\"\n\n#: cli/completion/completion.go:51\nmsgid \"Error: command description is not supported by %v\"\nmsgstr \"Error: command description is not supported by %v\"\n\n#: cli/compile/compile.go:154\nmsgid \"Error: invalid source code overrides data file: %v\"\nmsgstr \"Error: invalid source code overrides data file: %v\"\n\n#: cli/board/list.go:87\nmsgid \"Event\"\nmsgstr \"Event\"\n\n#: cli/lib/examples.go:118\nmsgid \"Examples for library %s\"\nmsgstr \"Examples for library %s\"\n\n#: cli/usage.go:27\nmsgid \"Examples:\"\nmsgstr \"Examples:\"\n\n#: cli/debug/debug.go:140\nmsgid \"Executable to debug\"\nmsgstr \"Executable to debug\"\n\n#: cli/board/attach.go:35\n#: cli/board/details.go:41\n#: cli/board/list.go:87\n#: cli/board/list.go:125\n#: cli/board/listall.go:84\n#: cli/board/search.go:86\nmsgid \"FQBN\"\nmsgstr \"FQBN\"\n\n#: cli/board/details.go:121\nmsgid \"FQBN:\"\nmsgstr \"FQBN:\"\n\n#: cli/daemon/daemon.go:114\nmsgid \"Failed to listen on TCP port: %[1]s. %[2]s is an invalid port.\"\nmsgstr \"Failed to listen on TCP port: %[1]s. %[2]s is an invalid port.\"\n\n#: cli/daemon/daemon.go:108\nmsgid \"Failed to listen on TCP port: %[1]s. %[2]s is unknown name.\"\nmsgstr \"Failed to listen on TCP port: %[1]s. %[2]s is unknown name.\"\n\n#: cli/daemon/daemon.go:123\nmsgid \"Failed to listen on TCP port: %[1]s. Unexpected error: %[2]v\"\nmsgstr \"Failed to listen on TCP port: %[1]s. Unexpected error: %[2]v\"\n\n#: cli/daemon/daemon.go:120\nmsgid \"Failed to listen on TCP port: %s. Address already in use.\"\nmsgstr \"Failed to listen on TCP port: %s. Address already in use.\"\n\n#: legacy/builder/builder_utils/utils.go:380\nmsgid \"Failed to read: {0}\"\nmsgstr \"Failed to read: {0}\"\n\n#: cli/board/details.go:166\nmsgid \"File:\"\nmsgstr \"File:\"\n\n#: commands/daemon/debug.go:47\nmsgid \"First message must contain debug request, not data\"\nmsgstr \"First message must contain debug request, not data\"\n\n#: cli/usage.go:29\nmsgid \"Flags:\"\nmsgstr \"Flags:\"\n\n#: cli/core/install.go:59\nmsgid \"Force run of post-install scripts (if the CLI is not running interactively).\"\nmsgstr \"Force run of post-install scripts (if the CLI is not running interactively).\"\n\n#: cli/core/install.go:60\nmsgid \"Force skip of post-install scripts (if the CLI is running interactively).\"\nmsgstr \"Force skip of post-install scripts (if the CLI is running interactively).\"\n\n#: cli/board/details.go:50\n#: cli/burnbootloader/burnbootloader.go:53\n#: cli/compile/compile.go:85\n#: cli/debug/debug.go:63\n#: cli/upload/upload.go:58\nmsgid \"Fully Qualified Board Name, e.g.: arduino:avr:uno\"\nmsgstr \"Fully Qualified Board Name, e.g.: arduino:avr:uno\"\n\n#: cli/debug/debug.go:154\nmsgid \"GDB Server path\"\nmsgstr \"GDB Server path\"\n\n#: cli/debug/debug.go:153\nmsgid \"GDB Server type\"\nmsgstr \"GDB Server type\"\n\n#: cli/generatedocs/generatedocs.go:38\n#: cli/generatedocs/generatedocs.go:39\nmsgid \"Generates bash completion and command manpages.\"\nmsgstr \"Generates bash completion and command manpages.\"\n\n#: cli/completion/completion.go:38\nmsgid \"Generates completion scripts\"\nmsgstr \"Generates completion scripts\"\n\n#: cli/completion/completion.go:39\nmsgid \"Generates completion scripts for various shells\"\nmsgstr \"Generates completion scripts for various shells\"\n\n#: legacy/builder/builder.go:67\nmsgid \"Generating function prototypes...\"\nmsgstr \"Generating function prototypes...\"\n\n#: cli/usage.go:30\nmsgid \"Global Flags:\"\nmsgstr \"Global Flags:\"\n\n#: legacy/builder/constants/constants.go:122\nmsgid \"Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes.\"\nmsgstr \"Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes.\"\n\n#: legacy/builder/constants/constants.go:123\nmsgid \"Global variables use {0} bytes of dynamic memory.\"\nmsgstr \"Global variables use {0} bytes of dynamic memory.\"\n\n#: cli/core/list.go:84\n#: cli/core/search.go:114\n#: cli/outdated/outdated.go:62\nmsgid \"ID\"\nmsgstr \"ID\"\n\n#: cli/board/details.go:93\n#: cli/board/details.go:194\nmsgid \"Id\"\nmsgstr \"Id\"\n\n#: cli/board/details.go:135\nmsgid \"Identification properties:\"\nmsgstr \"Identification properties:\"\n\n#: cli/compile/compile.go:115\nmsgid \"If set built binaries will be exported to the sketch folder.\"\nmsgstr \"If set built binaries will be exported to the sketch folder.\"\n\n#: cli/core/list.go:42\nmsgid \"If set return all installable and installed cores, including manually installed.\"\nmsgstr \"If set return all installable and installed cores, including manually installed.\"\n\n#: cli/lib/list.go:48\nmsgid \"Include built-in libraries (from platforms and IDE) in listing.\"\nmsgstr \"Include built-in libraries (from platforms and IDE) in listing.\"\n\n#: cli/sketch/archive.go:51\nmsgid \"Includes %s directory in the archive.\"\nmsgstr \"Includes %s directory in the archive.\"\n\n#: cli/core/list.go:84\n#: cli/lib/list.go:125\nmsgid \"Installed\"\nmsgstr \"Installed\"\n\n#: commands/instances.go:726\n#: commands/lib/install.go:108\nmsgid \"Installed %s\"\nmsgstr \"Installed %s\"\n\n#: commands/lib/install.go:118\nmsgid \"Installed Archived Library\"\nmsgstr \"Installed Archived Library\"\n\n#: commands/lib/install.go:128\nmsgid \"Installed Library from Git URL\"\nmsgstr \"Installed Library from Git URL\"\n\n#: cli/outdated/outdated.go:62\n#: cli/outdated/outdated.go:72\n#: cli/update/update.go:99\n#: cli/update/update.go:109\nmsgid \"Installed version\"\nmsgstr \"Installed version\"\n\n#: commands/bundled_tools.go:50\n#: commands/core/install.go:113\n#: commands/instances.go:709\n#: commands/lib/install.go:88\nmsgid \"Installing %s\"\nmsgstr \"Installing %s\"\n\n#: cli/core/install.go:38\n#: cli/core/install.go:39\nmsgid \"Installs one or more cores and corresponding tool dependencies.\"\nmsgstr \"Installs one or more cores and corresponding tool dependencies.\"\n\n#: cli/lib/install.go:39\n#: cli/lib/install.go:40\nmsgid \"Installs one or more specified libraries into the system.\"\nmsgstr \"Installs one or more specified libraries into the system.\"\n\n#: legacy/builder/container_find_includes.go:378\nmsgid \"Internal error in cache\"\nmsgstr \"Internal error in cache\"\n\n#: cli/cli.go:224\nmsgid \"Invalid Call : should show Help, but it is available only in TEXT mode.\"\nmsgstr \"Invalid Call : should show Help, but it is available only in TEXT mode.\"\n\n#: commands/instances.go:194\nmsgid \"Invalid additional URL: %v\"\nmsgstr \"Invalid additional URL: %v\"\n\n#: cli/core/download.go:55\n#: cli/core/install.go:92\n#: cli/core/uninstall.go:51\n#: cli/core/upgrade.go:79\n#: cli/lib/download.go:50\n#: cli/lib/uninstall.go:51\nmsgid \"Invalid argument passed: %v\"\nmsgstr \"Invalid argument passed: %v\"\n\n#: legacy/builder/phases/sizer.go:160\nmsgid \"Invalid data size regexp: %s\"\nmsgstr \"Invalid data size regexp: %s\"\n\n#: legacy/builder/phases/sizer.go:166\nmsgid \"Invalid eeprom size regexp: %s\"\nmsgstr \"Invalid eeprom size regexp: %s\"\n\n#: commands/instances.go:175\nmsgid \"Invalid instance ID\"\nmsgstr \"Invalid instance ID\"\n\n#: cli/core/upgrade.go:85\nmsgid \"Invalid item %s\"\nmsgstr \"Invalid item %s\"\n\n#: httpclient/httpclient_config.go:44\nmsgid \"Invalid network.proxy '%[1]s': %[2]s\"\nmsgstr \"Invalid network.proxy '%[1]s': %[2]s\"\n\n#: cli/cli.go:185\nmsgid \"Invalid option for --log-level: %s\"\nmsgstr \"Invalid option for --log-level: %s\"\n\n#: cli/cli.go:202\nmsgid \"Invalid output format: %s\"\nmsgstr \"Invalid output format: %s\"\n\n#: cli/core/uninstall.go:57\nmsgid \"Invalid parameter %s: version not allowed\"\nmsgstr \"Invalid parameter %s: version not allowed\"\n\n#: commands/board/list.go:51\nmsgid \"Invalid pid value: '%s'\"\nmsgstr \"Invalid pid value: '%s'\"\n\n#: legacy/builder/phases/sizer.go:150\nmsgid \"Invalid size regexp: %s\"\nmsgstr \"Invalid size regexp: %s\"\n\n#: commands/board/list.go:48\nmsgid \"Invalid vid value: '%s'\"\nmsgstr \"Invalid vid value: '%s'\"\n\n#: cli/compile/compile.go:110\nmsgid \"Just produce the compilation database, without actually compiling.\"\nmsgstr \"Just produce the compilation database, without actually compiling.\"\n\n#: cli/lib/list.go:37\nmsgid \"LIBNAME\"\nmsgstr \"LIBNAME\"\n\n#: cli/lib/check_deps.go:34\n#: cli/lib/install.go:38\nmsgid \"LIBRARY\"\nmsgstr \"LIBRARY\"\n\n#: cli/lib/download.go:34\n#: cli/lib/examples.go:38\n#: cli/lib/search.go:39\n#: cli/lib/uninstall.go:35\nmsgid \"LIBRARY_NAME\"\nmsgstr \"LIBRARY_NAME\"\n\n#: cli/core/list.go:84\nmsgid \"Latest\"\nmsgstr \"Latest\"\n\n#: commands/lib/uninstall.go:37\nmsgid \"Library %s is not installed\"\nmsgstr \"Library %s is not installed\"\n\n#: legacy/builder/constants/constants.go:109\nmsgid \"Library can't use both '%[1]s' and '%[2]s' folders. Double check {0}\"\nmsgstr \"Library can't use both '%[1]s' and '%[2]s' folders. Double check {0}\"\n\n#: cli/outdated/outdated.go:72\n#: cli/update/update.go:109\nmsgid \"Library name\"\nmsgstr \"Library name\"\n\n#: legacy/builder/phases/libraries_builder.go:91\nmsgid \"Library {0} has been declared precompiled:\"\nmsgstr \"Library {0} has been declared precompiled:\"\n\n#: cli/lib/search.go:167\nmsgid \"License: %s\"\nmsgstr \"License: %s\"\n\n#: legacy/builder/builder.go:86\nmsgid \"Linking everything together...\"\nmsgstr \"Linking everything together...\"\n\n#: cli/board/listall.go:37\n#: cli/board/search.go:38\nmsgid \"List all boards that have the support platform installed. You can search\\n\"\n\"for a specific board if you specify the board name\"\nmsgstr \"List all boards that have the support platform installed. You can search\\n\"\n\"for a specific board if you specify the board name\"\n\n#: cli/board/listall.go:36\n#: cli/board/search.go:37\nmsgid \"List all known boards and their corresponding FQBN.\"\nmsgstr \"List all known boards and their corresponding FQBN.\"\n\n#: cli/board/list.go:37\nmsgid \"List connected boards.\"\nmsgstr \"List connected boards.\"\n\n#: cli/compile/compile.go:93\nmsgid \"List of custom build properties separated by commas. Or can be used multiple times for multiple properties.\"\nmsgstr \"List of custom build properties separated by commas. Or can be used multiple times for multiple properties.\"\n\n#: cli/compile/compile.go:107\nmsgid \"List of custom libraries dir paths separated by commas. Or can be used multiple times for multiple libraries dir paths.\"\nmsgstr \"List of custom libraries dir paths separated by commas. Or can be used multiple times for multiple libraries dir paths.\"\n\n#: cli/compile/compile.go:105\nmsgid \"List of paths to libraries root folders. Libraries set this way have top priority in case of conflicts. Can be used multiple times for different libraries.\"\nmsgstr \"List of paths to libraries root folders. Libraries set this way have top priority in case of conflicts. Can be used multiple times for different libraries.\"\n\n#: cli/lib/list.go:50\nmsgid \"List updatable libraries.\"\nmsgstr \"List updatable libraries.\"\n\n#: cli/core/list.go:41\nmsgid \"List updatable platforms.\"\nmsgstr \"List updatable platforms.\"\n\n#: cli/board/board.go:30\nmsgid \"Lists all connected boards.\"\nmsgstr \"Lists all connected boards.\"\n\n#: cli/outdated/outdated.go:38\nmsgid \"Lists cores and libraries that can be upgraded\"\nmsgstr \"Lists cores and libraries that can be upgraded\"\n\n#: commands/instances.go:208\n#: commands/instances.go:219\n#: commands/instances.go:320\nmsgid \"Loading index file: %v\"\nmsgstr \"Loading index file: %v\"\n\n#: commands/instances.go:329\nmsgid \"Loading libraries: %v\"\nmsgstr \"Loading libraries: %v\"\n\n#: cli/lib/list.go:125\nmsgid \"Location\"\nmsgstr \"Location\"\n\n#: legacy/builder/constants/constants.go:111\nmsgid \"Looking for recipes like {0}*{1}\"\nmsgstr \"Looking for recipes like {0}*{1}\"\n\n#: legacy/builder/constants/constants.go:126\nmsgid \"Low memory available, stability problems may occur.\"\nmsgstr \"Low memory available, stability problems may occur.\"\n\n#: cli/lib/search.go:162\nmsgid \"Maintainer: %s\"\nmsgstr \"Maintainer: %s\"\n\n#: cli/arguments/port.go:46\nmsgid \"Max time to wait for port discovery, e.g.: 30s, 1m\"\nmsgstr \"Max time to wait for port discovery, e.g.: 30s, 1m\"\n\n#: cli/cli.go:101\nmsgid \"Messages with this level and above will be logged. Valid levels are: %s, %s, %s, %s, %s, %s, %s\"\nmsgstr \"Messages with this level and above will be logged. Valid levels are: %s, %s, %s, %s, %s, %s, %s\"\n\n#: legacy/builder/constants/constants.go:117\nmsgid \"Missing '{0}' from library in {1}\"\nmsgstr \"Missing '{0}' from library in {1}\"\n\n#: legacy/builder/phases/sizer.go:154\nmsgid \"Missing size regexp\"\nmsgstr \"Missing size regexp\"\n\n#: legacy/builder/constants/constants.go:106\nmsgid \"Multiple libraries were found for \\\"{0}\\\"\"\nmsgstr \"Multiple libraries were found for \\\"{0}\\\"\"\n\n#: cli/board/details.go:194\n#: cli/core/list.go:84\n#: cli/core/search.go:114\n#: cli/lib/list.go:125\n#: cli/outdated/outdated.go:62\nmsgid \"Name\"\nmsgstr \"Name\"\n\n#: cli/lib/search.go:141\nmsgid \"Name: \\\"%s\\\"\"\nmsgstr \"Name: \\\"%s\\\"\"\n\n#: cli/outdated/outdated.go:62\n#: cli/outdated/outdated.go:72\n#: cli/update/update.go:99\n#: cli/update/update.go:109\nmsgid \"New version\"\nmsgstr \"New version\"\n\n#: cli/board/list.go:115\nmsgid \"No boards found.\"\nmsgstr \"No boards found.\"\n\n#: legacy/builder/builder_utils/utils.go:351\nmsgid \"No colon in first line of depfile\"\nmsgstr \"No colon in first line of depfile\"\n\n#: cli/lib/examples.go:103\nmsgid \"No libraries found.\"\nmsgstr \"No libraries found.\"\n\n#: cli/lib/list.go:117\nmsgid \"No libraries installed.\"\nmsgstr \"No libraries installed.\"\n\n#: cli/lib/search.go:125\nmsgid \"No libraries matching your search.\"\nmsgstr \"No libraries matching your search.\"\n\n#: cli/lib/search.go:136\nmsgid \"No libraries matching your search.\\n\"\n\"Did you mean...\\n\"\n\"\"\nmsgstr \"No libraries matching your search.\\n\"\n\"Did you mean...\\n\"\n\"\"\n\n#: cli/core/search.go:124\nmsgid \"No platforms matching your search.\"\nmsgstr \"No platforms matching your search.\"\n\n#: cli/lib/list.go:115\nmsgid \"No updates available.\"\nmsgstr \"No updates available.\"\n\n#: commands/upload/upload.go:407\nmsgid \"No upload port found, using %s as fallback\"\nmsgstr \"No upload port found, using %s as fallback\"\n\n#: legacy/builder/constants/constants.go:125\nmsgid \"Not enough memory; see %s for tips on reducing your footprint.\"\nmsgstr \"Not enough memory; see %s for tips on reducing your footprint.\"\n\n#: legacy/builder/builder_utils/utils.go:284\nmsgid \"Not found: nil\"\nmsgstr \"Not found: nil\"\n\n#: legacy/builder/builder_utils/utils.go:300\n#: legacy/builder/builder_utils/utils.go:313\n#: legacy/builder/builder_utils/utils.go:387\nmsgid \"Not found: {0}\"\nmsgstr \"Not found: {0}\"\n\n#: cli/board/details.go:165\nmsgid \"OS:\"\nmsgstr \"OS:\"\n\n#: cli/board/details.go:129\nmsgid \"Official Arduino board:\"\nmsgstr \"Official Arduino board:\"\n\n#: cli/board/details.go:177\nmsgid \"Option:\"\nmsgstr \"Option:\"\n\n#: cli/compile/compile.go:97\nmsgid \"Optional, can be \\\"%[1]s\\\", \\\"%[2]s\\\", \\\"%[3]s\\\" and \\\"%[4]s\\\". Defaults to \\\"%[1]s\\\". Used to tell gcc which warning level to use (-W flag).\"\nmsgstr \"Optional, can be \\\"%[1]s\\\", \\\"%[2]s\\\", \\\"%[3]s\\\" and \\\"%[4]s\\\". Defaults to \\\"%[1]s\\\". Used to tell gcc which warning level to use (-W flag).\"\n\n#: cli/compile/compile.go:111\nmsgid \"Optional, cleanup the build folder and do not use any cached build.\"\nmsgstr \"Optional, cleanup the build folder and do not use any cached build.\"\n\n#: cli/compile/compile.go:108\nmsgid \"Optional, optimize compile output for debugging, rather than for release.\"\nmsgstr \"Optional, optimize compile output for debugging, rather than for release.\"\n\n#: cli/compile/compile.go:99\nmsgid \"Optional, suppresses almost every output.\"\nmsgstr \"Optional, suppresses almost every output.\"\n\n#: cli/compile/compile.go:98\n#: cli/upload/upload.go:63\nmsgid \"Optional, turns on verbose mode.\"\nmsgstr \"Optional, turns on verbose mode.\"\n\n#: cli/compile/compile.go:109\n#: cli/upload/upload.go:64\nmsgid \"Optional, use the specified programmer to upload.\"\nmsgstr \"Optional, use the specified programmer to upload.\"\n\n#: cli/compile/compile.go:116\nmsgid \"Optional. Path to a .json file that contains a set of replacements of the sketch source code.\"\nmsgstr \"Optional. Path to a .json file that contains a set of replacements of the sketch source code.\"\n\n#: commands/daemon/monitor.go:72\nmsgid \"OutputRate in Null monitor must be a float64\"\nmsgstr \"OutputRate in Null monitor must be a float64\"\n\n#: cli/compile/compile.go:95\nmsgid \"Override a build property with a custom value. Can be used multiple times for multiple properties.\"\nmsgstr \"Override a build property with a custom value. Can be used multiple times for multiple properties.\"\n\n#: cli/config/init.go:54\nmsgid \"Overwrite existing config file.\"\nmsgstr \"Overwrite existing config file.\"\n\n#: cli/core/download.go:36\n#: cli/core/install.go:37\n#: cli/core/uninstall.go:36\n#: cli/core/upgrade.go:36\nmsgid \"PACKAGER\"\nmsgstr \"PACKAGER\"\n\n#: cli/board/details.go:145\nmsgid \"Package URL:\"\nmsgstr \"Package URL:\"\n\n#: cli/board/details.go:144\nmsgid \"Package maintainer:\"\nmsgstr \"Package maintainer:\"\n\n#: cli/board/details.go:143\nmsgid \"Package name:\"\nmsgstr \"Package name:\"\n\n#: cli/board/details.go:147\nmsgid \"Package online help:\"\nmsgstr \"Package online help:\"\n\n#: cli/board/details.go:146\nmsgid \"Package website:\"\nmsgstr \"Package website:\"\n\n#: cli/lib/search.go:164\nmsgid \"Paragraph: %s\"\nmsgstr \"Paragraph: %s\"\n\n#: cli/cli.go:102\nmsgid \"Path to the file where logs will be written.\"\nmsgstr \"Path to the file where logs will be written.\"\n\n#: cli/compile/compile.go:91\nmsgid \"Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS.\"\nmsgstr \"Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS.\"\n\n#: commands/upload/upload.go:386\nmsgid \"Performing 1200-bps touch reset on serial port %s\"\nmsgstr \"Performing 1200-bps touch reset on serial port %s\"\n\n#: commands/core/install.go:74\nmsgid \"Platform %s already installed\"\nmsgstr \"Platform %s already installed\"\n\n#: cli/core/upgrade.go:99\nmsgid \"Platform %s is already at the latest version\"\nmsgstr \"Platform %s is already at the latest version\"\n\n#: cli/board/search.go:86\nmsgid \"Platform ID\"\nmsgstr \"Platform ID\"\n\n#: cli/board/details.go:153\nmsgid \"Platform URL:\"\nmsgstr \"Platform URL:\"\n\n#: cli/board/details.go:152\nmsgid \"Platform architecture:\"\nmsgstr \"Platform architecture:\"\n\n#: cli/board/details.go:151\nmsgid \"Platform category:\"\nmsgstr \"Platform category:\"\n\n#: cli/board/details.go:158\nmsgid \"Platform checksum:\"\nmsgstr \"Platform checksum:\"\n\n#: cli/board/details.go:154\nmsgid \"Platform file name:\"\nmsgstr \"Platform file name:\"\n\n#: cli/board/details.go:150\nmsgid \"Platform name:\"\nmsgstr \"Platform name:\"\n\n#: cli/board/details.go:156\nmsgid \"Platform size (bytes):\"\nmsgstr \"Platform size (bytes):\"\n\n#: legacy/builder/constants/constants.go:115\nmsgid \"Platform {0} (package {1}) is unknown\"\nmsgstr \"Platform {0} (package {1}) is unknown\"\n\n#: cli/board/list.go:87\n#: cli/board/list.go:125\nmsgid \"Port\"\nmsgstr \"Port\"\n\n#: legacy/builder/phases/libraries_builder.go:101\n#: legacy/builder/phases/libraries_builder.go:109\nmsgid \"Precompiled library in \\\"{0}\\\" not found\"\nmsgstr \"Precompiled library in \\\"{0}\\\" not found\"\n\n#: cli/board/details.go:42\nmsgid \"Print details about a board.\"\nmsgstr \"Print details about a board.\"\n\n#: cli/compile/compile.go:87\nmsgid \"Print preprocessed code to stdout instead of compiling.\"\nmsgstr \"Print preprocessed code to stdout instead of compiling.\"\n\n#: cli/cli.go:100\nmsgid \"Print the logs on the standard output.\"\nmsgstr \"Print the logs on the standard output.\"\n\n#: cli/config/dump.go:31\nmsgid \"Prints the current configuration\"\nmsgstr \"Prints the current configuration\"\n\n#: cli/config/dump.go:32\nmsgid \"Prints the current configuration.\"\nmsgstr \"Prints the current configuration.\"\n\n#: cli/board/details.go:93\nmsgid \"Programmer name\"\nmsgstr \"Programmer name\"\n\n#: cli/debug/debug.go:65\nmsgid \"Programmer to use for debugging\"\nmsgstr \"Programmer to use for debugging\"\n\n#: cli/board/details.go:194\nmsgid \"Programmers:\"\nmsgstr \"Programmers:\"\n\n#: legacy/builder/constants/constants.go:116\nmsgid \"Progress {0}\"\nmsgstr \"Progress {0}\"\n\n#: cli/board/list.go:125\nmsgid \"Protocol\"\nmsgstr \"Protocol\"\n\n#: cli/lib/search.go:174\nmsgid \"Provides includes: %s\"\nmsgstr \"Provides includes: %s\"\n\n#: cli/config/remove.go:31\n#: cli/config/remove.go:32\nmsgid \"Removes one or more values from a setting.\"\nmsgstr \"Removes one or more values from a setting.\"\n\n#: commands/instances.go:719\n#: commands/lib/install.go:101\nmsgid \"Replacing %[1]s with %[2]s\"\nmsgstr \"Replacing %[1]s with %[2]s\"\n\n#: cli/board/details.go:162\nmsgid \"Required tool:\"\nmsgstr \"Required tool:\"\n\n#: cli/daemon/daemon.go:50\nmsgid \"Run as a daemon on port %s\"\nmsgstr \"Run as a daemon on port %s\"\n\n#: cli/daemon/daemon.go:51\nmsgid \"Running as a daemon the initialization of cores and libraries is done only once.\"\nmsgstr \"Running as a daemon the initialization of cores and libraries is done only once.\"\n\n#: legacy/builder/phases/core_builder.go:49\nmsgid \"Running normal build of the core...\"\nmsgstr \"Running normal build of the core...\"\n\n#: legacy/builder/constants/constants.go:119\nmsgid \"Running recipe: {0}\"\nmsgstr \"Running recipe: {0}\"\n\n#: cli/compile/compile.go:89\nmsgid \"Save build artifacts in this directory.\"\nmsgstr \"Save build artifacts in this directory.\"\n\n#: cli/core/search.go:50\nmsgid \"Search for a core in Boards Manager using the specified keywords.\"\nmsgstr \"Search for a core in Boards Manager using the specified keywords.\"\n\n#: cli/core/search.go:49\nmsgid \"Search for a core in Boards Manager.\"\nmsgstr \"Search for a core in Boards Manager.\"\n\n#: cli/lib/search.go:41\nmsgid \"Search for one or more libraries data (case insensitive search).\"\nmsgstr \"Search for one or more libraries data (case insensitive search).\"\n\n#: cli/lib/search.go:40\nmsgid \"Searches for one or more libraries data.\"\nmsgstr \"Searches for one or more libraries data.\"\n\n#: legacy/builder/constants/constants.go:113\nmsgid \"Selected board depends on '{0}' core (not installed).\"\nmsgstr \"Selected board depends on '{0}' core (not installed).\"\n\n#: commands/board/attach.go:109\nmsgid \"Selected fqbn: %s\"\nmsgstr \"Selected fqbn: %s\"\n\n#: cli/lib/search.go:163\nmsgid \"Sentence: %s\"\nmsgstr \"Sentence: %s\"\n\n#: cli/config/set.go:32\n#: cli/config/set.go:33\nmsgid \"Sets a setting value.\"\nmsgstr \"Sets a setting value.\"\n\n#: cli/config/init.go:52\n#: cli/config/init.go:53\nmsgid \"Sets where to save the configuration file.\"\nmsgstr \"Sets where to save the configuration file.\"\n\n#: legacy/builder/constants/constants.go:120\nmsgid \"Setting build path to {0}\"\nmsgstr \"Setting build path to {0}\"\n\n#: cli/config/delete.go:57\n#: cli/config/validate.go:43\nmsgid \"Settings key doesn't exist\"\nmsgstr \"Settings key doesn't exist\"\n\n#: cli/core/search.go:55\nmsgid \"Show all available core versions.\"\nmsgstr \"Show all available core versions.\"\n\n#: cli/compile/compile.go:86\nmsgid \"Show all build properties used instead of compiling.\"\nmsgstr \"Show all build properties used instead of compiling.\"\n\n#: cli/board/listall.go:45\n#: cli/board/search.go:46\nmsgid \"Show also boards marked as 'hidden' in the platform\"\nmsgstr \"Show also boards marked as 'hidden' in the platform\"\n\n#: cli/board/details.go:49\nmsgid \"Show full board details\"\nmsgstr \"Show full board details\"\n\n#: cli/board/details.go:43\nmsgid \"Show information about a board, in particular if the board has options to be specified in the FQBN.\"\nmsgstr \"Show information about a board, in particular if the board has options to be specified in the FQBN.\"\n\n#: cli/lib/examples.go:45\n#: cli/lib/list.go:49\nmsgid \"Show libraries for the specified board FQBN.\"\nmsgstr \"Show libraries for the specified board FQBN.\"\n\n#: cli/lib/search.go:46\nmsgid \"Show library names only.\"\nmsgstr \"Show library names only.\"\n\n#: cli/board/details.go:51\nmsgid \"Show list of available programmers\"\nmsgstr \"Show list of available programmers\"\n\n#: cli/debug/debug.go:68\nmsgid \"Show metadata about the debug session instead of starting the debugger.\"\nmsgstr \"Show metadata about the debug session instead of starting the debugger.\"\n\n#: cli/update/update.go:46\nmsgid \"Show outdated cores and libraries after index update\"\nmsgstr \"Show outdated cores and libraries after index update\"\n\n#: cli/lib/list.go:38\nmsgid \"Shows a list of installed libraries.\"\nmsgstr \"Shows a list of installed libraries.\"\n\n#: cli/lib/list.go:39\nmsgid \"Shows a list of installed libraries.\\n\"\n\"\\n\"\n\"If the LIBNAME parameter is specified the listing is limited to that specific\\n\"\n\"library. By default the libraries provided as built-in by platforms/core are\\n\"\n\"not listed, they can be listed by adding the --all flag.\"\nmsgstr \"Shows a list of installed libraries.\\n\"\n\"\\n\"\n\"If the LIBNAME parameter is specified the listing is limited to that specific\\n\"\n\"library. By default the libraries provided as built-in by platforms/core are\\n\"\n\"not listed, they can be listed by adding the --all flag.\"\n\n#: cli/core/list.go:35\n#: cli/core/list.go:36\nmsgid \"Shows the list of installed platforms.\"\nmsgstr \"Shows the list of installed platforms.\"\n\n#: cli/lib/examples.go:39\nmsgid \"Shows the list of the examples for libraries.\"\nmsgstr \"Shows the list of the examples for libraries.\"\n\n#: cli/lib/examples.go:40\nmsgid \"Shows the list of the examples for libraries. A name may be given as argument to search a specific library.\"\nmsgstr \"Shows the list of the examples for libraries. A name may be given as argument to search a specific library.\"\n\n#: cli/version/version.go:34\nmsgid \"Shows the version number of Arduino CLI which is installed on your system.\"\nmsgstr \"Shows the version number of Arduino CLI which is installed on your system.\"\n\n#: cli/version/version.go:33\nmsgid \"Shows version number of Arduino CLI.\"\nmsgstr \"Shows version number of Arduino CLI.\"\n\n#: cli/board/details.go:167\nmsgid \"Size (bytes):\"\nmsgstr \"Size (bytes):\"\n\n#: legacy/builder/constants/constants.go:128\nmsgid \"Sketch cannot be located in build path. Please specify a different build path\"\nmsgstr \"Sketch cannot be located in build path. Please specify a different build path\"\n\n#: cli/sketch/new.go:68\nmsgid \"Sketch created in: %s\"\nmsgstr \"Sketch created in: %s\"\n\n#: legacy/builder/constants/constants.go:124\nmsgid \"Sketch too big; see %s for tips on reducing it.\"\nmsgstr \"Sketch too big; see %s for tips on reducing it.\"\n\n#: legacy/builder/constants/constants.go:121\nmsgid \"Sketch uses {0} bytes ({2}%%) of program storage space. Maximum is {1} bytes.\"\nmsgstr \"Sketch uses {0} bytes ({2}%%) of program storage space. Maximum is {1} bytes.\"\n\n#: cli/compile/compile.go:137\n#: cli/sketch/archive.go:66\n#: cli/upload/upload.go:88\nmsgid \"Sketches with .pde extension are deprecated, please rename the following files to .ino:\"\nmsgstr \"Sketches with .pde extension are deprecated, please rename the following files to .ino:\"\n\n#: legacy/builder/phases/linker.go:35\nmsgid \"Skip linking of final executable.\"\nmsgstr \"Skip linking of final executable.\"\n\n#: commands/upload/upload.go:379\nmsgid \"Skipping 1200-bps touch reset: no serial port selected!\"\nmsgstr \"Skipping 1200-bps touch reset: no serial port selected!\"\n\n#: legacy/builder/builder_utils/utils.go:476\nmsgid \"Skipping archive creation of: {0}\"\nmsgstr \"Skipping archive creation of: {0}\"\n\n#: legacy/builder/builder_utils/utils.go:269\nmsgid \"Skipping compile of: {0}\"\nmsgstr \"Skipping compile of: {0}\"\n\n#: legacy/builder/constants/constants.go:103\nmsgid \"Skipping dependencies detection for precompiled library {0}\"\nmsgstr \"Skipping dependencies detection for precompiled library {0}\"\n\n#: commands/core/install.go:177\n#: commands/instances.go:853\nmsgid \"Skipping platform configuration\"\nmsgstr \"Skipping platform configuration\"\n\n#: legacy/builder/recipe_runner.go:58\nmsgid \"Skipping: {0}\"\nmsgstr \"Skipping: {0}\"\n\n#: arduino/serialutils/serialutils.go:133\nmsgid \"TOUCH: error during reset: %s\"\nmsgstr \"TOUCH: error during reset: %s\"\n\n#: cli/daemon/daemon.go:56\nmsgid \"The TCP port the daemon will listen to\"\nmsgstr \"The TCP port the daemon will listen to\"\n\n#: cli/board/attach.go:45\nmsgid \"The connected devices search timeout, raise it if your board doesn't show up (e.g. to %s).\"\nmsgstr \"The connected devices search timeout, raise it if your board doesn't show up (e.g. to %s).\"\n\n#: cli/board/list.go:45\nmsgid \"The connected devices search timeout, raise it if your board doesn't show up e.g.: 10s\"\nmsgstr \"The connected devices search timeout, raise it if your board doesn't show up e.g.: 10s\"\n\n#: cli/cli.go:105\nmsgid \"The custom config file (if not specified the default will be used).\"\nmsgstr \"The custom config file (if not specified the default will be used).\"\n\n#: cli/core/install.go:66\nmsgid \"The flags --run-post-install and --skip-post-install can't be both set at the same time.\"\nmsgstr \"The flags --run-post-install and --skip-post-install can't be both set at the same time.\"\n\n#: cli/config/add.go:51\nmsgid \"The key '%[1]v' is not a list of items, can't add to it.\\n\"\n\"Maybe use '%[2]s'?\"\nmsgstr \"The key '%[1]v' is not a list of items, can't add to it.\\n\"\n\"Maybe use '%[2]s'?\"\n\n#: cli/config/remove.go:51\nmsgid \"The key '%[1]v' is not a list of items, can't remove from it.\\n\"\n\"Maybe use '%[2]s'?\"\nmsgstr \"The key '%[1]v' is not a list of items, can't remove from it.\\n\"\n\"Maybe use '%[2]s'?\"\n\n#: cli/cli.go:103\nmsgid \"The output format for the logs, can be {%s|%s}.\"\nmsgstr \"The output format for the logs, can be {%s|%s}.\"\n\n#: cli/cli.go:104\nmsgid \"The output format, can be {%s|%s}.\"\nmsgstr \"The output format, can be {%s|%s}.\"\n\n#: legacy/builder/phases/libraries_builder.go:151\nmsgid \"The platform does not support '{0}' for precompiled libraries.\"\nmsgstr \"The platform does not support '{0}' for precompiled libraries.\"\n\n#: cli/lib/upgrade.go:34\nmsgid \"This command upgrades an installed library to the latest available version. Multiple libraries can be passed separated by a space. If no arguments are provided, the command will upgrade all the installed libraries where an update is available.\"\nmsgstr \"This command upgrades an installed library to the latest available version. Multiple libraries can be passed separated by a space. If no arguments are provided, the command will upgrade all the installed libraries where an update is available.\"\n\n#: cli/outdated/outdated.go:39\nmsgid \"This commands shows a list of installed cores and/or libraries\\n\"\n\"that can be upgraded. If nothing needs to be updated the output is empty.\"\nmsgstr \"This commands shows a list of installed cores and/or libraries\\n\"\n\"that can be upgraded. If nothing needs to be updated the output is empty.\"\n\n#: commands/bundled_tools.go:45\n#: commands/core/install.go:81\n#: commands/instances.go:770\nmsgid \"Tool %s already installed\"\nmsgstr \"Tool %s already installed\"\n\n#: cli/debug/debug.go:148\nmsgid \"Toolchain custom configurations\"\nmsgstr \"Toolchain custom configurations\"\n\n#: cli/debug/debug.go:142\nmsgid \"Toolchain path\"\nmsgstr \"Toolchain path\"\n\n#: cli/debug/debug.go:143\nmsgid \"Toolchain prefix\"\nmsgstr \"Toolchain prefix\"\n\n#: cli/debug/debug.go:141\nmsgid \"Toolchain type\"\nmsgstr \"Toolchain type\"\n\n#: legacy/builder/constants/constants.go:118\nmsgid \"Ts: {0} - Running: {1}\"\nmsgstr \"Ts: {0} - Running: {1}\"\n\n#: cli/burnbootloader/burnbootloader.go:56\nmsgid \"Turns on verbose mode.\"\nmsgstr \"Turns on verbose mode.\"\n\n#: cli/board/list.go:87\n#: cli/board/list.go:125\nmsgid \"Type\"\nmsgstr \"Type\"\n\n#: cli/lib/search.go:171\nmsgid \"Types: %s\"\nmsgstr \"Types: %s\"\n\n#: cli/board/details.go:169\nmsgid \"URL:\"\nmsgstr \"URL:\"\n\n#: legacy/builder/constants/constants.go:95\nmsgid \"Unable to cache built core, please tell {0} maintainers to follow %s\"\nmsgstr \"Unable to cache built core, please tell {0} maintainers to follow %s\"\n\n#: legacy/builder/constants/constants.go:101\nmsgid \"Unable to find {0} in {1}\"\nmsgstr \"Unable to find {0} in {1}\"\n\n#: configuration/configuration.go:125\nmsgid \"Unable to get Documents Folder: %v\"\nmsgstr \"Unable to get Documents Folder: %v\"\n\n#: configuration/configuration.go:100\nmsgid \"Unable to get Local App Data Folder: %v\"\nmsgstr \"Unable to get Local App Data Folder: %v\"\n\n#: configuration/configuration.go:88\n#: configuration/configuration.go:113\nmsgid \"Unable to get user home dir: %v\"\nmsgstr \"Unable to get user home dir: %v\"\n\n#: cli/cli.go:171\nmsgid \"Unable to open file for logging: %s\"\nmsgstr \"Unable to open file for logging: %s\"\n\n#: commands/core/uninstall.go:82\n#: commands/lib/uninstall.go:39\nmsgid \"Uninstalling %s\"\nmsgstr \"Uninstalling %s\"\n\n#: commands/core/uninstall.go:98\n#: commands/instances.go:832\nmsgid \"Uninstalling %s, tool is no more required\"\nmsgstr \"Uninstalling %s, tool is no more required\"\n\n#: cli/core/uninstall.go:37\n#: cli/core/uninstall.go:38\nmsgid \"Uninstalls one or more cores and corresponding tool dependencies if no longer used.\"\nmsgstr \"Uninstalls one or more cores and corresponding tool dependencies if no longer used.\"\n\n#: cli/lib/uninstall.go:36\n#: cli/lib/uninstall.go:37\nmsgid \"Uninstalls one or more libraries.\"\nmsgstr \"Uninstalls one or more libraries.\"\n\n#: cli/board/list.go:157\nmsgid \"Unknown\"\nmsgstr \"Unknown\"\n\n#: legacy/builder/constants/constants.go:129\nmsgid \"Unknown sketch file extension: {0}\"\nmsgstr \"Unknown sketch file extension: {0}\"\n\n#: cli/update/update.go:40\nmsgid \"Updates the index of cores and libraries\"\nmsgstr \"Updates the index of cores and libraries\"\n\n#: cli/update/update.go:41\nmsgid \"Updates the index of cores and libraries to the latest versions.\"\nmsgstr \"Updates the index of cores and libraries to the latest versions.\"\n\n#: cli/core/update_index.go:36\nmsgid \"Updates the index of cores to the latest version.\"\nmsgstr \"Updates the index of cores to the latest version.\"\n\n#: cli/core/update_index.go:35\nmsgid \"Updates the index of cores.\"\nmsgstr \"Updates the index of cores.\"\n\n#: cli/lib/update_index.go:35\nmsgid \"Updates the libraries index to the latest version.\"\nmsgstr \"Updates the libraries index to the latest version.\"\n\n#: cli/lib/update_index.go:34\nmsgid \"Updates the libraries index.\"\nmsgstr \"Updates the libraries index.\"\n\n#: commands/instances.go:792\nmsgid \"Updating %s\"\nmsgstr \"Updating %s\"\n\n#: commands/instances.go:450\n#: commands/instances.go:476\n#: commands/instances.go:506\nmsgid \"Updating index: %s\"\nmsgstr \"Updating index: %s\"\n\n#: commands/instances.go:377\nmsgid \"Updating index: library_index.json.gz\"\nmsgstr \"Updating index: library_index.json.gz\"\n\n#: commands/instances.go:387\nmsgid \"Updating index: library_index.json.sig\"\nmsgstr \"Updating index: library_index.json.sig\"\n\n#: cli/upgrade/upgrade.go:40\nmsgid \"Upgrades installed cores and libraries to latest version.\"\nmsgstr \"Upgrades installed cores and libraries to latest version.\"\n\n#: cli/upgrade/upgrade.go:39\nmsgid \"Upgrades installed cores and libraries.\"\nmsgstr \"Upgrades installed cores and libraries.\"\n\n#: cli/lib/upgrade.go:33\nmsgid \"Upgrades installed libraries.\"\nmsgstr \"Upgrades installed libraries.\"\n\n#: cli/core/upgrade.go:37\n#: cli/core/upgrade.go:38\nmsgid \"Upgrades one or all installed platforms to the latest version.\"\nmsgstr \"Upgrades one or all installed platforms to the latest version.\"\n\n#: commands/core/install.go:117\nmsgid \"Upgrading %[1]s with %[2]s\"\nmsgstr \"Upgrading %[1]s with %[2]s\"\n\n#: cli/upload/upload.go:50\nmsgid \"Upload Arduino sketches.\"\nmsgstr \"Upload Arduino sketches.\"\n\n#: cli/upload/upload.go:51\nmsgid \"Upload Arduino sketches. This does NOT compile the sketch prior to upload.\"\nmsgstr \"Upload Arduino sketches. This does NOT compile the sketch prior to upload.\"\n\n#: cli/arguments/port.go:44\nmsgid \"Upload port address, e.g.: COM3 or /dev/ttyACM2\"\nmsgstr \"Upload port address, e.g.: COM3 or /dev/ttyACM2\"\n\n#: commands/upload/upload.go:404\nmsgid \"Upload port found on %s\"\nmsgstr \"Upload port found on %s\"\n\n#: cli/arguments/port.go:45\nmsgid \"Upload port protocol, e.g: serial\"\nmsgstr \"Upload port protocol, e.g: serial\"\n\n#: cli/compile/compile.go:100\nmsgid \"Upload the binary after the compilation.\"\nmsgstr \"Upload the binary after the compilation.\"\n\n#: cli/burnbootloader/burnbootloader.go:47\nmsgid \"Upload the bootloader on the board using an external programmer.\"\nmsgstr \"Upload the bootloader on the board using an external programmer.\"\n\n#: cli/burnbootloader/burnbootloader.go:46\nmsgid \"Upload the bootloader.\"\nmsgstr \"Upload the bootloader.\"\n\n#: cli/compile/compile.go:218\n#: cli/upload/upload.go:117\nmsgid \"Uploading to specified board using %s protocol requires the following info:\"\nmsgstr \"Uploading to specified board using %s protocol requires the following info:\"\n\n#: cli/usage.go:25\nmsgid \"Usage:\"\nmsgstr \"Usage:\"\n\n#: cli/usage.go:32\nmsgid \"Use %s for more information about a command.\"\nmsgstr \"Use %s for more information about a command.\"\n\n#: cli/burnbootloader/burnbootloader.go:57\nmsgid \"Use the specified programmer to upload.\"\nmsgstr \"Use the specified programmer to upload.\"\n\n#: arduino/libraries/librariesmanager/install.go:62\n#: arduino/libraries/librariesmanager/install.go:78\n#: arduino/libraries/librariesmanager/install.go:100\n#: arduino/libraries/librariesmanager/install.go:184\nmsgid \"User directory not set\"\nmsgstr \"User directory not set\"\n\n#: legacy/builder/constants/constants.go:132\nmsgid \"Using board '{0}' from platform in folder: {1}\"\nmsgstr \"Using board '{0}' from platform in folder: {1}\"\n\n#: legacy/builder/constants/constants.go:135\nmsgid \"Using cached library dependencies for file: {0}\"\nmsgstr \"Using cached library dependencies for file: {0}\"\n\n#: legacy/builder/constants/constants.go:133\nmsgid \"Using core '{0}' from platform in folder: {1}\"\nmsgstr \"Using core '{0}' from platform in folder: {1}\"\n\n#: legacy/builder/constants/constants.go:130\nmsgid \"Using library {0} at version {1} in folder: {2} {3}\"\nmsgstr \"Using library {0} at version {1} in folder: {2} {3}\"\n\n#: legacy/builder/constants/constants.go:131\nmsgid \"Using library {0} in folder: {1} {2}\"\nmsgstr \"Using library {0} in folder: {1} {2}\"\n\n#: legacy/builder/phases/core_builder.go:107\nmsgid \"Using precompiled core: {0}\"\nmsgstr \"Using precompiled core: {0}\"\n\n#: legacy/builder/phases/libraries_builder.go:98\n#: legacy/builder/phases/libraries_builder.go:106\nmsgid \"Using precompiled library in {0}\"\nmsgstr \"Using precompiled library in {0}\"\n\n#: legacy/builder/constants/constants.go:134\nmsgid \"Using previously compiled file: {0}\"\nmsgstr \"Using previously compiled file: {0}\"\n\n#: cli/core/download.go:36\n#: cli/core/install.go:37\nmsgid \"VERSION\"\nmsgstr \"VERSION\"\n\n#: cli/lib/check_deps.go:34\n#: cli/lib/install.go:38\nmsgid \"VERSION_NUMBER\"\nmsgstr \"VERSION_NUMBER\"\n\n#: cli/burnbootloader/burnbootloader.go:55\n#: cli/compile/compile.go:102\n#: cli/upload/upload.go:62\nmsgid \"Verify uploaded binary after the upload.\"\nmsgstr \"Verify uploaded binary after the upload.\"\n\n#: cli/core/search.go:114\nmsgid \"Version\"\nmsgstr \"Version\"\n\n#: cli/lib/search.go:172\nmsgid \"Versions: %s\"\nmsgstr \"Versions: %s\"\n\n#: legacy/builder/constants/constants.go:136\nmsgid \"WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'\"\nmsgstr \"WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'\"\n\n#: legacy/builder/constants/constants.go:138\nmsgid \"WARNING: Spurious {0} folder in '{1}' library\"\nmsgstr \"WARNING: Spurious {0} folder in '{1}' library\"\n\n#: commands/core/install.go:173\n#: commands/instances.go:849\nmsgid \"WARNING: cannot run post install: %s\"\nmsgstr \"WARNING: cannot run post install: %s\"\n\n#: legacy/builder/constants/constants.go:110\nmsgid \"WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s).\"\nmsgstr \"WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s).\"\n\n#: commands/upload/upload.go:393\nmsgid \"Waiting for upload port...\"\nmsgstr \"Waiting for upload port...\"\n\n#: legacy/builder/constants/constants.go:112\nmsgid \"Warning: Board {0}:{1}:{2} doesn''t define a %s preference. Auto-set to: {3}\"\nmsgstr \"Warning: Board {0}:{1}:{2} doesn''t define a %s preference. Auto-set to: {3}\"\n\n#: legacy/builder/constants/constants.go:137\nmsgid \"Warning: platform.txt from core '{0}' contains deprecated {1}, automatically converted to {2}. Consider upgrading this core.\"\nmsgstr \"Warning: platform.txt from core '{0}' contains deprecated {1}, automatically converted to {2}. Consider upgrading this core.\"\n\n#: commands/upload/upload.go:288\nmsgid \"Warning: tool '%s' is not installed. It might not be available for your OS.\"\nmsgstr \"Warning: tool '%s' is not installed. It might not be available for your OS.\"\n\n#: cli/lib/search.go:165\nmsgid \"Website: %s\"\nmsgstr \"Website: %s\"\n\n#: cli/compile/compile.go:103\nmsgid \"When specified, VID/PID specific build properties are used, if board supports them.\"\nmsgstr \"When specified, VID/PID specific build properties are used, if board supports them.\"\n\n#: cli/config/init.go:42\nmsgid \"Writes current configuration to a configuration file.\"\nmsgstr \"Writes current configuration to a configuration file.\"\n\n#: cli/config/init.go:45\nmsgid \"Writes current configuration to the configuration file in the data directory.\"\nmsgstr \"Writes current configuration to the configuration file in the data directory.\"\n\n#: cli/config/set.go:76\nmsgid \"Writing config file: %v\"\nmsgstr \"Writing config file: %v\"\n\n#: cli/core/list.go:88\n#: cli/core/search.go:118\nmsgid \"[DEPRECATED] %s\"\nmsgstr \"[DEPRECATED] %s\"\n\n#: commands/upload/upload.go:302\nmsgid \"a programmer is required to upload for this board\"\nmsgstr \"a programmer is required to upload for this board\"\n\n#: commands/sketch/archive.go:70\nmsgid \"archive already exists\"\nmsgstr \"archive already exists\"\n\n#: arduino/resources/checksums.go:80\nmsgid \"archive hash differs from hash in index\"\nmsgstr \"archive hash differs from hash in index\"\n\n#: arduino/libraries/librariesmanager/install.go:131\nmsgid \"archive is not valid: multiple files found in zip file top level\"\nmsgstr \"archive is not valid: multiple files found in zip file top level\"\n\n#: cli/sketch/archive.go:38\nmsgid \"archivePath\"\nmsgstr \"archivePath\"\n\n#: legacy/builder/preprocess_sketch.go:103\nmsgid \"arduino-preprocessor pattern is missing\"\nmsgstr \"arduino-preprocessor pattern is missing\"\n\n#: commands/upload/upload.go:553\nmsgid \"autodetect build artifact: %s\"\nmsgstr \"autodetect build artifact: %s\"\n\n#: commands/upload/upload.go:538\nmsgid \"binary file not found in %s\"\nmsgstr \"binary file not found in %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:189\nmsgid \"board %s:%s not found\"\nmsgstr \"board %s:%s not found\"\n\n#: commands/board/list.go:40\nmsgid \"board not found\"\nmsgstr \"board not found\"\n\n#: cli/board/listall.go:35\n#: cli/board/search.go:36\nmsgid \"boardname\"\nmsgstr \"boardname\"\n\n#: commands/upload/upload.go:452\nmsgid \"burn bootloader error: %s\"\nmsgstr \"burn bootloader error: %s\"\n\n#: arduino/discovery/discovery.go:297\n#: arduino/discovery/discovery.go:318\n#: arduino/discovery/discovery.go:338\n#: arduino/discovery/discovery.go:361\n#: arduino/discovery/discovery.go:384\n#: arduino/discovery/discovery.go:407\nmsgid \"calling %[1]s: %[2]w\"\nmsgstr \"calling %[1]s: %[2]w\"\n\n#: commands/instances.go:525\nmsgid \"can't create data directory %[1]s: %[2]s\"\nmsgstr \"can't create data directory %[1]s: %[2]s\"\n\n#: commands/core/install.go:130\nmsgid \"can't find dependencies for platform %[1]s: %[2]w\"\nmsgstr \"can't find dependencies for platform %[1]s: %[2]w\"\n\n#: arduino/cores/status.go:123\nmsgid \"can't find latest release of %s\"\nmsgstr \"can't find latest release of %s\"\n\n#: commands/core/list.go:64\nmsgid \"can't find latest release of core %s\"\nmsgstr \"can't find latest release of core %s\"\n\n#: arduino/sketch/sketch.go:101\nmsgid \"can't find main Sketch file in %s\"\nmsgstr \"can't find main Sketch file in %s\"\n\n#: arduino/cores/packagemanager/loader.go:749\nmsgid \"can't find pattern for discovery with id %s\"\nmsgstr \"can't find pattern for discovery with id %s\"\n\n#: executils/output.go:52\nmsgid \"can't retrieve standard error stream: %s\"\nmsgstr \"can't retrieve standard error stream: %s\"\n\n#: executils/output.go:34\nmsgid \"can't retrieve standard output stream: %s\"\nmsgstr \"can't retrieve standard output stream: %s\"\n\n#: commands/compile/compile.go:181\nmsgid \"cannot create build cache directory: %s\"\nmsgstr \"cannot create build cache directory: %s\"\n\n#: commands/compile/compile.go:151\nmsgid \"cannot create build directory: %s\"\nmsgstr \"cannot create build directory: %s\"\n\n#: commands/upload/upload.go:495\n#: commands/upload/upload.go:502\nmsgid \"cannot execute upload tool: %s\"\nmsgstr \"cannot execute upload tool: %s\"\n\n#: commands/board/attach.go:107\nmsgid \"cannot export sketch metadata: %s\"\nmsgstr \"cannot export sketch metadata: %s\"\n\n#: commands/upload/upload.go:87\nmsgid \"cannot find tool: undefined '%s' property\"\nmsgstr \"cannot find tool: undefined '%s' property\"\n\n#: commands/instances.go:715\n#: commands/lib/install.go:97\nmsgid \"checking lib install prerequisites: %s\"\nmsgstr \"checking lib install prerequisites: %s\"\n\n#: arduino/resources/install.go:39\nmsgid \"checking local archive integrity\"\nmsgstr \"checking local archive integrity\"\n\n#: commands/upload/upload.go:449\nmsgid \"chip erase error: %s\"\nmsgstr \"chip erase error: %s\"\n\n#: legacy/builder/wipeout_build_path_if_build_options_changed.go:85\n#: legacy/builder/wipeout_build_path_if_build_options_changed.go:89\nmsgid \"cleaning build path\"\nmsgstr \"cleaning build path\"\n\n#: cli/cli.go:69\nmsgid \"command\"\nmsgstr \"command\"\n\n#: arduino/discovery/discovery.go:301\n#: arduino/discovery/discovery.go:322\n#: arduino/discovery/discovery.go:342\n#: arduino/discovery/discovery.go:365\n#: arduino/discovery/discovery.go:388\n#: arduino/discovery/discovery.go:411\nmsgid \"command failed: %s\"\nmsgstr \"command failed: %s\"\n\n#: arduino/discovery/discovery.go:299\nmsgid \"communication out of sync, expected 'hello', received '%s'\"\nmsgstr \"communication out of sync, expected 'hello', received '%s'\"\n\n#: arduino/discovery/discovery.go:386\nmsgid \"communication out of sync, expected 'list', received '%s'\"\nmsgstr \"communication out of sync, expected 'list', received '%s'\"\n\n#: arduino/discovery/discovery.go:363\nmsgid \"communication out of sync, expected 'quit', received '%s'\"\nmsgstr \"communication out of sync, expected 'quit', received '%s'\"\n\n#: arduino/discovery/discovery.go:320\nmsgid \"communication out of sync, expected 'start', received '%s'\"\nmsgstr \"communication out of sync, expected 'start', received '%s'\"\n\n#: arduino/discovery/discovery.go:409\nmsgid \"communication out of sync, expected 'start_sync', received '%s'\"\nmsgstr \"communication out of sync, expected 'start_sync', received '%s'\"\n\n#: arduino/discovery/discovery.go:340\nmsgid \"communication out of sync, expected 'stop', received '%s'\"\nmsgstr \"communication out of sync, expected 'stop', received '%s'\"\n\n#: commands/debug/debug_info.go:123\n#: commands/upload/upload.go:353\nmsgid \"compiled sketch not found in %s\"\nmsgstr \"compiled sketch not found in %s\"\n\n#: arduino/resources/checksums.go:76\nmsgid \"computing hash: %s\"\nmsgstr \"computing hash: %s\"\n\n#: commands/compile/compile.go:282\n#: commands/lib/list.go:108\nmsgid \"converting library %[1]s to rpc struct: %[2]w\"\nmsgstr \"converting library %[1]s to rpc struct: %[2]w\"\n\n#: commands/compile/compile.go:273\nmsgid \"copying output file %s\"\nmsgstr \"copying output file %s\"\n\n#: commands/upload/upload.go:610\nmsgid \"could not find a valid build artifact\"\nmsgstr \"could not find a valid build artifact\"\n\n#: arduino/cores/packagemanager/loader.go:721\nmsgid \"creating discovery: %s\"\nmsgstr \"creating discovery: %s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:45\nmsgid \"creating installed.json in %[1]s: %[2]s\"\nmsgstr \"creating installed.json in %[1]s: %[2]s\"\n\n#: commands/compile/compile.go:253\nmsgid \"creating output dir\"\nmsgstr \"creating output dir\"\n\n#: arduino/resources/install.go:44\n#: arduino/resources/install.go:48\nmsgid \"creating temp dir for extraction: %s\"\nmsgstr \"creating temp dir for extraction: %s\"\n\n#: commands/instances.go:459\n#: commands/instances.go:461\nmsgid \"creating temp file for index download: %s\"\nmsgstr \"creating temp file for index download: %s\"\n\n#: commands/instances.go:492\n#: commands/instances.go:494\nmsgid \"creating temp file for index signature download: %s\"\nmsgstr \"creating temp file for index signature download: %s\"\n\n#: legacy/builder/phases/sizer.go:116\nmsgid \"data section exceeds available space in board\"\nmsgstr \"data section exceeds available space in board\"\n\n#: commands/debug/debug_info.go:146\nmsgid \"debugging not supported for board %s\"\nmsgstr \"debugging not supported for board %s\"\n\n#: arduino/sketch/sketch.go:207\nmsgid \"decoding sketch metadata: %s\"\nmsgstr \"decoding sketch metadata: %s\"\n\n#: commands/lib/resolve_deps.go:51\nmsgid \"dependency '%s' is not available\"\nmsgstr \"dependency '%s' is not available\"\n\n#: legacy/builder/utils/utils.go:471\nmsgid \"destination already exists\"\nmsgstr \"destination already exists\"\n\n#: arduino/libraries/librariesmanager/install.go:69\nmsgid \"destination dir %s already exists, cannot install\"\nmsgstr \"destination dir %s already exists, cannot install\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:112\nmsgid \"discovery %[1]s process not started: %[2]w\"\nmsgstr \"discovery %[1]s process not started: %[2]w\"\n\n#: arduino/cores/packagemanager/loader.go:710\nmsgid \"discovery not found: %s\"\nmsgstr \"discovery not found: %s\"\n\n#: arduino/cores/packagemanager/loader.go:715\nmsgid \"discovery not installed: %s\"\nmsgstr \"discovery not installed: %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:478\nmsgid \"discovery release not found: %s\"\nmsgstr \"discovery release not found: %s\"\n\n#: cli/core/download.go:36\nmsgid \"download [%s:%s[@%s]]...\"\nmsgstr \"download [%s:%s[@%s]]...\"\n\n#: cli/core/install.go:42\nmsgid \"download a specific version (in this case 1.6.9).\"\nmsgstr \"download a specific version (in this case 1.6.9).\"\n\n#: cli/core/install.go:40\nmsgid \"download the latest version of Arduino SAMD core.\"\nmsgstr \"download the latest version of Arduino SAMD core.\"\n\n#: commands/instances.go:95\nmsgid \"downloading %[1]s tool: %[2]s\"\nmsgstr \"downloading %[1]s tool: %[2]s\"\n\n#: commands/instances.go:469\n#: commands/instances.go:473\n#: commands/instances.go:478\nmsgid \"downloading index %[1]s: %[2]s\"\nmsgstr \"downloading index %[1]s: %[2]s\"\n\n#: commands/instances.go:508\nmsgid \"downloading index signature %[1]s: %[2]s\"\nmsgstr \"downloading index signature %[1]s: %[2]s\"\n\n#: commands/lib/install.go:72\nmsgid \"downloading library: %s\"\nmsgstr \"downloading library: %s\"\n\n#: commands/instances.go:378\nmsgid \"downloading library_index.json.gz\"\nmsgstr \"downloading library_index.json.gz\"\n\n#: commands/instances.go:388\nmsgid \"downloading library_index.json.sig\"\nmsgstr \"downloading library_index.json.sig\"\n\n#: commands/core/download.go:61\nmsgid \"downloading tool %[1]s: %[2]s\"\nmsgstr \"downloading tool %[1]s: %[2]s\"\n\n#: arduino/sketch/sketch.go:196\nmsgid \"encoding sketch metadata: %s\"\nmsgstr \"encoding sketch metadata: %s\"\n\n#: commands/board/list.go:140\nmsgid \"error getting board info from Arduino Cloud\"\nmsgstr \"error getting board info from Arduino Cloud\"\n\n#: commands/instances.go:867\nmsgid \"error loading sketch %[1]v: %[2]v\"\nmsgstr \"error loading sketch %[1]v: %[2]v\"\n\n#: arduino/monitors/serial.go:44\nmsgid \"error opening serial monitor\"\nmsgstr \"error opening serial monitor\"\n\n#: commands/debug/debug_info.go:65\nmsgid \"error parsing FQBN\"\nmsgstr \"error parsing FQBN\"\n\n#: cli/config/set.go:68\nmsgid \"error parsing value: %v\"\nmsgstr \"error parsing value: %v\"\n\n#: commands/board/list.go:81\nmsgid \"error processing response from server\"\nmsgstr \"error processing response from server\"\n\n#: commands/board/list.go:96\nmsgid \"error querying Arduino Cloud Api\"\nmsgstr \"error querying Arduino Cloud Api\"\n\n#: commands/debug/debug_info.go:71\nmsgid \"error resolving FQBN\"\nmsgstr \"error resolving FQBN\"\n\n#: cli/upload/upload.go:72\nmsgid \"error: %s and %s flags cannot be used together\"\nmsgstr \"error: %s and %s flags cannot be used together\"\n\n#: commands/debug/debug_info.go:126\n#: commands/upload/upload.go:356\nmsgid \"expected compiled sketch in directory %s, but is a file instead\"\nmsgstr \"expected compiled sketch in directory %s, but is a file instead\"\n\n#: arduino/resources/install.go:67\nmsgid \"extracting archive: %s\"\nmsgstr \"extracting archive: %s\"\n\n#: arduino/libraries/librariesmanager/install.go:119\nmsgid \"extracting archive: %w\"\nmsgstr \"extracting archive: %w\"\n\n#: arduino/resources/checksums.go:145\nmsgid \"failed to compute hash of file \\\"%s\\\"\"\nmsgstr \"failed to compute hash of file \\\"%s\\\"\"\n\n#: commands/board/list.go:64\nmsgid \"failed to initialize http client\"\nmsgstr \"failed to initialize http client\"\n\n#: arduino/resources/checksums.go:97\nmsgid \"fetched archive size differs from size specified in index\"\nmsgstr \"fetched archive size differs from size specified in index\"\n\n#: arduino/resources/install.go:132\nmsgid \"files in archive must be placed in a subdirectory\"\nmsgstr \"files in archive must be placed in a subdirectory\"\n\n#: arduino/cores/packagemanager/loader.go:66\nmsgid \"find abs path: %s\"\nmsgstr \"find abs path: %s\"\n\n#: commands/core/download.go:50\nmsgid \"find platform dependencies: %s\"\nmsgstr \"find platform dependencies: %s\"\n\n#: commands/core/install.go:49\n#: commands/core/uninstall.go:56\nmsgid \"finding platform dependencies: %s\"\nmsgstr \"finding platform dependencies: %s\"\n\n#: commands/daemon/monitor.go:45\nmsgid \"first message must contain monitor configuration, not data\"\nmsgstr \"first message must contain monitor configuration, not data\"\n\n#: cli/cli.go:69\nmsgid \"flags\"\nmsgstr \"flags\"\n\n#: arduino/cores/packagemanager/loader.go:108\nmsgid \"following possible symlink %[1]s: %[2]s\"\nmsgstr \"following possible symlink %[1]s: %[2]s\"\n\n#: cli/core/download.go:41\nmsgid \"for a specific version (in this case 1.6.9).\"\nmsgstr \"for a specific version (in this case 1.6.9).\"\n\n#: cli/lib/download.go:39\nmsgid \"for a specific version.\"\nmsgstr \"for a specific version.\"\n\n#: cli/lib/check_deps.go:38\n#: cli/lib/download.go:38\n#: cli/lib/install.go:42\nmsgid \"for the latest version.\"\nmsgstr \"for the latest version.\"\n\n#: cli/lib/check_deps.go:39\n#: cli/lib/install.go:43\nmsgid \"for the specific version.\"\nmsgstr \"for the specific version.\"\n\n#: arduino/libraries/libraries.go:114\nmsgid \"gathering library headers: %w\"\nmsgstr \"gathering library headers: %w\"\n\n#: inventory/inventory.go:67\nmsgid \"generating installation.id: %w\"\nmsgstr \"generating installation.id: %w\"\n\n#: inventory/inventory.go:73\nmsgid \"generating installation.secret: %w\"\nmsgstr \"generating installation.secret: %w\"\n\n#: arduino/resources/helpers.go:68\nmsgid \"getting archive file info: %s\"\nmsgstr \"getting archive file info: %s\"\n\n#: arduino/resources/checksums.go:94\nmsgid \"getting archive info: %s\"\nmsgstr \"getting archive info: %s\"\n\n#: arduino/resources/checksums.go:67\n#: arduino/resources/checksums.go:90\n#: arduino/resources/helpers.go:40\n#: arduino/resources/helpers.go:49\n#: arduino/resources/install.go:55\nmsgid \"getting archive path: %s\"\nmsgstr \"getting archive path: %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:195\nmsgid \"getting build properties for board %[1]s: %[2]s\"\nmsgstr \"getting build properties for board %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/download.go:103\nmsgid \"getting discovery dependencies for platform %[1]s: %[2]s\"\nmsgstr \"getting discovery dependencies for platform %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:649\nmsgid \"getting parent dir of %[1]s: %[2]s\"\nmsgstr \"getting parent dir of %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/download.go:96\nmsgid \"getting tool dependencies for platform %[1]s: %[2]s\"\nmsgstr \"getting tool dependencies for platform %[1]s: %[2]s\"\n\n#: arduino/sketch/sketch.go:151\nmsgid \"importing sketch metadata: %s\"\nmsgstr \"importing sketch metadata: %s\"\n\n#: commands/compile/compile.go:115\n#: commands/upload/programmers_list.go:37\n#: commands/upload/programmers_list.go:43\n#: commands/upload/upload.go:194\n#: commands/upload/upload.go:201\nmsgid \"incorrect FQBN: %s\"\nmsgstr \"incorrect FQBN: %s\"\n\n#: commands/instances.go:516\nmsgid \"index has an invalid signature\"\nmsgstr \"index has an invalid signature\"\n\n#: arduino/libraries/librariesmanager/install.go:86\nmsgid \"install directory not set\"\nmsgstr \"install directory not set\"\n\n#: commands/instances.go:99\nmsgid \"installing %[1]s tool: %[2]s\"\nmsgstr \"installing %[1]s tool: %[2]s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:37\nmsgid \"installing platform %[1]s: %[2]s\"\nmsgstr \"installing platform %[1]s: %[2]s\"\n\n#: commands/bundled_tools.go:54\nmsgid \"installing tool %[1]s: %[2]s\"\nmsgstr \"installing tool %[1]s: %[2]s\"\n\n#: arduino/discovery/discovery.go:184\nmsgid \"invalid 'add' message: missing port\"\nmsgstr \"invalid 'add' message: missing port\"\n\n#: arduino/discovery/discovery.go:195\nmsgid \"invalid 'remove' message: missing port\"\nmsgstr \"invalid 'remove' message: missing port\"\n\n#: commands/upload/upload.go:254\nmsgid \"invalid 'upload.tool' property: %s\"\nmsgstr \"invalid 'upload.tool' property: %s\"\n\n#: commands/board/attach.go:66\nmsgid \"invalid Device URL format: %s\"\nmsgstr \"invalid Device URL format: %s\"\n\n#: arduino/resources/checksums.go:45\nmsgid \"invalid checksum format: %s\"\nmsgstr \"invalid checksum format: %s\"\n\n#: commands/board/attach.go:76\nmsgid \"invalid device port type provided\"\nmsgstr \"invalid device port type provided\"\n\n#: cli/arguments/reference.go:82\nmsgid \"invalid empty core architecture '%s'\"\nmsgstr \"invalid empty core architecture '%s'\"\n\n#: cli/arguments/reference.go:58\nmsgid \"invalid empty core argument\"\nmsgstr \"invalid empty core argument\"\n\n#: cli/arguments/reference.go:78\nmsgid \"invalid empty core name '%s'\"\nmsgstr \"invalid empty core name '%s'\"\n\n#: cli/arguments/reference.go:62\nmsgid \"invalid empty core reference '%s'\"\nmsgstr \"invalid empty core reference '%s'\"\n\n#: cli/arguments/reference.go:67\nmsgid \"invalid empty core version: '%s'\"\nmsgstr \"invalid empty core version: '%s'\"\n\n#: cli/lib/args.go:49\nmsgid \"invalid empty library name\"\nmsgstr \"invalid empty library name\"\n\n#: cli/lib/args.go:54\nmsgid \"invalid empty library version: %s\"\nmsgstr \"invalid empty library version: %s\"\n\n#: arduino/cores/board.go:123\nmsgid \"invalid empty option found\"\nmsgstr \"invalid empty option found\"\n\n#: arduino/cores/fqbn.go:54\n#: arduino/cores/fqbn.go:59\nmsgid \"invalid fqbn config: %s\"\nmsgstr \"invalid fqbn config: %s\"\n\n#: arduino/cores/fqbn.go:48\nmsgid \"invalid fqbn: empty board identifier\"\nmsgstr \"invalid fqbn: empty board identifier\"\n\n#: arduino/libraries/librariesmanager/install.go:250\nmsgid \"invalid git url\"\nmsgstr \"invalid git url\"\n\n#: commands/instances.go:344\n#: commands/instances.go:356\n#: commands/instances.go:425\n#: commands/instances.go:687\n#: commands/instances.go:732\nmsgid \"invalid handle\"\nmsgstr \"invalid handle\"\n\n#: arduino/resources/checksums.go:49\nmsgid \"invalid hash '%[1]s': %[2]s\"\nmsgstr \"invalid hash '%[1]s': %[2]s\"\n\n#: commands/board/attach.go:42\n#: commands/board/details.go:33\n#: commands/board/list.go:185\n#: commands/board/listall.go:32\n#: commands/board/search.go:36\n#: commands/compile/compile.go:93\n#: commands/core/download.go:36\n#: commands/core/install.go:35\n#: commands/core/list.go:39\n#: commands/core/search.go:40\n#: commands/core/uninstall.go:33\n#: commands/core/upgrade.go:40\n#: commands/instances.go:566\n#: commands/instances.go:589\n#: commands/lib/list.go:41\n#: commands/lib/list.go:46\n#: commands/lib/search.go:34\n#: commands/upload/upload.go:51\nmsgid \"invalid instance\"\nmsgstr \"invalid instance\"\n\n#: cli/arguments/reference.go:75\nmsgid \"invalid item %s\"\nmsgstr \"invalid item %s\"\n\n#: arduino/libraries/libraries_layout.go:53\nmsgid \"invalid library layout value: %d\"\nmsgstr \"invalid library layout value: %d\"\n\n#: arduino/libraries/libraries_layout.go:68\nmsgid \"invalid library layout: %s\"\nmsgstr \"invalid library layout: %s\"\n\n#: arduino/libraries/libraries_location.go:73\nmsgid \"invalid library location value: %d\"\nmsgstr \"invalid library location value: %d\"\n\n#: arduino/libraries/libraries_location.go:94\nmsgid \"invalid library location: %s\"\nmsgstr \"invalid library location: %s\"\n\n#: arduino/cores/board.go:125\nmsgid \"invalid option '%s'\"\nmsgstr \"invalid option '%s'\"\n\n#: commands/instances.go:445\n#: commands/instances.go:521\nmsgid \"invalid package index in %[1]s: %[2]s\"\nmsgstr \"invalid package index in %[1]s: %[2]s\"\n\n#: inventory/inventory.go:85\nmsgid \"invalid path creating config dir: %[1]s error: %[2]w\"\nmsgstr \"invalid path creating config dir: %[1]s error: %[2]w\"\n\n#: inventory/inventory.go:91\nmsgid \"invalid path writing inventory file: %[1]s error: %[2]w\"\nmsgstr \"invalid path writing inventory file: %[1]s error: %[2]w\"\n\n#: arduino/cores/packageindex/index.go:239\nmsgid \"invalid platform archive size: %s\"\nmsgstr \"invalid platform archive size: %s\"\n\n#: commands/upload/upload.go:482\nmsgid \"invalid recipe '%[1]s': %[2]s\"\nmsgstr \"invalid recipe '%[1]s': %[2]s\"\n\n#: arduino/cores/board.go:109\nmsgid \"invalid value '%[1]s' for option '%[2]s'\"\nmsgstr \"invalid value '%[1]s' for option '%[2]s'\"\n\n#: arduino/cores/packagemanager/loader.go:280\nmsgid \"invalid version dir %[1]s: %[2]s\"\nmsgstr \"invalid version dir %[1]s: %[2]s\"\n\n#: commands/core/download.go:41\n#: commands/core/install.go:40\n#: commands/lib/utils.go:34\nmsgid \"invalid version: %s\"\nmsgstr \"invalid version: %s\"\n\n#: commands/daemon/settings.go:108\nmsgid \"key not found in settings\"\nmsgstr \"key not found in settings\"\n\n#: cli/core/search.go:48\nmsgid \"keywords\"\nmsgstr \"keywords\"\n\n#: arduino/libraries/librariesmanager/install.go:157\n#: arduino/libraries/librariesmanager/install.go:200\nmsgid \"library %s already installed\"\nmsgstr \"library %s already installed\"\n\n#: commands/lib/utils.go:47\nmsgid \"library %s not found\"\nmsgstr \"library %s not found\"\n\n#: arduino/libraries/librariesmanager/install.go:38\nmsgid \"library already installed\"\nmsgstr \"library already installed\"\n\n#: arduino/libraries/librariesmanager/install.go:269\nmsgid \"library is not valid: missing file \\\"library.properties\\\"\"\nmsgstr \"library is not valid: missing file \\\"library.properties\\\"\"\n\n#: arduino/libraries/librariesmanager/install.go:264\nmsgid \"library is not valid: missing header file \\\"%s\\\"\"\nmsgstr \"library is not valid: missing header file \\\"%s\\\"\"\n\n#: arduino/libraries/librariesmanager/librariesmanager.go:226\nmsgid \"library path does not exist: %s\"\nmsgstr \"library path does not exist: %s\"\n\n#: commands/instances.go:404\nmsgid \"library_index.json has an invalid signature\"\nmsgstr \"library_index.json has an invalid signature\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:222\nmsgid \"listing ports from discovery %[1]s: %[2]w\"\nmsgstr \"listing ports from discovery %[1]s: %[2]w\"\n\n#: arduino/serialutils/serialutils.go:61\nmsgid \"listing serial ports\"\nmsgstr \"listing serial ports\"\n\n#: arduino/cores/packagemanager/loader.go:307\n#: arduino/cores/packagemanager/loader.go:316\n#: arduino/cores/packagemanager/loader.go:321\nmsgid \"loading %[1]s: %[2]s\"\nmsgstr \"loading %[1]s: %[2]s\"\n\n#: commands/board/details.go:44\n#: commands/lib/list.go:60\n#: commands/upload/upload.go:61\nmsgid \"loading board data: %s\"\nmsgstr \"loading board data: %s\"\n\n#: arduino/cores/packagemanager/loader.go:356\nmsgid \"loading boards: %s\"\nmsgstr \"loading boards: %s\"\n\n#: arduino/cores/packagemanager/loader.go:604\nmsgid \"loading bundled tools from %[1]s: %[2]s\"\nmsgstr \"loading bundled tools from %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/package_manager.go:230\n#: arduino/cores/packagemanager/package_manager.go:245\nmsgid \"loading json index file %[1]s: %[2]s\"\nmsgstr \"loading json index file %[1]s: %[2]s\"\n\n#: arduino/libraries/librariesmanager/librariesmanager.go:205\n#: arduino/libraries/librariesmanager/librariesmanager.go:231\nmsgid \"loading library from %[1]s: %[2]s\"\nmsgstr \"loading library from %[1]s: %[2]s\"\n\n#: arduino/libraries/loader.go:47\nmsgid \"loading library.properties: %s\"\nmsgstr \"loading library.properties: %s\"\n\n#: arduino/cores/packagemanager/loader.go:256\n#: arduino/cores/packagemanager/loader.go:284\nmsgid \"loading platform release %[1]s: %[2]s\"\nmsgstr \"loading platform release %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:207\nmsgid \"loading platform.txt: %v\"\nmsgstr \"loading platform.txt: %v\"\n\n#: arduino/cores/packagemanager/loader.go:571\nmsgid \"loading tool release in %[1]s: %[2]s\"\nmsgstr \"loading tool release in %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:200\nmsgid \"looking for boards.txt in %[1]s: %[2]s\"\nmsgstr \"looking for boards.txt in %[1]s: %[2]s\"\n\n#: commands/lib/download.go:42\n#: commands/lib/install.go:68\n#: commands/lib/resolve_deps.go:34\nmsgid \"looking for library: %s\"\nmsgstr \"looking for library: %s\"\n\n#: legacy/builder/container_setup.go:74\nmsgid \"main file missing from sketch\"\nmsgstr \"main file missing from sketch\"\n\n#: commands/compile/compile.go:259\nmsgid \"missing 'build.project_name' build property\"\nmsgstr \"missing 'build.project_name' build property\"\n\n#: arduino/resources/checksums.go:41\nmsgid \"missing checksum for: %s\"\nmsgstr \"missing checksum for: %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:207\nmsgid \"missing package %[1]s referenced by board %[2]s\"\nmsgstr \"missing package %[1]s referenced by board %[2]s\"\n\n#: arduino/cores/packagemanager/package_manager.go:212\nmsgid \"missing platform %[1]s:%[2]s referenced by board %[3]s\"\nmsgstr \"missing platform %[1]s:%[2]s referenced by board %[3]s\"\n\n#: arduino/cores/packagemanager/package_manager.go:217\nmsgid \"missing platform release %[1]s:%[2]s referenced by board %[3]s\"\nmsgstr \"missing platform release %[1]s:%[2]s referenced by board %[3]s\"\n\n#: commands/upload/upload.go:46\nmsgid \"missing protocol\"\nmsgstr \"missing protocol\"\n\n#: commands/compile/compile.go:98\n#: commands/debug/debug_info.go:47\nmsgid \"missing sketchPath\"\nmsgstr \"missing sketchPath\"\n\n#: arduino/libraries/librariesmanager/install.go:174\n#: arduino/resources/install.go:94\nmsgid \"moving extracted archive to destination dir: %s\"\nmsgstr \"moving extracted archive to destination dir: %s\"\n\n#: commands/upload/upload.go:605\nmsgid \"multiple build artifacts found: '%[1]s' and '%[2]s'\"\nmsgstr \"multiple build artifacts found: '%[1]s' and '%[2]s'\"\n\n#: arduino/sketch/sketch.go:73\nmsgid \"multiple main sketch files found (%[1]v, %[2]v)\"\nmsgstr \"multiple main sketch files found (%[1]v, %[2]v)\"\n\n#: commands/compile/compile.go:111\nmsgid \"no FQBN provided\"\nmsgstr \"no FQBN provided\"\n\n#: commands/debug/debug_info.go:61\n#: commands/upload/programmers_list.go:33\n#: commands/upload/upload.go:190\nmsgid \"no Fully Qualified Board Name provided\"\nmsgstr \"no Fully Qualified Board Name provided\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:127\nmsgid \"no compatible version of %s tools found for the current os\"\nmsgstr \"no compatible version of %s tools found for the current os\"\n\n#: executils/process.go:37\nmsgid \"no executable specified\"\nmsgstr \"no executable specified\"\n\n#: commands/daemon/daemon.go:82\nmsgid \"no instance specified\"\nmsgstr \"no instance specified\"\n\n#: commands/upload/upload.go:181\nmsgid \"no programmer specified for burning bootloader\"\nmsgstr \"no programmer specified for burning bootloader\"\n\n#: commands/upload/upload.go:560\nmsgid \"no sketch or build directory/file specified\"\nmsgstr \"no sketch or build directory/file specified\"\n\n#: commands/board/attach.go:92\nmsgid \"no supported board found at %s\"\nmsgstr \"no supported board found at %s\"\n\n#: arduino/resources/install.go:128\nmsgid \"no unique root dir in archive, found '%[1]s' and '%[2]s'\"\nmsgstr \"no unique root dir in archive, found '%[1]s' and '%[2]s'\"\n\n#: commands/upload/upload.go:477\nmsgid \"no upload port provided\"\nmsgstr \"no upload port provided\"\n\n#: arduino/sketch/sketch.go:259\nmsgid \"no valid sketch found in %[1]s: missing %[2]s\"\nmsgstr \"no valid sketch found in %[1]s: missing %[2]s\"\n\n#: commands/lib/resolve_deps.go:56\nmsgid \"no valid solution found\"\nmsgstr \"no valid solution found\"\n\n#: arduino/resources/checksums.go:72\n#: arduino/resources/install.go:59\nmsgid \"opening archive file: %s\"\nmsgstr \"opening archive file: %s\"\n\n#: arduino/cores/packagemanager/loader.go:273\nmsgid \"opening boards.txt: %s\"\nmsgstr \"opening boards.txt: %s\"\n\n#: arduino/serialutils/serialutils.go:37\nmsgid \"opening port at 1200bps\"\nmsgstr \"opening port at 1200bps\"\n\n#: arduino/security/signatures.go:81\nmsgid \"opening signature file: %s\"\nmsgstr \"opening signature file: %s\"\n\n#: commands/debug/debug_info.go:52\nmsgid \"opening sketch\"\nmsgstr \"opening sketch\"\n\n#: commands/board/attach.go:50\n#: commands/compile/compile.go:103\n#: commands/upload/upload.go:123\nmsgid \"opening sketch: %s\"\nmsgstr \"opening sketch: %s\"\n\n#: arduino/security/signatures.go:76\nmsgid \"opening target file: %s\"\nmsgstr \"opening target file: %s\"\n\n#: arduino/cores/packagemanager/download.go:73\n#: arduino/cores/status.go:88\n#: arduino/cores/status.go:113\nmsgid \"package %s not found\"\nmsgstr \"package %s not found\"\n\n#: arduino/cores/packagemanager/package_manager.go:259\nmsgid \"package '%s' not found\"\nmsgstr \"package '%s' not found\"\n\n#: arduino/cores/status.go:167\nmsgid \"package not found\"\nmsgstr \"package not found\"\n\n#: arduino/cores/packagemanager/loader.go:227\nmsgid \"parsing IDE bundled index: %s\"\nmsgstr \"parsing IDE bundled index: %s\"\n\n#: arduino/cores/board.go:139\n#: arduino/cores/packagemanager/package_manager.go:136\n#: commands/board/details.go:38\n#: commands/lib/list.go:56\n#: commands/upload/upload.go:56\nmsgid \"parsing fqbn: %s\"\nmsgstr \"parsing fqbn: %s\"\n\n#: arduino/libraries/librariesindex/json.go:69\nmsgid \"parsing library_index.json: %s\"\nmsgstr \"parsing library_index.json: %s\"\n\n#: commands/instances.go:487\nmsgid \"parsing url for index signature check: %s\"\nmsgstr \"parsing url for index signature check: %s\"\n\n#: arduino/cores/packagemanager/loader.go:189\nmsgid \"path is not a platform directory: %s\"\nmsgstr \"path is not a platform directory: %s\"\n\n#: arduino/cores/packagemanager/download.go:77\nmsgid \"platform %[1]s not found in package %[2]s\"\nmsgstr \"platform %[1]s not found in package %[2]s\"\n\n#: arduino/cores/packagemanager/download.go:89\nmsgid \"platform %s has no available releases\"\nmsgstr \"platform %s has no available releases\"\n\n#: arduino/cores/packagemanager/package_manager.go:182\n#: commands/core/upgrade.go:74\n#: commands/core/upgrade.go:84\n#: commands/instances.go:763\nmsgid \"platform %s is not installed\"\nmsgstr \"platform %s is not installed\"\n\n#: commands/core/upgrade.go:70\nmsgid \"platform %s not found\"\nmsgstr \"platform %s not found\"\n\n#: commands/core/upgrade.go:31\nmsgid \"platform already at latest version\"\nmsgstr \"platform already at latest version\"\n\n#: commands/core/uninstall.go:43\nmsgid \"platform not found: %s\"\nmsgstr \"platform not found: %s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:65\n#: arduino/cores/packagemanager/install_uninstall.go:108\n#: arduino/cores/packagemanager/loader.go:433\n#: commands/compile/compile.go:128\nmsgid \"platform not installed\"\nmsgstr \"platform not installed\"\n\n#: commands/core/uninstall.go:48\nmsgid \"platform not installed: %s\"\nmsgstr \"platform not installed: %s\"\n\n#: cli/compile/compile.go:121\nmsgid \"please use --build-property instead.\"\nmsgstr \"please use --build-property instead.\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:67\nmsgid \"pluggable discovery already added: %s\"\nmsgstr \"pluggable discovery already added: %s\"\n\n#: cli/board/attach.go:35\nmsgid \"port\"\nmsgstr \"port\"\n\n#: cli/arguments/port.go:122\nmsgid \"port not found: %[1]s %[2]s\"\nmsgstr \"port not found: %[1]s %[2]s\"\n\n#: commands/upload/upload.go:218\nmsgid \"programmer '%s' not available\"\nmsgstr \"programmer '%s' not available\"\n\n#: commands/debug/debug_info.go:114\nmsgid \"programmer '%s' not found\"\nmsgstr \"programmer '%s' not found\"\n\n#: commands/upload/upload.go:155\nmsgid \"programmer not specified\"\nmsgstr \"programmer not specified\"\n\n#: commands/upload/upload.go:456\nmsgid \"programming error: %s\"\nmsgstr \"programming error: %s\"\n\n#: arduino/discovery/discovery.go:303\nmsgid \"protocol version not supported: requested 1, got %d\"\nmsgstr \"protocol version not supported: requested 1, got %d\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:188\nmsgid \"quitting discovery %[1]s: %[2]w\"\nmsgstr \"quitting discovery %[1]s: %[2]w\"\n\n#: arduino/cores/packagemanager/loader.go:78\nmsgid \"reading %[1]s directory: %[2]s\"\nmsgstr \"reading %[1]s directory: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:654\nmsgid \"reading %[1]s: %[2]s\"\nmsgstr \"reading %[1]s: %[2]s\"\n\n#: commands/compile/compile.go:263\nmsgid \"reading build directory: %s\"\nmsgstr \"reading build directory: %s\"\n\n#: arduino/cores/packagemanager/loader.go:267\n#: arduino/libraries/librariesmanager/librariesmanager.go:196\nmsgid \"reading dir %[1]s: %[2]s\"\nmsgstr \"reading dir %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:162\n#: arduino/cores/packagemanager/loader.go:562\nmsgid \"reading directory %[1]s: %[2]s\"\nmsgstr \"reading directory %[1]s: %[2]s\"\n\n#: arduino/builder/sketch.go:76\nmsgid \"reading file %[1]s: %[2]s\"\nmsgstr \"reading file %[1]s: %[2]s\"\n\n#: arduino/sketch/sketch.go:229\nmsgid \"reading files: %v\"\nmsgstr \"reading files: %v\"\n\n#: inventory/inventory.go:57\nmsgid \"reading inventory file: %w\"\nmsgstr \"reading inventory file: %w\"\n\n#: arduino/libraries/librariesresolver/cpp.go:60\nmsgid \"reading lib headers: %s\"\nmsgstr \"reading lib headers: %s\"\n\n#: arduino/libraries/libraries.go:234\nmsgid \"reading lib src dir: %s\"\nmsgstr \"reading lib src dir: %s\"\n\n#: arduino/libraries/librariesindex/json.go:63\nmsgid \"reading library_index.json: %s\"\nmsgstr \"reading library_index.json: %s\"\n\n#: arduino/resources/install.go:118\nmsgid \"reading package root dir: %s\"\nmsgstr \"reading package root dir: %s\"\n\n#: arduino/sketch/sketch.go:188\nmsgid \"reading sketch metadata %[1]s: %[2]s\"\nmsgstr \"reading sketch metadata %[1]s: %[2]s\"\n\n#: commands/upload/upload.go:471\nmsgid \"recipe not found '%s'\"\nmsgstr \"recipe not found '%s'\"\n\n#: arduino/cores/packagemanager/package_manager.go:335\nmsgid \"release %[1]s not found for tool %[2]s\"\nmsgstr \"release %[1]s not found for tool %[2]s\"\n\n#: arduino/cores/status.go:82\n#: arduino/cores/status.go:106\nmsgid \"release cannot be nil\"\nmsgstr \"release cannot be nil\"\n\n#: arduino/cores/status.go:183\nmsgid \"release not found\"\nmsgstr \"release not found\"\n\n#: arduino/resources/helpers.go:59\nmsgid \"removing corrupted archive file: %s\"\nmsgstr \"removing corrupted archive file: %s\"\n\n#: arduino/libraries/librariesmanager/install.go:89\nmsgid \"removing lib directory: %s\"\nmsgstr \"removing lib directory: %s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:117\nmsgid \"removing platform files: %s\"\nmsgstr \"removing platform files: %s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:169\nmsgid \"removing tool files: %s\"\nmsgstr \"removing tool files: %s\"\n\n#: arduino/cores/packagemanager/download.go:84\nmsgid \"required version %[1]s not found for platform %[2]s\"\nmsgstr \"required version %[1]s not found for platform %[2]s\"\n\n#: commands/lib/install.go:82\n#: commands/lib/upgrade.go:38\nmsgid \"rescanning libraries: %s\"\nmsgstr \"rescanning libraries: %s\"\n\n#: arduino/security/signatures.go:72\nmsgid \"retrieving Arduino public keys: %s\"\nmsgstr \"retrieving Arduino public keys: %s\"\n\n#: commands/upload/upload.go:350\nmsgid \"retrieving build artifacts: %s\"\nmsgstr \"retrieving build artifacts: %s\"\n\n#: commands/instances.go:529\nmsgid \"saving downloaded index %[1]s: %[2]s\"\nmsgstr \"saving downloaded index %[1]s: %[2]s\"\n\n#: commands/instances.go:533\nmsgid \"saving downloaded index signature: %s\"\nmsgstr \"saving downloaded index signature: %s\"\n\n#: arduino/libraries/loader.go:109\n#: arduino/libraries/loader.go:140\nmsgid \"scanning examples: %s\"\nmsgstr \"scanning examples: %s\"\n\n#: arduino/cores/packagemanager/loader.go:640\nmsgid \"searching for builtin_tools_versions.txt in %[1]s: %[2]s\"\nmsgstr \"searching for builtin_tools_versions.txt in %[1]s: %[2]s\"\n\n#: arduino/resources/install.go:73\nmsgid \"searching package root dir: %s\"\nmsgstr \"searching package root dir: %s\"\n\n#: arduino/serialutils/serialutils.go:43\nmsgid \"setting DTR to OFF\"\nmsgstr \"setting DTR to OFF\"\n\n#: commands/instances.go:513\nmsgid \"signature verification error: %s\"\nmsgstr \"signature verification error: %s\"\n\n#: cli/board/attach.go:35\n#: cli/sketch/archive.go:38\nmsgid \"sketchPath\"\nmsgstr \"sketchPath\"\n\n#: arduino/cores/packagemanager/loader.go:496\nmsgid \"skipping loading of boards %s: malformed custom board options\"\nmsgstr \"skipping loading of boards %s: malformed custom board options\"\n\n#: legacy/builder/utils/utils.go:463\nmsgid \"source is not a directory\"\nmsgstr \"source is not a directory\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:149\nmsgid \"start syncing discovery %[1]s: %[2]w\"\nmsgstr \"start syncing discovery %[1]s: %[2]w\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:128\nmsgid \"starting discovery %[1]s: %[2]w\"\nmsgstr \"starting discovery %[1]s: %[2]w\"\n\n#: commands/board/list.go:277\nmsgid \"stopping discoveries: %s\"\nmsgstr \"stopping discoveries: %s\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:172\nmsgid \"stopping discovery %[1]s: %[2]w\"\nmsgstr \"stopping discovery %[1]s: %[2]w\"\n\n#: arduino/resources/checksums.go:119\nmsgid \"testing archive checksum: %s\"\nmsgstr \"testing archive checksum: %s\"\n\n#: arduino/resources/checksums.go:112\nmsgid \"testing archive size: %s\"\nmsgstr \"testing archive size: %s\"\n\n#: arduino/resources/checksums.go:106\nmsgid \"testing if archive is cached: %s\"\nmsgstr \"testing if archive is cached: %s\"\n\n#: arduino/resources/install.go:37\nmsgid \"testing local archive integrity: %s\"\nmsgstr \"testing local archive integrity: %s\"\n\n#: legacy/builder/phases/sizer.go:111\nmsgid \"text section exceeds available space in board\"\nmsgstr \"text section exceeds available space in board\"\n\n#: arduino/libraries/librariesmanager/librariesmanager.go:65\nmsgid \"the library name is different from the set (%[1]s != %[2]s)\"\nmsgstr \"the library name is different from the set (%[1]s != %[2]s)\"\n\n#: commands/board/list.go:72\nmsgid \"the server responded with status %s\"\nmsgstr \"the server responded with status %s\"\n\n#: arduino/discovery/discovery.go:228\nmsgid \"timeout waiting for message from %s\"\nmsgstr \"timeout waiting for message from %s\"\n\n#: cli/core/download.go:40\nmsgid \"to download the latest version of Arduino SAMD core.\\n\"\n\"\"\nmsgstr \"to download the latest version of Arduino SAMD core.\\n\"\n\"\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:165\nmsgid \"tool %s is not managed by package manager\"\nmsgstr \"tool %s is not managed by package manager\"\n\n#: commands/core/download.go:84\nmsgid \"tool %s not available for the current OS\"\nmsgstr \"tool %s not available for the current OS\"\n\n#: arduino/cores/status.go:92\n#: arduino/cores/status.go:117\nmsgid \"tool %s not found\"\nmsgstr \"tool %s not found\"\n\n#: arduino/cores/packagemanager/package_manager.go:285\nmsgid \"tool '%[1]s' not found in package '%[2]s'\"\nmsgstr \"tool '%[1]s' not found in package '%[2]s'\"\n\n#: arduino/cores/packagemanager/download.go:114\nmsgid \"tool not available for your OS\"\nmsgstr \"tool not available for your OS\"\n\n#: arduino/cores/status.go:171\nmsgid \"tool not found\"\nmsgstr \"tool not found\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:160\nmsgid \"tool not installed\"\nmsgstr \"tool not installed\"\n\n#: arduino/cores/packagemanager/package_manager.go:467\n#: arduino/cores/packagemanager/package_manager.go:533\nmsgid \"tool release not found: %s\"\nmsgstr \"tool release not found: %s\"\n\n#: arduino/cores/status.go:96\nmsgid \"tool version %s not found\"\nmsgstr \"tool version %s not found\"\n\n#: commands/lib/install.go:54\nmsgid \"two different versions of the library %[1]s are required: %[2]s and %[3]s\"\nmsgstr \"two different versions of the library %[1]s are required: %[2]s and %[3]s\"\n\n#: arduino/builder/sketch.go:69\n#: arduino/builder/sketch.go:117\nmsgid \"unable to compute relative path to the sketch for the item\"\nmsgstr \"unable to compute relative path to the sketch for the item\"\n\n#: arduino/builder/sketch.go:49\nmsgid \"unable to create a folder to save the sketch\"\nmsgstr \"unable to create a folder to save the sketch\"\n\n#: arduino/builder/sketch.go:111\nmsgid \"unable to create a folder to save the sketch files\"\nmsgstr \"unable to create a folder to save the sketch files\"\n\n#: arduino/builder/sketch.go:123\nmsgid \"unable to create the folder containing the item\"\nmsgstr \"unable to create the folder containing the item\"\n\n#: commands/core/list.go:34\nmsgid \"unable to find an instance with ID: %d\"\nmsgstr \"unable to find an instance with ID: %d\"\n\n#: cli/config/dump.go:53\nmsgid \"unable to marshal config to YAML: %v\"\nmsgstr \"unable to marshal config to YAML: %v\"\n\n#: arduino/builder/sketch.go:161\nmsgid \"unable to read contents of the destination item\"\nmsgstr \"unable to read contents of the destination item\"\n\n#: arduino/builder/sketch.go:134\nmsgid \"unable to read contents of the source item\"\nmsgstr \"unable to read contents of the source item\"\n\n#: arduino/builder/sketch.go:55\nmsgid \"unable to save the sketch on disk\"\nmsgstr \"unable to save the sketch on disk\"\n\n#: arduino/builder/sketch.go:144\nmsgid \"unable to write to destination file\"\nmsgstr \"unable to write to destination file\"\n\n#: arduino/cores/packagemanager/package_manager.go:170\nmsgid \"unknown package %s\"\nmsgstr \"unknown package %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:177\nmsgid \"unknown platform %s:%s\"\nmsgstr \"unknown platform %s:%s\"\n\n#: arduino/sketch/sketch.go:142\nmsgid \"unknown sketch file extension '%s'\"\nmsgstr \"unknown sketch file extension '%s'\"\n\n#: commands/debug/debug.go:173\nmsgid \"unsupported gdb server '%s'\"\nmsgstr \"unsupported gdb server '%s'\"\n\n#: arduino/resources/checksums.go:62\nmsgid \"unsupported hash algorithm: %s\"\nmsgstr \"unsupported hash algorithm: %s\"\n\n#: commands/debug/debug.go:134\nmsgid \"unsupported toolchain '%s'\"\nmsgstr \"unsupported toolchain '%s'\"\n\n#: commands/instances.go:397\nmsgid \"unzipping library_index.json.gz\"\nmsgstr \"unzipping library_index.json.gz\"\n\n#: cli/core/upgrade.go:42\nmsgid \"upgrade arduino:samd to the latest version\"\nmsgstr \"upgrade arduino:samd to the latest version\"\n\n#: commands/core/upgrade.go:64\nmsgid \"upgrade doesn't accept parameters with version\"\nmsgstr \"upgrade doesn't accept parameters with version\"\n\n#: cli/core/upgrade.go:40\nmsgid \"upgrade everything to the latest version\"\nmsgstr \"upgrade everything to the latest version\"\n\n#: commands/core/install.go:156\nmsgid \"upgrading platform: %s\"\nmsgstr \"upgrading platform: %s\"\n\n#: commands/upload/upload.go:460\n#: commands/upload/upload.go:506\nmsgid \"uploading error: %s\"\nmsgstr \"uploading error: %s\"\n\n#: commands/instances.go:402\nmsgid \"verifying signature\"\nmsgstr \"verifying signature\"\n\n#: commands/instances.go:411\nmsgid \"writing library_index.json\"\nmsgstr \"writing library_index.json\"\n\n#: commands/instances.go:414\nmsgid \"writing library_index.json.sig\"\nmsgstr \"writing library_index.json.sig\"\n\n#: arduino/sketch/sketch.go:212\nmsgid \"writing sketch metadata %[1]s: %[2]s\"\nmsgstr \"writing sketch metadata %[1]s: %[2]s\"\n\n#: commands/board/list.go:88\nmsgid \"wrong format in server response\"\nmsgstr \"wrong format in server response\"\n\n#: legacy/builder/constants/constants.go:100\nmsgid \"{0} invalid\"\nmsgstr \"{0} invalid\"\n\n#: legacy/builder/constants/constants.go:102\nmsgid \"{0} is not a valid fully qualified board name. Required format is targetPackageName:targetPlatformName:targetBoardName.\"\nmsgstr \"{0} is not a valid fully qualified board name. Required format is targetPackageName:targetPlatformName:targetBoardName.\"\n\n#: legacy/builder/builder_utils/utils.go:323\n#: legacy/builder/builder_utils/utils.go:329\n#: legacy/builder/builder_utils/utils.go:393\nmsgid \"{0} newer than {1}\"\nmsgstr \"{0} newer than {1}\"\n\n#: legacy/builder/constants/constants.go:114\nmsgid \"{0}: Unknown package\"\nmsgstr \"{0}: Unknown package\"\n\n"), + Content: string("msgid \"\"\nmsgstr \"\"\n\n#: legacy/builder/resolve_library.go:36\nmsgid \" -> candidates: %s\"\nmsgstr \" -> candidates: %s\"\n\n#: legacy/builder/constants/constants.go:107\nmsgid \" Not used: {0}\"\nmsgstr \" Not used: {0}\"\n\n#: legacy/builder/constants/constants.go:108\nmsgid \" Used: {0}\"\nmsgstr \" Used: {0}\"\n\n#: version/version.go:54\nmsgid \"%[1]s %[2]s Version: %[3]s Commit: %[4]s Date: %[5]s\"\nmsgstr \"%[1]s %[2]s Version: %[3]s Commit: %[4]s Date: %[5]s\"\n\n#: legacy/builder/constants/constants.go:92\nmsgid \"%[1]s folder is no longer supported! See %[2]s for more information\"\nmsgstr \"%[1]s folder is no longer supported! See %[2]s for more information\"\n\n#: arduino/discovery/discovery.go:74\nmsgid \"%[1]s, message: %[2]s\"\nmsgstr \"%[1]s, message: %[2]s\"\n\n#: arduino/discovery/discovery.go:83\nmsgid \"%[1]s, port: %[2]s\"\nmsgstr \"%[1]s, port: %[2]s\"\n\n#: arduino/discovery/discovery.go:80\nmsgid \"%[1]s, ports: %[2]s\"\nmsgstr \"%[1]s, ports: %[2]s\"\n\n#: arduino/discovery/discovery.go:77\nmsgid \"%[1]s, protocol version: %[2]d\"\nmsgstr \"%[1]s, protocol version: %[2]d\"\n\n#: cli/output/rpc_progress.go:64\nmsgid \"%s already downloaded\"\nmsgstr \"%s already downloaded\"\n\n#: commands/upload/upload.go:533\nmsgid \"%s and %s cannot be used together\"\nmsgstr \"%s and %s cannot be used together\"\n\n#: cli/debug/debug.go:154\nmsgid \"%s custom configurations\"\nmsgstr \"%s custom configurations\"\n\n#: cli/output/rpc_progress.go:76\nmsgid \"%s downloaded\"\nmsgstr \"%s downloaded\"\n\n#: commands/bundled_tools.go:57\nmsgid \"%s installed\"\nmsgstr \"%s installed\"\n\n#: cli/lib/check_deps.go:93\nmsgid \"%s is already installed.\"\nmsgstr \"%s is already installed.\"\n\n#: arduino/cores/packagemanager/loader.go:71\nmsgid \"%s is not a directory\"\nmsgstr \"%s is not a directory\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:113\nmsgid \"%s is not managed by package manager\"\nmsgstr \"%s is not managed by package manager\"\n\n#: cli/lib/check_deps.go:96\nmsgid \"%s is required but %s is currently installed.\"\nmsgstr \"%s is required but %s is currently installed.\"\n\n#: cli/lib/check_deps.go:90\nmsgid \"%s must be installed.\"\nmsgstr \"%s must be installed.\"\n\n#: legacy/builder/builder_utils/utils.go:530\n#: legacy/builder/ctags_runner.go:41\nmsgid \"%s pattern is missing\"\nmsgstr \"%s pattern is missing\"\n\n#: commands/instances.go:838\nmsgid \"%s uninstalled\"\nmsgstr \"%s uninstalled\"\n\n#: commands/errors.go:595\nmsgid \"'%s' has an invalid signature\"\nmsgstr \"'%s' has an invalid signature\"\n\n#: cli/board/listall.go:88\n#: cli/board/search.go:90\nmsgid \"(hidden)\"\nmsgstr \"(hidden)\"\n\n#: legacy/builder/constants/constants.go:105\nmsgid \"(legacy)\"\nmsgstr \"(legacy)\"\n\n#: legacy/builder/constants/constants.go:98\nmsgid \", rebuilding all\"\nmsgstr \", rebuilding all\"\n\n#: cli/lib/install.go:71\nmsgid \"--git-url and --zip-path are disabled by default, for more information see: %v\"\nmsgstr \"--git-url and --zip-path are disabled by default, for more information see: %v\"\n\n#: cli/lib/install.go:74\nmsgid \"--git-url and --zip-path flags allow installing untrusted files, use it at your own risk.\"\nmsgstr \"--git-url and --zip-path flags allow installing untrusted files, use it at your own risk.\"\n\n#: commands/errors.go:181\nmsgid \"A programmer is required to upload\"\nmsgstr \"A programmer is required to upload\"\n\n#: cli/core/download.go:36\n#: cli/core/install.go:37\n#: cli/core/uninstall.go:36\n#: cli/core/upgrade.go:38\nmsgid \"ARCH\"\nmsgstr \"ARCH\"\n\n#: cli/generatedocs/generatedocs.go:79\nmsgid \"ARDUINO COMMAND LINE MANUAL\"\nmsgstr \"ARDUINO COMMAND LINE MANUAL\"\n\n#: cli/usage.go:31\nmsgid \"Additional help topics:\"\nmsgstr \"Additional help topics:\"\n\n#: cli/config/add.go:31\n#: cli/config/add.go:32\nmsgid \"Adds one or more values to a setting.\"\nmsgstr \"Adds one or more values to a setting.\"\n\n#: cli/usage.go:26\nmsgid \"Aliases:\"\nmsgstr \"Aliases:\"\n\n#: cli/core/upgrade.go:68\nmsgid \"All the cores are already at the latest version\"\nmsgstr \"All the cores are already at the latest version\"\n\n#: commands/instances.go:707\n#: commands/lib/install.go:96\nmsgid \"Already installed %s\"\nmsgstr \"Already installed %s\"\n\n#: legacy/builder/resolve_library.go:34\nmsgid \"Alternatives for %[1]s: %[2]s\"\nmsgstr \"Alternatives for %[1]s: %[2]s\"\n\n#: cli/lib/search.go:171\nmsgid \"Architecture: %s\"\nmsgstr \"Architecture: %s\"\n\n#: commands/sketch/archive.go:70\nmsgid \"Archive already exists\"\nmsgstr \"Archive already exists\"\n\n#: legacy/builder/constants/constants.go:93\nmsgid \"Archiving built core (caching) in: {0}\"\nmsgstr \"Archiving built core (caching) in: {0}\"\n\n#: cli/sketch/sketch.go:31\n#: cli/sketch/sketch.go:32\nmsgid \"Arduino CLI sketch commands.\"\nmsgstr \"Arduino CLI sketch commands.\"\n\n#: cli/cli.go:67\nmsgid \"Arduino CLI.\"\nmsgstr \"Arduino CLI.\"\n\n#: cli/cli.go:68\nmsgid \"Arduino Command Line Interface (arduino-cli).\"\nmsgstr \"Arduino Command Line Interface (arduino-cli).\"\n\n#: cli/board/board.go:28\n#: cli/board/board.go:29\nmsgid \"Arduino board commands.\"\nmsgstr \"Arduino board commands.\"\n\n#: cli/cache/cache.go:31\n#: cli/cache/cache.go:32\nmsgid \"Arduino cache commands.\"\nmsgstr \"Arduino cache commands.\"\n\n#: cli/lib/lib.go:31\n#: cli/lib/lib.go:32\nmsgid \"Arduino commands about libraries.\"\nmsgstr \"Arduino commands about libraries.\"\n\n#: cli/config/config.go:31\nmsgid \"Arduino configuration commands.\"\nmsgstr \"Arduino configuration commands.\"\n\n#: cli/core/core.go:31\n#: cli/core/core.go:32\nmsgid \"Arduino core operations.\"\nmsgstr \"Arduino core operations.\"\n\n#: cli/lib/check_deps.go:50\n#: cli/lib/install.go:117\nmsgid \"Arguments error: %v\"\nmsgstr \"Arguments error: %v\"\n\n#: cli/board/attach.go:68\nmsgid \"Attach board error: %v\"\nmsgstr \"Attach board error: %v\"\n\n#: cli/board/attach.go:36\n#: cli/board/attach.go:37\n#: cli/board/board.go:32\nmsgid \"Attaches a sketch to a board.\"\nmsgstr \"Attaches a sketch to a board.\"\n\n#: cli/lib/search.go:162\nmsgid \"Author: %s\"\nmsgstr \"Author: %s\"\n\n#: cli/lib/list.go:125\nmsgid \"Available\"\nmsgstr \"Available\"\n\n#: cli/usage.go:28\nmsgid \"Available Commands:\"\nmsgstr \"Available Commands:\"\n\n#: cli/upload/upload.go:61\nmsgid \"Binary file to upload.\"\nmsgstr \"Binary file to upload.\"\n\n#: cli/board/list.go:87\n#: cli/board/list.go:125\n#: cli/board/listall.go:84\n#: cli/board/search.go:86\nmsgid \"Board Name\"\nmsgstr \"Board Name\"\n\n#: commands/board/attach.go:93\nmsgid \"Board found: %s\"\nmsgstr \"Board found: %s\"\n\n#: cli/board/details.go:120\nmsgid \"Board name:\"\nmsgstr \"Board name:\"\n\n#: cli/board/details.go:122\nmsgid \"Board version:\"\nmsgstr \"Board version:\"\n\n#: legacy/builder/constants/constants.go:96\nmsgid \"Board {0} (platform {1}, package {2}) is unknown\"\nmsgstr \"Board {0} (platform {1}, package {2}) is unknown\"\n\n#: legacy/builder/constants/constants.go:97\nmsgid \"Bootloader file specified but missing: {0}\"\nmsgstr \"Bootloader file specified but missing: {0}\"\n\n#: legacy/builder/constants/constants.go:99\nmsgid \"Build options changed\"\nmsgstr \"Build options changed\"\n\n#: cli/compile/compile.go:88\nmsgid \"Builds of 'core.a' are saved into this path to be cached and reused.\"\nmsgstr \"Builds of 'core.a' are saved into this path to be cached and reused.\"\n\n#: commands/instances.go:520\nmsgid \"Can't create data directory %s\"\nmsgstr \"Can't create data directory %s\"\n\n#: commands/lib/download.go:61\n#: commands/lib/download.go:64\n#: commands/lib/download.go:66\nmsgid \"Can't download library\"\nmsgstr \"Can't download library\"\n\n#: commands/core/install.go:127\n#: commands/core/uninstall.go:53\n#: commands/instances.go:746\n#: commands/instances.go:758\nmsgid \"Can't find dependencies for platform %s\"\nmsgstr \"Can't find dependencies for platform %s\"\n\n#: commands/errors.go:332\nmsgid \"Can't open sketch\"\nmsgstr \"Can't open sketch\"\n\n#: cli/config/set.go:54\nmsgid \"Can't set multiple values in key %v\"\nmsgstr \"Can't set multiple values in key %v\"\n\n#: cli/config/init.go:60\nmsgid \"Can't use both --dest-file and --dest-dir flags at the same time.\"\nmsgstr \"Can't use both --dest-file and --dest-dir flags at the same time.\"\n\n#: cli/config/add.go:60\n#: cli/config/delete.go:67\n#: cli/config/remove.go:69\nmsgid \"Can't write config file: %v\"\nmsgstr \"Can't write config file: %v\"\n\n#: commands/compile/compile.go:180\nmsgid \"Cannot create build cache directory\"\nmsgstr \"Cannot create build cache directory\"\n\n#: commands/compile/compile.go:150\nmsgid \"Cannot create build directory\"\nmsgstr \"Cannot create build directory\"\n\n#: cli/config/init.go:97\nmsgid \"Cannot create config file directory: %v\"\nmsgstr \"Cannot create config file directory: %v\"\n\n#: cli/config/init.go:106\nmsgid \"Cannot create config file: %v\"\nmsgstr \"Cannot create config file: %v\"\n\n#: commands/errors.go:558\nmsgid \"Cannot create temp dir\"\nmsgstr \"Cannot create temp dir\"\n\n#: commands/errors.go:576\nmsgid \"Cannot create temp file\"\nmsgstr \"Cannot create temp file\"\n\n#: commands/debug/debug.go:66\nmsgid \"Cannot execute debug tool\"\nmsgstr \"Cannot execute debug tool\"\n\n#: commands/board/attach.go:106\nmsgid \"Cannot export sketch metadata\"\nmsgstr \"Cannot export sketch metadata\"\n\n#: cli/config/init.go:72\n#: cli/config/init.go:83\nmsgid \"Cannot find absolute path: %v\"\nmsgstr \"Cannot find absolute path: %v\"\n\n#: configuration/configuration.go:147\n#: configuration/configuration.go:153\nmsgid \"Cannot get executable path: %v\"\nmsgstr \"Cannot get executable path: %v\"\n\n#: commands/core/install.go:134\nmsgid \"Cannot install platform\"\nmsgstr \"Cannot install platform\"\n\n#: commands/bundled_tools.go:54\nmsgid \"Cannot install tool %s\"\nmsgstr \"Cannot install tool %s\"\n\n#: commands/upload/upload.go:423\nmsgid \"Cannot perform port reset: %s\"\nmsgstr \"Cannot perform port reset: %s\"\n\n#: commands/core/install.go:152\nmsgid \"Cannot upgrade platform\"\nmsgstr \"Cannot upgrade platform\"\n\n#: cli/lib/search.go:170\nmsgid \"Category: %s\"\nmsgstr \"Category: %s\"\n\n#: cli/lib/check_deps.go:35\n#: cli/lib/check_deps.go:36\nmsgid \"Check dependencies status for the specified library.\"\nmsgstr \"Check dependencies status for the specified library.\"\n\n#: commands/lib/install.go:101\nmsgid \"Checking lib install prerequisites\"\nmsgstr \"Checking lib install prerequisites\"\n\n#: legacy/builder/builder_utils/utils.go:280\nmsgid \"Checking previous results for {0} (result = {1}, dep = {2})\"\nmsgstr \"Checking previous results for {0} (result = {1}, dep = {2})\"\n\n#: arduino/resources/checksums.go:182\nmsgid \"Checksum differs from checksum in package.json\"\nmsgstr \"Checksum differs from checksum in package.json\"\n\n#: cli/board/details.go:168\nmsgid \"Checksum:\"\nmsgstr \"Checksum:\"\n\n#: cli/cache/cache.go:33\nmsgid \"Clean caches.\"\nmsgstr \"Clean caches.\"\n\n#: cli/cli.go:106\nmsgid \"Comma-separated list of additional URLs for the Boards Manager.\"\nmsgstr \"Comma-separated list of additional URLs for the Boards Manager.\"\n\n#: cli/board/list.go:47\nmsgid \"Command keeps running and prints list of connected boards whenever there is a change.\"\nmsgstr \"Command keeps running and prints list of connected boards whenever there is a change.\"\n\n#: commands/debug/debug_info.go:118\n#: commands/upload/upload.go:358\nmsgid \"Compiled sketch not found in %s\"\nmsgstr \"Compiled sketch not found in %s\"\n\n#: cli/compile/compile.go:74\n#: cli/compile/compile.go:75\nmsgid \"Compiles Arduino sketches.\"\nmsgstr \"Compiles Arduino sketches.\"\n\n#: legacy/builder/builder.go:81\nmsgid \"Compiling core...\"\nmsgstr \"Compiling core...\"\n\n#: legacy/builder/builder.go:75\nmsgid \"Compiling libraries...\"\nmsgstr \"Compiling libraries...\"\n\n#: legacy/builder/phases/libraries_builder.go:135\nmsgid \"Compiling library \\\"{0}\\\"\"\nmsgstr \"Compiling library \\\"{0}\\\"\"\n\n#: legacy/builder/builder.go:70\nmsgid \"Compiling sketch...\"\nmsgstr \"Compiling sketch...\"\n\n#: cli/config/init.go:90\nmsgid \"Config file already exists, use --overwrite to discard the existing one.\"\nmsgstr \"Config file already exists, use --overwrite to discard the existing one.\"\n\n#: cli/config/init.go:110\nmsgid \"Config file written to: %s\"\nmsgstr \"Config file written to: %s\"\n\n#: commands/instances.go:845\nmsgid \"Configuring platform\"\nmsgstr \"Configuring platform\"\n\n#: commands/core/install.go:167\nmsgid \"Configuring platform.\"\nmsgstr \"Configuring platform.\"\n\n#: cli/board/list.go:183\nmsgid \"Connected\"\nmsgstr \"Connected\"\n\n#: cli/board/list.go:87\n#: cli/board/list.go:125\nmsgid \"Core\"\nmsgstr \"Core\"\n\n#: cli/update/update.go:99\nmsgid \"Core name\"\nmsgstr \"Core name\"\n\n#: commands/download.go:31\nmsgid \"Could not connect via HTTP\"\nmsgstr \"Could not connect via HTTP\"\n\n#: commands/instances.go:361\nmsgid \"Could not create index directory\"\nmsgstr \"Could not create index directory\"\n\n#: cli/sketch/new.go:58\nmsgid \"Could not create sketch directory: %v\"\nmsgstr \"Could not create sketch directory: %v\"\n\n#: legacy/builder/phases/core_builder.go:48\nmsgid \"Couldn't deeply cache core build: {0}\"\nmsgstr \"Couldn't deeply cache core build: {0}\"\n\n#: legacy/builder/constants/constants.go:127\nmsgid \"Couldn't determine program size\"\nmsgstr \"Couldn't determine program size\"\n\n#: cli/arguments/sketch.go:36\n#: cli/lib/install.go:97\nmsgid \"Couldn't get current working directory: %v\"\nmsgstr \"Couldn't get current working directory: %v\"\n\n#: cli/sketch/new.go:32\n#: cli/sketch/new.go:33\nmsgid \"Create a new Sketch\"\nmsgstr \"Create a new Sketch\"\n\n#: cli/sketch/archive.go:39\n#: cli/sketch/archive.go:40\nmsgid \"Creates a zip file containing all sketch files.\"\nmsgstr \"Creates a zip file containing all sketch files.\"\n\n#: cli/config/init.go:43\nmsgid \"Creates or updates the configuration file in the data directory or custom directory with the current configuration settings.\"\nmsgstr \"Creates or updates the configuration file in the data directory or custom directory with the current configuration settings.\"\n\n#: cli/debug/debug.go:55\nmsgid \"Debug Arduino sketches.\"\nmsgstr \"Debug Arduino sketches.\"\n\n#: cli/debug/debug.go:56\nmsgid \"Debug Arduino sketches. (this command opens an interactive gdb session)\"\nmsgstr \"Debug Arduino sketches. (this command opens an interactive gdb session)\"\n\n#: cli/debug/debug.go:65\nmsgid \"Debug interpreter e.g.: %s, %s, %s, %s, %s\"\nmsgstr \"Debug interpreter e.g.: %s, %s, %s, %s, %s\"\n\n#: commands/debug/debug_info.go:141\nmsgid \"Debugging not supported for board %s\"\nmsgstr \"Debugging not supported for board %s\"\n\n#: cli/board/details.go:124\nmsgid \"Debugging supported:\"\nmsgstr \"Debugging supported:\"\n\n#: cli/cache/clean.go:31\nmsgid \"Delete Boards/Library Manager download cache.\"\nmsgstr \"Delete Boards/Library Manager download cache.\"\n\n#: cli/cache/clean.go:32\nmsgid \"Delete contents of the `directories.downloads` folder, where archive files are staged during installation of libraries and boards platforms.\"\nmsgstr \"Delete contents of the `directories.downloads` folder, where archive files are staged during installation of libraries and boards platforms.\"\n\n#: cli/config/delete.go:32\n#: cli/config/delete.go:33\nmsgid \"Deletes a settings key and all its sub keys.\"\nmsgstr \"Deletes a settings key and all its sub keys.\"\n\n#: cli/lib/search.go:178\nmsgid \"Dependencies: %s\"\nmsgstr \"Dependencies: %s\"\n\n#: legacy/builder/builder_utils/utils.go:358\nmsgid \"Depfile is about different file: {0}\"\nmsgstr \"Depfile is about different file: {0}\"\n\n#: cli/lib/list.go:125\nmsgid \"Description\"\nmsgstr \"Description\"\n\n#: legacy/builder/builder.go:62\nmsgid \"Detecting libraries used...\"\nmsgstr \"Detecting libraries used...\"\n\n#: cli/board/list.go:38\nmsgid \"Detects and displays a list of boards connected to the current computer.\"\nmsgstr \"Detects and displays a list of boards connected to the current computer.\"\n\n#: cli/debug/debug.go:66\nmsgid \"Directory containing binaries for debug.\"\nmsgstr \"Directory containing binaries for debug.\"\n\n#: cli/upload/upload.go:60\nmsgid \"Directory containing binaries to upload.\"\nmsgstr \"Directory containing binaries to upload.\"\n\n#: cli/generatedocs/generatedocs.go:45\nmsgid \"Directory where to save generated files. Default is './docs', the directory must exist.\"\nmsgstr \"Directory where to save generated files. Default is './docs', the directory must exist.\"\n\n#: cli/completion/completion.go:44\nmsgid \"Disable completion description for shells that support it\"\nmsgstr \"Disable completion description for shells that support it\"\n\n#: cli/board/list.go:184\nmsgid \"Disconnected\"\nmsgstr \"Disconnected\"\n\n#: cli/lib/install.go:49\nmsgid \"Do not install dependencies.\"\nmsgstr \"Do not install dependencies.\"\n\n#: cli/burnbootloader/burnbootloader.go:58\n#: cli/upload/upload.go:65\nmsgid \"Do not perform the actual upload, just log out actions\"\nmsgstr \"Do not perform the actual upload, just log out actions\"\n\n#: cli/daemon/daemon.go:58\nmsgid \"Do not terminate daemon process if the parent process dies\"\nmsgstr \"Do not terminate daemon process if the parent process dies\"\n\n#: commands/instances.go:696\n#: commands/instances.go:755\n#: commands/lib/download.go:58\nmsgid \"Downloading %s\"\nmsgstr \"Downloading %s\"\n\n#: commands/instances.go:92\nmsgid \"Downloading missing tool %s\"\nmsgstr \"Downloading missing tool %s\"\n\n#: commands/core/install.go:87\nmsgid \"Downloading packages\"\nmsgstr \"Downloading packages\"\n\n#: cli/core/download.go:37\n#: cli/core/download.go:38\nmsgid \"Downloads one or more cores and corresponding tool dependencies.\"\nmsgstr \"Downloads one or more cores and corresponding tool dependencies.\"\n\n#: cli/lib/download.go:35\n#: cli/lib/download.go:36\nmsgid \"Downloads one or more libraries without installing them.\"\nmsgstr \"Downloads one or more libraries without installing them.\"\n\n#: cli/lib/install.go:51\nmsgid \"Enter a path to zip file\"\nmsgstr \"Enter a path to zip file\"\n\n#: cli/lib/install.go:50\nmsgid \"Enter git url for libraries hosted on repositories\"\nmsgstr \"Enter git url for libraries hosted on repositories\"\n\n#: commands/sketch/archive.go:105\nmsgid \"Error adding file to sketch archive\"\nmsgstr \"Error adding file to sketch archive\"\n\n#: legacy/builder/constants/constants.go:94\nmsgid \"Error archiving built core (caching) in {0}: {1}\"\nmsgstr \"Error archiving built core (caching) in {0}: {1}\"\n\n#: cli/sketch/archive.go:85\nmsgid \"Error archiving: %v\"\nmsgstr \"Error archiving: %v\"\n\n#: commands/sketch/archive.go:93\nmsgid \"Error calculating relative file path\"\nmsgstr \"Error calculating relative file path\"\n\n#: cli/cache/clean.go:46\nmsgid \"Error cleaning caches: %v\"\nmsgstr \"Error cleaning caches: %v\"\n\n#: commands/compile/compile.go:280\nmsgid \"Error copying output file %s\"\nmsgstr \"Error copying output file %s\"\n\n#: cli/core/search.go:66\n#: cli/core/update_index.go:52\n#: cli/instance/instance.go:42\n#: cli/lib/search.go:57\n#: cli/lib/update_index.go:45\n#: cli/update/update.go:62\nmsgid \"Error creating instance: %v\"\nmsgstr \"Error creating instance: %v\"\n\n#: commands/compile/compile.go:260\nmsgid \"Error creating output dir\"\nmsgstr \"Error creating output dir\"\n\n#: commands/sketch/archive.go:81\nmsgid \"Error creating sketch archive\"\nmsgstr \"Error creating sketch archive\"\n\n#: cli/sketch/new.go:54\n#: cli/sketch/new.go:64\nmsgid \"Error creating sketch: %v\"\nmsgstr \"Error creating sketch: %v\"\n\n#: cli/board/list.go:71\n#: cli/board/list.go:80\nmsgid \"Error detecting boards: %v\"\nmsgstr \"Error detecting boards: %v\"\n\n#: cli/core/download.go:68\n#: cli/lib/download.go:62\nmsgid \"Error downloading %[1]s: %[2]v\"\nmsgstr \"Error downloading %[1]s: %[2]v\"\n\n#: commands/instances.go:466\n#: commands/instances.go:470\n#: commands/instances.go:475\nmsgid \"Error downloading index '%s'\"\nmsgstr \"Error downloading index '%s'\"\n\n#: commands/instances.go:499\n#: commands/instances.go:505\nmsgid \"Error downloading index signature '%s'\"\nmsgstr \"Error downloading index signature '%s'\"\n\n#: commands/instances.go:698\n#: commands/instances.go:700\nmsgid \"Error downloading library\"\nmsgstr \"Error downloading library\"\n\n#: commands/instances.go:375\n#: commands/instances.go:378\nmsgid \"Error downloading library_index.json.gz\"\nmsgstr \"Error downloading library_index.json.gz\"\n\n#: commands/instances.go:385\n#: commands/instances.go:388\nmsgid \"Error downloading library_index.json.sig\"\nmsgstr \"Error downloading library_index.json.sig\"\n\n#: commands/core/download.go:70\n#: commands/core/download.go:74\n#: commands/instances.go:781\n#: commands/instances.go:783\nmsgid \"Error downloading platform %s\"\nmsgstr \"Error downloading platform %s\"\n\n#: commands/core/download.go:83\n#: commands/core/download.go:88\n#: commands/instances.go:774\n#: commands/instances.go:775\nmsgid \"Error downloading tool %s\"\nmsgstr \"Error downloading tool %s\"\n\n#: cli/debug/debug.go:82\n#: cli/debug/debug.go:87\n#: cli/debug/debug.go:116\nmsgid \"Error during Debug: %v\"\nmsgstr \"Error during Debug: %v\"\n\n#: cli/feedback/feedback.go:134\nmsgid \"Error during JSON encoding of the output: %v\"\nmsgstr \"Error during JSON encoding of the output: %v\"\n\n#: cli/burnbootloader/burnbootloader.go:70\n#: cli/burnbootloader/burnbootloader.go:83\n#: cli/compile/compile.go:196\n#: cli/compile/compile.go:202\n#: cli/compile/compile.go:212\n#: cli/compile/compile.go:244\n#: cli/upload/upload.go:96\n#: cli/upload/upload.go:101\n#: cli/upload/upload.go:111\n#: cli/upload/upload.go:134\nmsgid \"Error during Upload: %v\"\nmsgstr \"Error during Upload: %v\"\n\n#: cli/compile/compile.go:256\nmsgid \"Error during build: %v\"\nmsgstr \"Error during build: %v\"\n\n#: cli/core/install.go:106\nmsgid \"Error during install: %v\"\nmsgstr \"Error during install: %v\"\n\n#: cli/core/uninstall.go:68\nmsgid \"Error during uninstall: %v\"\nmsgstr \"Error during uninstall: %v\"\n\n#: cli/core/upgrade.go:105\nmsgid \"Error during upgrade: %v\"\nmsgstr \"Error during upgrade: %v\"\n\n#: commands/instances.go:394\nmsgid \"Error extracting library_index.json.gz\"\nmsgstr \"Error extracting library_index.json.gz\"\n\n#: commands/upload/upload.go:355\nmsgid \"Error finding build artifacts\"\nmsgstr \"Error finding build artifacts\"\n\n#: cli/debug/debug.go:103\nmsgid \"Error getting Debug info: %v\"\nmsgstr \"Error getting Debug info: %v\"\n\n#: commands/sketch/archive.go:59\nmsgid \"Error getting absolute path of sketch archive\"\nmsgstr \"Error getting absolute path of sketch archive\"\n\n#: cli/board/details.go:71\nmsgid \"Error getting board details: %v\"\nmsgstr \"Error getting board details: %v\"\n\n#: commands/board/list.go:140\nmsgid \"Error getting board info from Arduino Cloud\"\nmsgstr \"Error getting board info from Arduino Cloud\"\n\n#: commands/board/list.go:205\nmsgid \"Error getting board list\"\nmsgstr \"Error getting board list\"\n\n#: arduino/builder/compilation_database.go:78\nmsgid \"Error getting current directory for compilation database: %s\"\nmsgstr \"Error getting current directory for compilation database: %s\"\n\n#: commands/compile/compile.go:289\n#: commands/lib/list.go:106\nmsgid \"Error getting information for library %s\"\nmsgstr \"Error getting information for library %s\"\n\n#: cli/lib/examples.go:69\nmsgid \"Error getting libraries info: %v\"\nmsgstr \"Error getting libraries info: %v\"\n\n#: legacy/builder/types/context.go:239\nmsgid \"Error in FQBN: %s\"\nmsgstr \"Error in FQBN: %s\"\n\n#: cli/core/search.go:81\n#: cli/instance/instance.go:46\n#: cli/lib/search.go:71\n#: cli/update/update.go:87\nmsgid \"Error initializing instance: %v\"\nmsgstr \"Error initializing instance: %v\"\n\n#: cli/lib/install.go:130\nmsgid \"Error installing %s: %v\"\nmsgstr \"Error installing %s: %v\"\n\n#: cli/lib/install.go:108\nmsgid \"Error installing Git Library: %v\"\nmsgstr \"Error installing Git Library: %v\"\n\n#: cli/lib/install.go:85\nmsgid \"Error installing Zip Library: %v\"\nmsgstr \"Error installing Zip Library: %v\"\n\n#: commands/instances.go:802\nmsgid \"Error installing platform %s\"\nmsgstr \"Error installing platform %s\"\n\n#: commands/instances.go:792\nmsgid \"Error installing tool %s\"\nmsgstr \"Error installing tool %s\"\n\n#: cli/lib/list.go:77\nmsgid \"Error listing Libraries: %v\"\nmsgstr \"Error listing Libraries: %v\"\n\n#: cli/board/listall.go:61\nmsgid \"Error listing boards: %v\"\nmsgstr \"Error listing boards: %v\"\n\n#: cli/core/list.go:61\nmsgid \"Error listing platforms: %v\"\nmsgstr \"Error listing platforms: %v\"\n\n#: cli/compile/compile.go:147\nmsgid \"Error opening source code overrides data file: %v\"\nmsgstr \"Error opening source code overrides data file: %v\"\n\n#: commands/compile/compile.go:270\nmsgid \"Error reading build directory\"\nmsgstr \"Error reading build directory\"\n\n#: configuration/configuration.go:69\nmsgid \"Error reading config file: %v\"\nmsgstr \"Error reading config file: %v\"\n\n#: commands/sketch/archive.go:75\nmsgid \"Error reading sketch files\"\nmsgstr \"Error reading sketch files\"\n\n#: legacy/builder/target_board_resolver.go:33\nmsgid \"Error resolving FQBN: {0}\"\nmsgstr \"Error resolving FQBN: {0}\"\n\n#: cli/lib/check_deps.go:60\nmsgid \"Error resolving dependencies for %[1]s: %[2]s\"\nmsgstr \"Error resolving dependencies for %[1]s: %[2]s\"\n\n#: cli/core/upgrade.go:63\nmsgid \"Error retrieving core list: %v\"\nmsgstr \"Error retrieving core list: %v\"\n\n#: cli/outdated/outdated.go:57\n#: cli/update/update.go:94\nmsgid \"Error retrieving outdated cores and libraries: %v\"\nmsgstr \"Error retrieving outdated cores and libraries: %v\"\n\n#: commands/instances.go:818\nmsgid \"Error rolling-back changes\"\nmsgstr \"Error rolling-back changes\"\n\n#: commands/core/install.go:149\nmsgid \"Error rolling-back changes: %s\"\nmsgstr \"Error rolling-back changes: %s\"\n\n#: commands/instances.go:524\nmsgid \"Error saving downloaded index %s\"\nmsgstr \"Error saving downloaded index %s\"\n\n#: commands/instances.go:528\nmsgid \"Error saving downloaded index signature\"\nmsgstr \"Error saving downloaded index signature\"\n\n#: cli/board/search.go:63\nmsgid \"Error searching boards: %v\"\nmsgstr \"Error searching boards: %v\"\n\n#: cli/lib/search.go:80\nmsgid \"Error searching for Library: %v\"\nmsgstr \"Error searching for Library: %v\"\n\n#: cli/core/search.go:93\nmsgid \"Error searching for platforms: %v\"\nmsgstr \"Error searching for platforms: %v\"\n\n#: arduino/builder/compilation_database.go:63\nmsgid \"Error serializing compilation database: %s\"\nmsgstr \"Error serializing compilation database: %s\"\n\n#: commands/board/list.go:190\n#: commands/board/list.go:193\n#: commands/board/list.go:234\nmsgid \"Error starting board discoveries\"\nmsgstr \"Error starting board discoveries\"\n\n#: cli/lib/uninstall.go:62\nmsgid \"Error uninstalling %[1]s: %[2]v\"\nmsgstr \"Error uninstalling %[1]s: %[2]v\"\n\n#: commands/core/uninstall.go:81\nmsgid \"Error uninstalling platform %s\"\nmsgstr \"Error uninstalling platform %s\"\n\n#: commands/core/uninstall.go:97\n#: commands/instances.go:834\nmsgid \"Error uninstalling tool %s\"\nmsgstr \"Error uninstalling tool %s\"\n\n#: cli/update/update.go:79\nmsgid \"Error updating core and libraries index: %v\"\nmsgstr \"Error updating core and libraries index: %v\"\n\n#: cli/core/search.go:75\n#: cli/core/update_index.go:69\nmsgid \"Error updating index: %v\"\nmsgstr \"Error updating index: %v\"\n\n#: cli/core/update_index.go:61\n#: cli/lib/update_index.go:54\n#: cli/update/update.go:71\nmsgid \"Error updating indexes: %v\"\nmsgstr \"Error updating indexes: %v\"\n\n#: cli/lib/search.go:66\n#: cli/lib/update_index.go:62\nmsgid \"Error updating library index: %v\"\nmsgstr \"Error updating library index: %v\"\n\n#: cli/lib/upgrade.go:50\n#: cli/lib/upgrade.go:56\nmsgid \"Error upgrading libraries: %v\"\nmsgstr \"Error upgrading libraries: %v\"\n\n#: commands/core/install.go:144\n#: commands/instances.go:813\nmsgid \"Error upgrading platform: %s\"\nmsgstr \"Error upgrading platform: %s\"\n\n#: cli/upgrade/upgrade.go:60\nmsgid \"Error upgrading: %v\"\nmsgstr \"Error upgrading: %v\"\n\n#: commands/instances.go:399\n#: commands/instances.go:509\nmsgid \"Error verifying signature\"\nmsgstr \"Error verifying signature\"\n\n#: legacy/builder/constants/constants.go:104\nmsgid \"Error while detecting libraries included by {0}\"\nmsgstr \"Error while detecting libraries included by {0}\"\n\n#: legacy/builder/phases/sizer.go:135\n#: legacy/builder/phases/sizer.go:141\nmsgid \"Error while determining sketch size: %s\"\nmsgstr \"Error while determining sketch size: %s\"\n\n#: arduino/builder/compilation_database.go:66\nmsgid \"Error writing compilation database: %s\"\nmsgstr \"Error writing compilation database: %s\"\n\n#: commands/instances.go:408\nmsgid \"Error writing library_index.json\"\nmsgstr \"Error writing library_index.json\"\n\n#: commands/instances.go:411\nmsgid \"Error writing library_index.json.sig\"\nmsgstr \"Error writing library_index.json.sig\"\n\n#: cli/completion/completion.go:51\nmsgid \"Error: command description is not supported by %v\"\nmsgstr \"Error: command description is not supported by %v\"\n\n#: cli/compile/compile.go:154\nmsgid \"Error: invalid source code overrides data file: %v\"\nmsgstr \"Error: invalid source code overrides data file: %v\"\n\n#: cli/board/list.go:87\nmsgid \"Event\"\nmsgstr \"Event\"\n\n#: cli/lib/examples.go:118\nmsgid \"Examples for library %s\"\nmsgstr \"Examples for library %s\"\n\n#: cli/usage.go:27\nmsgid \"Examples:\"\nmsgstr \"Examples:\"\n\n#: cli/debug/debug.go:135\nmsgid \"Executable to debug\"\nmsgstr \"Executable to debug\"\n\n#: commands/debug/debug_info.go:121\n#: commands/upload/upload.go:361\nmsgid \"Expected compiled sketch in directory %s, but is a file instead\"\nmsgstr \"Expected compiled sketch in directory %s, but is a file instead\"\n\n#: cli/board/attach.go:35\n#: cli/board/details.go:41\n#: cli/board/list.go:87\n#: cli/board/list.go:125\n#: cli/board/listall.go:84\n#: cli/board/search.go:86\nmsgid \"FQBN\"\nmsgstr \"FQBN\"\n\n#: cli/board/details.go:121\nmsgid \"FQBN:\"\nmsgstr \"FQBN:\"\n\n#: commands/upload/upload.go:454\nmsgid \"Failed chip erase\"\nmsgstr \"Failed chip erase\"\n\n#: commands/upload/upload.go:461\nmsgid \"Failed programming\"\nmsgstr \"Failed programming\"\n\n#: commands/upload/upload.go:457\nmsgid \"Failed to burn bootloader\"\nmsgstr \"Failed to burn bootloader\"\n\n#: commands/instances.go:122\nmsgid \"Failed to create data directory\"\nmsgstr \"Failed to create data directory\"\n\n#: commands/instances.go:112\nmsgid \"Failed to create downloads directory\"\nmsgstr \"Failed to create downloads directory\"\n\n#: cli/daemon/daemon.go:114\nmsgid \"Failed to listen on TCP port: %[1]s. %[2]s is an invalid port.\"\nmsgstr \"Failed to listen on TCP port: %[1]s. %[2]s is an invalid port.\"\n\n#: cli/daemon/daemon.go:108\nmsgid \"Failed to listen on TCP port: %[1]s. %[2]s is unknown name.\"\nmsgstr \"Failed to listen on TCP port: %[1]s. %[2]s is unknown name.\"\n\n#: cli/daemon/daemon.go:123\nmsgid \"Failed to listen on TCP port: %[1]s. Unexpected error: %[2]v\"\nmsgstr \"Failed to listen on TCP port: %[1]s. Unexpected error: %[2]v\"\n\n#: cli/daemon/daemon.go:120\nmsgid \"Failed to listen on TCP port: %s. Address already in use.\"\nmsgstr \"Failed to listen on TCP port: %s. Address already in use.\"\n\n#: legacy/builder/builder_utils/utils.go:380\nmsgid \"Failed to read: {0}\"\nmsgstr \"Failed to read: {0}\"\n\n#: commands/upload/upload.go:465\nmsgid \"Failed uploading\"\nmsgstr \"Failed uploading\"\n\n#: cli/board/details.go:166\nmsgid \"File:\"\nmsgstr \"File:\"\n\n#: commands/daemon/debug.go:47\nmsgid \"First message must contain debug request, not data\"\nmsgstr \"First message must contain debug request, not data\"\n\n#: cli/usage.go:29\nmsgid \"Flags:\"\nmsgstr \"Flags:\"\n\n#: cli/core/install.go:59\nmsgid \"Force run of post-install scripts (if the CLI is not running interactively).\"\nmsgstr \"Force run of post-install scripts (if the CLI is not running interactively).\"\n\n#: cli/core/install.go:60\nmsgid \"Force skip of post-install scripts (if the CLI is running interactively).\"\nmsgstr \"Force skip of post-install scripts (if the CLI is running interactively).\"\n\n#: cli/board/details.go:50\n#: cli/burnbootloader/burnbootloader.go:53\n#: cli/compile/compile.go:85\n#: cli/debug/debug.go:62\n#: cli/upload/upload.go:58\nmsgid \"Fully Qualified Board Name, e.g.: arduino:avr:uno\"\nmsgstr \"Fully Qualified Board Name, e.g.: arduino:avr:uno\"\n\n#: cli/debug/debug.go:149\nmsgid \"GDB Server path\"\nmsgstr \"GDB Server path\"\n\n#: cli/debug/debug.go:148\nmsgid \"GDB Server type\"\nmsgstr \"GDB Server type\"\n\n#: commands/debug/debug.go:172\nmsgid \"GDB server '%s' is not supported\"\nmsgstr \"GDB server '%s' is not supported\"\n\n#: cli/generatedocs/generatedocs.go:38\n#: cli/generatedocs/generatedocs.go:39\nmsgid \"Generates bash completion and command manpages.\"\nmsgstr \"Generates bash completion and command manpages.\"\n\n#: cli/completion/completion.go:38\nmsgid \"Generates completion scripts\"\nmsgstr \"Generates completion scripts\"\n\n#: cli/completion/completion.go:39\nmsgid \"Generates completion scripts for various shells\"\nmsgstr \"Generates completion scripts for various shells\"\n\n#: legacy/builder/builder.go:67\nmsgid \"Generating function prototypes...\"\nmsgstr \"Generating function prototypes...\"\n\n#: cli/usage.go:30\nmsgid \"Global Flags:\"\nmsgstr \"Global Flags:\"\n\n#: legacy/builder/constants/constants.go:122\nmsgid \"Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes.\"\nmsgstr \"Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes.\"\n\n#: legacy/builder/constants/constants.go:123\nmsgid \"Global variables use {0} bytes of dynamic memory.\"\nmsgstr \"Global variables use {0} bytes of dynamic memory.\"\n\n#: cli/core/list.go:84\n#: cli/core/search.go:114\n#: cli/outdated/outdated.go:62\nmsgid \"ID\"\nmsgstr \"ID\"\n\n#: cli/board/details.go:93\n#: cli/board/details.go:194\nmsgid \"Id\"\nmsgstr \"Id\"\n\n#: cli/board/details.go:135\nmsgid \"Identification properties:\"\nmsgstr \"Identification properties:\"\n\n#: cli/compile/compile.go:115\nmsgid \"If set built binaries will be exported to the sketch folder.\"\nmsgstr \"If set built binaries will be exported to the sketch folder.\"\n\n#: cli/core/list.go:42\nmsgid \"If set return all installable and installed cores, including manually installed.\"\nmsgstr \"If set return all installable and installed cores, including manually installed.\"\n\n#: cli/lib/list.go:48\nmsgid \"Include built-in libraries (from platforms and IDE) in listing.\"\nmsgstr \"Include built-in libraries (from platforms and IDE) in listing.\"\n\n#: cli/sketch/archive.go:51\nmsgid \"Includes %s directory in the archive.\"\nmsgstr \"Includes %s directory in the archive.\"\n\n#: cli/core/list.go:84\n#: cli/lib/list.go:125\nmsgid \"Installed\"\nmsgstr \"Installed\"\n\n#: commands/instances.go:721\n#: commands/lib/install.go:112\nmsgid \"Installed %s\"\nmsgstr \"Installed %s\"\n\n#: cli/outdated/outdated.go:62\n#: cli/outdated/outdated.go:72\n#: cli/update/update.go:99\n#: cli/update/update.go:109\nmsgid \"Installed version\"\nmsgstr \"Installed version\"\n\n#: commands/bundled_tools.go:50\n#: commands/instances.go:704\n#: commands/lib/install.go:92\nmsgid \"Installing %s\"\nmsgstr \"Installing %s\"\n\n#: commands/core/install.go:110\nmsgid \"Installing platform %s\"\nmsgstr \"Installing platform %s\"\n\n#: cli/core/install.go:38\n#: cli/core/install.go:39\nmsgid \"Installs one or more cores and corresponding tool dependencies.\"\nmsgstr \"Installs one or more cores and corresponding tool dependencies.\"\n\n#: cli/lib/install.go:39\n#: cli/lib/install.go:40\nmsgid \"Installs one or more specified libraries into the system.\"\nmsgstr \"Installs one or more specified libraries into the system.\"\n\n#: legacy/builder/container_find_includes.go:378\nmsgid \"Internal error in cache\"\nmsgstr \"Internal error in cache\"\n\n#: commands/errors.go:218\nmsgid \"Invalid '%[1]s' property: %[2]s\"\nmsgstr \"Invalid '%[1]s' property: %[2]s\"\n\n#: cli/cli.go:224\nmsgid \"Invalid Call : should show Help, but it is available only in TEXT mode.\"\nmsgstr \"Invalid Call : should show Help, but it is available only in TEXT mode.\"\n\n#: commands/board/attach.go:65\nmsgid \"Invalid Device URL format\"\nmsgstr \"Invalid Device URL format\"\n\n#: commands/errors.go:57\nmsgid \"Invalid FQBN\"\nmsgstr \"Invalid FQBN\"\n\n#: commands/errors.go:75\nmsgid \"Invalid URL\"\nmsgstr \"Invalid URL\"\n\n#: commands/instances.go:191\nmsgid \"Invalid additional URL: %v\"\nmsgstr \"Invalid additional URL: %v\"\n\n#: cli/core/download.go:55\n#: cli/core/install.go:92\n#: cli/core/uninstall.go:51\n#: cli/core/upgrade.go:81\n#: cli/lib/download.go:50\n#: cli/lib/uninstall.go:51\nmsgid \"Invalid argument passed: %v\"\nmsgstr \"Invalid argument passed: %v\"\n\n#: legacy/builder/phases/sizer.go:160\nmsgid \"Invalid data size regexp: %s\"\nmsgstr \"Invalid data size regexp: %s\"\n\n#: commands/board/attach.go:75\nmsgid \"Invalid device port type provided\"\nmsgstr \"Invalid device port type provided\"\n\n#: legacy/builder/phases/sizer.go:166\nmsgid \"Invalid eeprom size regexp: %s\"\nmsgstr \"Invalid eeprom size regexp: %s\"\n\n#: commands/errors.go:43\nmsgid \"Invalid instance\"\nmsgstr \"Invalid instance\"\n\n#: cli/core/upgrade.go:87\nmsgid \"Invalid item %s\"\nmsgstr \"Invalid item %s\"\n\n#: commands/errors.go:93\nmsgid \"Invalid library\"\nmsgstr \"Invalid library\"\n\n#: httpclient/httpclient_config.go:44\nmsgid \"Invalid network.proxy '%[1]s': %[2]s\"\nmsgstr \"Invalid network.proxy '%[1]s': %[2]s\"\n\n#: cli/cli.go:185\nmsgid \"Invalid option for --log-level: %s\"\nmsgstr \"Invalid option for --log-level: %s\"\n\n#: cli/cli.go:202\nmsgid \"Invalid output format: %s\"\nmsgstr \"Invalid output format: %s\"\n\n#: commands/instances.go:442\n#: commands/instances.go:516\nmsgid \"Invalid package index in %s\"\nmsgstr \"Invalid package index in %s\"\n\n#: cli/core/uninstall.go:57\nmsgid \"Invalid parameter %s: version not allowed\"\nmsgstr \"Invalid parameter %s: version not allowed\"\n\n#: commands/board/list.go:51\nmsgid \"Invalid pid value: '%s'\"\nmsgstr \"Invalid pid value: '%s'\"\n\n#: legacy/builder/phases/sizer.go:150\nmsgid \"Invalid size regexp: %s\"\nmsgstr \"Invalid size regexp: %s\"\n\n#: commands/errors.go:111\nmsgid \"Invalid version\"\nmsgstr \"Invalid version\"\n\n#: commands/board/list.go:48\nmsgid \"Invalid vid value: '%s'\"\nmsgstr \"Invalid vid value: '%s'\"\n\n#: cli/compile/compile.go:110\nmsgid \"Just produce the compilation database, without actually compiling.\"\nmsgstr \"Just produce the compilation database, without actually compiling.\"\n\n#: cli/lib/list.go:37\nmsgid \"LIBNAME\"\nmsgstr \"LIBNAME\"\n\n#: cli/lib/check_deps.go:34\n#: cli/lib/install.go:38\nmsgid \"LIBRARY\"\nmsgstr \"LIBRARY\"\n\n#: cli/lib/download.go:34\n#: cli/lib/examples.go:38\n#: cli/lib/search.go:39\n#: cli/lib/uninstall.go:35\nmsgid \"LIBRARY_NAME\"\nmsgstr \"LIBRARY_NAME\"\n\n#: cli/core/list.go:84\nmsgid \"Latest\"\nmsgstr \"Latest\"\n\n#: commands/lib/uninstall.go:37\nmsgid \"Library %s is not installed\"\nmsgstr \"Library %s is not installed\"\n\n#: commands/errors.go:266\nmsgid \"Library '%s' not found\"\nmsgstr \"Library '%s' not found\"\n\n#: legacy/builder/constants/constants.go:109\nmsgid \"Library can't use both '%[1]s' and '%[2]s' folders. Double check {0}\"\nmsgstr \"Library can't use both '%[1]s' and '%[2]s' folders. Double check {0}\"\n\n#: commands/errors.go:369\nmsgid \"Library install failed\"\nmsgstr \"Library install failed\"\n\n#: commands/lib/install.go:122\n#: commands/lib/install.go:132\nmsgid \"Library installed\"\nmsgstr \"Library installed\"\n\n#: cli/outdated/outdated.go:72\n#: cli/update/update.go:109\nmsgid \"Library name\"\nmsgstr \"Library name\"\n\n#: legacy/builder/phases/libraries_builder.go:91\nmsgid \"Library {0} has been declared precompiled:\"\nmsgstr \"Library {0} has been declared precompiled:\"\n\n#: cli/lib/search.go:168\nmsgid \"License: %s\"\nmsgstr \"License: %s\"\n\n#: legacy/builder/builder.go:86\nmsgid \"Linking everything together...\"\nmsgstr \"Linking everything together...\"\n\n#: cli/board/listall.go:37\n#: cli/board/search.go:38\nmsgid \"List all boards that have the support platform installed. You can search\\n\"\n\"for a specific board if you specify the board name\"\nmsgstr \"List all boards that have the support platform installed. You can search\\n\"\n\"for a specific board if you specify the board name\"\n\n#: cli/board/listall.go:36\n#: cli/board/search.go:37\nmsgid \"List all known boards and their corresponding FQBN.\"\nmsgstr \"List all known boards and their corresponding FQBN.\"\n\n#: cli/board/list.go:37\nmsgid \"List connected boards.\"\nmsgstr \"List connected boards.\"\n\n#: cli/compile/compile.go:93\nmsgid \"List of custom build properties separated by commas. Or can be used multiple times for multiple properties.\"\nmsgstr \"List of custom build properties separated by commas. Or can be used multiple times for multiple properties.\"\n\n#: cli/compile/compile.go:107\nmsgid \"List of custom libraries dir paths separated by commas. Or can be used multiple times for multiple libraries dir paths.\"\nmsgstr \"List of custom libraries dir paths separated by commas. Or can be used multiple times for multiple libraries dir paths.\"\n\n#: cli/compile/compile.go:105\nmsgid \"List of paths to libraries root folders. Libraries set this way have top priority in case of conflicts. Can be used multiple times for different libraries.\"\nmsgstr \"List of paths to libraries root folders. Libraries set this way have top priority in case of conflicts. Can be used multiple times for different libraries.\"\n\n#: cli/lib/list.go:50\nmsgid \"List updatable libraries.\"\nmsgstr \"List updatable libraries.\"\n\n#: cli/core/list.go:41\nmsgid \"List updatable platforms.\"\nmsgstr \"List updatable platforms.\"\n\n#: cli/board/board.go:30\nmsgid \"Lists all connected boards.\"\nmsgstr \"Lists all connected boards.\"\n\n#: cli/outdated/outdated.go:38\nmsgid \"Lists cores and libraries that can be upgraded\"\nmsgstr \"Lists cores and libraries that can be upgraded\"\n\n#: commands/instances.go:205\n#: commands/instances.go:216\n#: commands/instances.go:317\nmsgid \"Loading index file: %v\"\nmsgstr \"Loading index file: %v\"\n\n#: commands/instances.go:326\nmsgid \"Loading libraries: %v\"\nmsgstr \"Loading libraries: %v\"\n\n#: cli/lib/list.go:125\nmsgid \"Location\"\nmsgstr \"Location\"\n\n#: legacy/builder/constants/constants.go:111\nmsgid \"Looking for recipes like {0}*{1}\"\nmsgstr \"Looking for recipes like {0}*{1}\"\n\n#: legacy/builder/constants/constants.go:126\nmsgid \"Low memory available, stability problems may occur.\"\nmsgstr \"Low memory available, stability problems may occur.\"\n\n#: cli/lib/search.go:163\nmsgid \"Maintainer: %s\"\nmsgstr \"Maintainer: %s\"\n\n#: cli/arguments/port.go:46\nmsgid \"Max time to wait for port discovery, e.g.: 30s, 1m\"\nmsgstr \"Max time to wait for port discovery, e.g.: 30s, 1m\"\n\n#: cli/cli.go:101\nmsgid \"Messages with this level and above will be logged. Valid levels are: %s, %s, %s, %s, %s, %s, %s\"\nmsgstr \"Messages with this level and above will be logged. Valid levels are: %s, %s, %s, %s, %s, %s, %s\"\n\n#: legacy/builder/constants/constants.go:117\nmsgid \"Missing '{0}' from library in {1}\"\nmsgstr \"Missing '{0}' from library in {1}\"\n\n#: commands/errors.go:127\nmsgid \"Missing FQBN (Fully Qualified Board Name)\"\nmsgstr \"Missing FQBN (Fully Qualified Board Name)\"\n\n#: commands/errors.go:157\nmsgid \"Missing port protocol\"\nmsgstr \"Missing port protocol\"\n\n#: commands/errors.go:169\nmsgid \"Missing programmer\"\nmsgstr \"Missing programmer\"\n\n#: legacy/builder/phases/sizer.go:154\nmsgid \"Missing size regexp\"\nmsgstr \"Missing size regexp\"\n\n#: commands/errors.go:318\nmsgid \"Missing sketch path\"\nmsgstr \"Missing sketch path\"\n\n#: legacy/builder/constants/constants.go:106\nmsgid \"Multiple libraries were found for \\\"{0}\\\"\"\nmsgstr \"Multiple libraries were found for \\\"{0}\\\"\"\n\n#: cli/board/details.go:194\n#: cli/core/list.go:84\n#: cli/core/search.go:114\n#: cli/lib/list.go:125\n#: cli/outdated/outdated.go:62\nmsgid \"Name\"\nmsgstr \"Name\"\n\n#: cli/lib/search.go:142\nmsgid \"Name: \\\"%s\\\"\"\nmsgstr \"Name: \\\"%s\\\"\"\n\n#: cli/outdated/outdated.go:62\n#: cli/outdated/outdated.go:72\n#: cli/update/update.go:99\n#: cli/update/update.go:109\nmsgid \"New version\"\nmsgstr \"New version\"\n\n#: cli/board/list.go:115\nmsgid \"No boards found.\"\nmsgstr \"No boards found.\"\n\n#: legacy/builder/builder_utils/utils.go:351\nmsgid \"No colon in first line of depfile\"\nmsgstr \"No colon in first line of depfile\"\n\n#: cli/lib/examples.go:103\nmsgid \"No libraries found.\"\nmsgstr \"No libraries found.\"\n\n#: cli/lib/list.go:117\nmsgid \"No libraries installed.\"\nmsgstr \"No libraries installed.\"\n\n#: cli/lib/search.go:126\nmsgid \"No libraries matching your search.\"\nmsgstr \"No libraries matching your search.\"\n\n#: cli/lib/search.go:137\nmsgid \"No libraries matching your search.\\n\"\n\"Did you mean...\\n\"\n\"\"\nmsgstr \"No libraries matching your search.\\n\"\n\"Did you mean...\\n\"\n\"\"\n\n#: cli/core/search.go:124\nmsgid \"No platforms matching your search.\"\nmsgstr \"No platforms matching your search.\"\n\n#: commands/board/attach.go:91\nmsgid \"No supported board found at %s\"\nmsgstr \"No supported board found at %s\"\n\n#: cli/lib/list.go:115\nmsgid \"No updates available.\"\nmsgstr \"No updates available.\"\n\n#: commands/upload/upload.go:412\nmsgid \"No upload port found, using %s as fallback\"\nmsgstr \"No upload port found, using %s as fallback\"\n\n#: commands/errors.go:285\nmsgid \"No valid dependencies solution found\"\nmsgstr \"No valid dependencies solution found\"\n\n#: legacy/builder/constants/constants.go:125\nmsgid \"Not enough memory; see %s for tips on reducing your footprint.\"\nmsgstr \"Not enough memory; see %s for tips on reducing your footprint.\"\n\n#: legacy/builder/builder_utils/utils.go:284\nmsgid \"Not found: nil\"\nmsgstr \"Not found: nil\"\n\n#: legacy/builder/builder_utils/utils.go:300\n#: legacy/builder/builder_utils/utils.go:313\n#: legacy/builder/builder_utils/utils.go:387\nmsgid \"Not found: {0}\"\nmsgstr \"Not found: {0}\"\n\n#: cli/board/details.go:165\nmsgid \"OS:\"\nmsgstr \"OS:\"\n\n#: cli/board/details.go:129\nmsgid \"Official Arduino board:\"\nmsgstr \"Official Arduino board:\"\n\n#: cli/board/details.go:177\nmsgid \"Option:\"\nmsgstr \"Option:\"\n\n#: cli/compile/compile.go:97\nmsgid \"Optional, can be \\\"%[1]s\\\", \\\"%[2]s\\\", \\\"%[3]s\\\" and \\\"%[4]s\\\". Defaults to \\\"%[1]s\\\". Used to tell gcc which warning level to use (-W flag).\"\nmsgstr \"Optional, can be \\\"%[1]s\\\", \\\"%[2]s\\\", \\\"%[3]s\\\" and \\\"%[4]s\\\". Defaults to \\\"%[1]s\\\". Used to tell gcc which warning level to use (-W flag).\"\n\n#: cli/compile/compile.go:111\nmsgid \"Optional, cleanup the build folder and do not use any cached build.\"\nmsgstr \"Optional, cleanup the build folder and do not use any cached build.\"\n\n#: cli/compile/compile.go:108\nmsgid \"Optional, optimize compile output for debugging, rather than for release.\"\nmsgstr \"Optional, optimize compile output for debugging, rather than for release.\"\n\n#: cli/compile/compile.go:99\nmsgid \"Optional, suppresses almost every output.\"\nmsgstr \"Optional, suppresses almost every output.\"\n\n#: cli/compile/compile.go:98\n#: cli/upload/upload.go:63\nmsgid \"Optional, turns on verbose mode.\"\nmsgstr \"Optional, turns on verbose mode.\"\n\n#: cli/compile/compile.go:109\n#: cli/upload/upload.go:64\nmsgid \"Optional, use the specified programmer to upload.\"\nmsgstr \"Optional, use the specified programmer to upload.\"\n\n#: cli/compile/compile.go:116\nmsgid \"Optional. Path to a .json file that contains a set of replacements of the sketch source code.\"\nmsgstr \"Optional. Path to a .json file that contains a set of replacements of the sketch source code.\"\n\n#: commands/daemon/monitor.go:72\nmsgid \"OutputRate in Null monitor must be a float64\"\nmsgstr \"OutputRate in Null monitor must be a float64\"\n\n#: cli/compile/compile.go:95\nmsgid \"Override a build property with a custom value. Can be used multiple times for multiple properties.\"\nmsgstr \"Override a build property with a custom value. Can be used multiple times for multiple properties.\"\n\n#: cli/config/init.go:54\nmsgid \"Overwrite existing config file.\"\nmsgstr \"Overwrite existing config file.\"\n\n#: cli/core/download.go:36\n#: cli/core/install.go:37\n#: cli/core/uninstall.go:36\n#: cli/core/upgrade.go:38\nmsgid \"PACKAGER\"\nmsgstr \"PACKAGER\"\n\n#: cli/board/details.go:145\nmsgid \"Package URL:\"\nmsgstr \"Package URL:\"\n\n#: cli/board/details.go:144\nmsgid \"Package maintainer:\"\nmsgstr \"Package maintainer:\"\n\n#: cli/board/details.go:143\nmsgid \"Package name:\"\nmsgstr \"Package name:\"\n\n#: cli/board/details.go:147\nmsgid \"Package online help:\"\nmsgstr \"Package online help:\"\n\n#: cli/board/details.go:146\nmsgid \"Package website:\"\nmsgstr \"Package website:\"\n\n#: cli/lib/search.go:165\nmsgid \"Paragraph: %s\"\nmsgstr \"Paragraph: %s\"\n\n#: cli/cli.go:102\nmsgid \"Path to the file where logs will be written.\"\nmsgstr \"Path to the file where logs will be written.\"\n\n#: cli/compile/compile.go:91\nmsgid \"Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS.\"\nmsgstr \"Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS.\"\n\n#: commands/upload/upload.go:391\nmsgid \"Performing 1200-bps touch reset on serial port %s\"\nmsgstr \"Performing 1200-bps touch reset on serial port %s\"\n\n#: commands/core/install.go:73\nmsgid \"Platform %s already installed\"\nmsgstr \"Platform %s already installed\"\n\n#: commands/core/install.go:177\nmsgid \"Platform %s installed\"\nmsgstr \"Platform %s installed\"\n\n#: commands/core/uninstall.go:85\nmsgid \"Platform %s uninstalled\"\nmsgstr \"Platform %s uninstalled\"\n\n#: commands/errors.go:303\nmsgid \"Platform '%s' is already at the latest version\"\nmsgstr \"Platform '%s' is already at the latest version\"\n\n#: commands/errors.go:247\nmsgid \"Platform '%s' not found\"\nmsgstr \"Platform '%s' not found\"\n\n#: cli/board/search.go:86\nmsgid \"Platform ID\"\nmsgstr \"Platform ID\"\n\n#: cli/board/details.go:153\nmsgid \"Platform URL:\"\nmsgstr \"Platform URL:\"\n\n#: cli/board/details.go:152\nmsgid \"Platform architecture:\"\nmsgstr \"Platform architecture:\"\n\n#: cli/board/details.go:151\nmsgid \"Platform category:\"\nmsgstr \"Platform category:\"\n\n#: cli/board/details.go:158\nmsgid \"Platform checksum:\"\nmsgstr \"Platform checksum:\"\n\n#: cli/board/details.go:154\nmsgid \"Platform file name:\"\nmsgstr \"Platform file name:\"\n\n#: cli/board/details.go:150\nmsgid \"Platform name:\"\nmsgstr \"Platform name:\"\n\n#: cli/board/details.go:156\nmsgid \"Platform size (bytes):\"\nmsgstr \"Platform size (bytes):\"\n\n#: legacy/builder/constants/constants.go:115\nmsgid \"Platform {0} (package {1}) is unknown\"\nmsgstr \"Platform {0} (package {1}) is unknown\"\n\n#: cli/board/list.go:87\n#: cli/board/list.go:125\nmsgid \"Port\"\nmsgstr \"Port\"\n\n#: legacy/builder/phases/libraries_builder.go:101\n#: legacy/builder/phases/libraries_builder.go:109\nmsgid \"Precompiled library in \\\"{0}\\\" not found\"\nmsgstr \"Precompiled library in \\\"{0}\\\" not found\"\n\n#: cli/board/details.go:42\nmsgid \"Print details about a board.\"\nmsgstr \"Print details about a board.\"\n\n#: cli/compile/compile.go:87\nmsgid \"Print preprocessed code to stdout instead of compiling.\"\nmsgstr \"Print preprocessed code to stdout instead of compiling.\"\n\n#: cli/cli.go:100\nmsgid \"Print the logs on the standard output.\"\nmsgstr \"Print the logs on the standard output.\"\n\n#: cli/config/dump.go:31\nmsgid \"Prints the current configuration\"\nmsgstr \"Prints the current configuration\"\n\n#: cli/config/dump.go:32\nmsgid \"Prints the current configuration.\"\nmsgstr \"Prints the current configuration.\"\n\n#: commands/errors.go:199\nmsgid \"Programmer '%s' not found\"\nmsgstr \"Programmer '%s' not found\"\n\n#: cli/board/details.go:93\nmsgid \"Programmer name\"\nmsgstr \"Programmer name\"\n\n#: cli/debug/debug.go:64\nmsgid \"Programmer to use for debugging\"\nmsgstr \"Programmer to use for debugging\"\n\n#: cli/board/details.go:194\nmsgid \"Programmers:\"\nmsgstr \"Programmers:\"\n\n#: legacy/builder/constants/constants.go:116\nmsgid \"Progress {0}\"\nmsgstr \"Progress {0}\"\n\n#: commands/errors.go:232\nmsgid \"Property '%s' is undefined\"\nmsgstr \"Property '%s' is undefined\"\n\n#: cli/board/list.go:125\nmsgid \"Protocol\"\nmsgstr \"Protocol\"\n\n#: cli/lib/search.go:175\nmsgid \"Provides includes: %s\"\nmsgstr \"Provides includes: %s\"\n\n#: cli/config/remove.go:31\n#: cli/config/remove.go:32\nmsgid \"Removes one or more values from a setting.\"\nmsgstr \"Removes one or more values from a setting.\"\n\n#: commands/instances.go:714\n#: commands/lib/install.go:105\nmsgid \"Replacing %[1]s with %[2]s\"\nmsgstr \"Replacing %[1]s with %[2]s\"\n\n#: cli/board/details.go:162\nmsgid \"Required tool:\"\nmsgstr \"Required tool:\"\n\n#: cli/daemon/daemon.go:50\nmsgid \"Run as a daemon on port %s\"\nmsgstr \"Run as a daemon on port %s\"\n\n#: cli/daemon/daemon.go:51\nmsgid \"Running as a daemon the initialization of cores and libraries is done only once.\"\nmsgstr \"Running as a daemon the initialization of cores and libraries is done only once.\"\n\n#: legacy/builder/phases/core_builder.go:49\nmsgid \"Running normal build of the core...\"\nmsgstr \"Running normal build of the core...\"\n\n#: legacy/builder/constants/constants.go:119\nmsgid \"Running recipe: {0}\"\nmsgstr \"Running recipe: {0}\"\n\n#: cli/compile/compile.go:89\nmsgid \"Save build artifacts in this directory.\"\nmsgstr \"Save build artifacts in this directory.\"\n\n#: cli/core/search.go:50\nmsgid \"Search for a core in Boards Manager using the specified keywords.\"\nmsgstr \"Search for a core in Boards Manager using the specified keywords.\"\n\n#: cli/core/search.go:49\nmsgid \"Search for a core in Boards Manager.\"\nmsgstr \"Search for a core in Boards Manager.\"\n\n#: cli/lib/search.go:41\nmsgid \"Search for one or more libraries data (case insensitive search).\"\nmsgstr \"Search for one or more libraries data (case insensitive search).\"\n\n#: cli/lib/search.go:40\nmsgid \"Searches for one or more libraries data.\"\nmsgstr \"Searches for one or more libraries data.\"\n\n#: legacy/builder/constants/constants.go:113\nmsgid \"Selected board depends on '{0}' core (not installed).\"\nmsgstr \"Selected board depends on '{0}' core (not installed).\"\n\n#: commands/board/attach.go:108\nmsgid \"Selected fqbn: %s\"\nmsgstr \"Selected fqbn: %s\"\n\n#: cli/lib/search.go:164\nmsgid \"Sentence: %s\"\nmsgstr \"Sentence: %s\"\n\n#: commands/download.go:62\nmsgid \"Server responded with: %s\"\nmsgstr \"Server responded with: %s\"\n\n#: cli/config/set.go:32\n#: cli/config/set.go:33\nmsgid \"Sets a setting value.\"\nmsgstr \"Sets a setting value.\"\n\n#: cli/config/init.go:52\n#: cli/config/init.go:53\nmsgid \"Sets where to save the configuration file.\"\nmsgstr \"Sets where to save the configuration file.\"\n\n#: legacy/builder/constants/constants.go:120\nmsgid \"Setting build path to {0}\"\nmsgstr \"Setting build path to {0}\"\n\n#: cli/config/delete.go:57\n#: cli/config/validate.go:43\nmsgid \"Settings key doesn't exist\"\nmsgstr \"Settings key doesn't exist\"\n\n#: cli/core/search.go:55\nmsgid \"Show all available core versions.\"\nmsgstr \"Show all available core versions.\"\n\n#: cli/compile/compile.go:86\nmsgid \"Show all build properties used instead of compiling.\"\nmsgstr \"Show all build properties used instead of compiling.\"\n\n#: cli/board/listall.go:45\n#: cli/board/search.go:46\nmsgid \"Show also boards marked as 'hidden' in the platform\"\nmsgstr \"Show also boards marked as 'hidden' in the platform\"\n\n#: cli/board/details.go:49\nmsgid \"Show full board details\"\nmsgstr \"Show full board details\"\n\n#: cli/board/details.go:43\nmsgid \"Show information about a board, in particular if the board has options to be specified in the FQBN.\"\nmsgstr \"Show information about a board, in particular if the board has options to be specified in the FQBN.\"\n\n#: cli/lib/examples.go:45\n#: cli/lib/list.go:49\nmsgid \"Show libraries for the specified board FQBN.\"\nmsgstr \"Show libraries for the specified board FQBN.\"\n\n#: cli/lib/search.go:46\nmsgid \"Show library names only.\"\nmsgstr \"Show library names only.\"\n\n#: cli/board/details.go:51\nmsgid \"Show list of available programmers\"\nmsgstr \"Show list of available programmers\"\n\n#: cli/debug/debug.go:67\nmsgid \"Show metadata about the debug session instead of starting the debugger.\"\nmsgstr \"Show metadata about the debug session instead of starting the debugger.\"\n\n#: cli/update/update.go:46\nmsgid \"Show outdated cores and libraries after index update\"\nmsgstr \"Show outdated cores and libraries after index update\"\n\n#: cli/lib/list.go:38\nmsgid \"Shows a list of installed libraries.\"\nmsgstr \"Shows a list of installed libraries.\"\n\n#: cli/lib/list.go:39\nmsgid \"Shows a list of installed libraries.\\n\"\n\"\\n\"\n\"If the LIBNAME parameter is specified the listing is limited to that specific\\n\"\n\"library. By default the libraries provided as built-in by platforms/core are\\n\"\n\"not listed, they can be listed by adding the --all flag.\"\nmsgstr \"Shows a list of installed libraries.\\n\"\n\"\\n\"\n\"If the LIBNAME parameter is specified the listing is limited to that specific\\n\"\n\"library. By default the libraries provided as built-in by platforms/core are\\n\"\n\"not listed, they can be listed by adding the --all flag.\"\n\n#: cli/core/list.go:35\n#: cli/core/list.go:36\nmsgid \"Shows the list of installed platforms.\"\nmsgstr \"Shows the list of installed platforms.\"\n\n#: cli/lib/examples.go:39\nmsgid \"Shows the list of the examples for libraries.\"\nmsgstr \"Shows the list of the examples for libraries.\"\n\n#: cli/lib/examples.go:40\nmsgid \"Shows the list of the examples for libraries. A name may be given as argument to search a specific library.\"\nmsgstr \"Shows the list of the examples for libraries. A name may be given as argument to search a specific library.\"\n\n#: cli/version/version.go:34\nmsgid \"Shows the version number of Arduino CLI which is installed on your system.\"\nmsgstr \"Shows the version number of Arduino CLI which is installed on your system.\"\n\n#: cli/version/version.go:33\nmsgid \"Shows version number of Arduino CLI.\"\nmsgstr \"Shows version number of Arduino CLI.\"\n\n#: cli/board/details.go:167\nmsgid \"Size (bytes):\"\nmsgstr \"Size (bytes):\"\n\n#: legacy/builder/constants/constants.go:128\nmsgid \"Sketch cannot be located in build path. Please specify a different build path\"\nmsgstr \"Sketch cannot be located in build path. Please specify a different build path\"\n\n#: cli/sketch/new.go:68\nmsgid \"Sketch created in: %s\"\nmsgstr \"Sketch created in: %s\"\n\n#: legacy/builder/constants/constants.go:124\nmsgid \"Sketch too big; see %s for tips on reducing it.\"\nmsgstr \"Sketch too big; see %s for tips on reducing it.\"\n\n#: legacy/builder/constants/constants.go:121\nmsgid \"Sketch uses {0} bytes ({2}%%) of program storage space. Maximum is {1} bytes.\"\nmsgstr \"Sketch uses {0} bytes ({2}%%) of program storage space. Maximum is {1} bytes.\"\n\n#: cli/compile/compile.go:137\n#: cli/sketch/archive.go:66\n#: cli/upload/upload.go:88\nmsgid \"Sketches with .pde extension are deprecated, please rename the following files to .ino:\"\nmsgstr \"Sketches with .pde extension are deprecated, please rename the following files to .ino:\"\n\n#: legacy/builder/phases/linker.go:35\nmsgid \"Skip linking of final executable.\"\nmsgstr \"Skip linking of final executable.\"\n\n#: commands/upload/upload.go:384\nmsgid \"Skipping 1200-bps touch reset: no serial port selected!\"\nmsgstr \"Skipping 1200-bps touch reset: no serial port selected!\"\n\n#: legacy/builder/builder_utils/utils.go:476\nmsgid \"Skipping archive creation of: {0}\"\nmsgstr \"Skipping archive creation of: {0}\"\n\n#: legacy/builder/builder_utils/utils.go:269\nmsgid \"Skipping compile of: {0}\"\nmsgstr \"Skipping compile of: {0}\"\n\n#: legacy/builder/constants/constants.go:103\nmsgid \"Skipping dependencies detection for precompiled library {0}\"\nmsgstr \"Skipping dependencies detection for precompiled library {0}\"\n\n#: commands/instances.go:851\nmsgid \"Skipping platform configuration\"\nmsgstr \"Skipping platform configuration\"\n\n#: commands/core/install.go:173\nmsgid \"Skipping platform configuration.\"\nmsgstr \"Skipping platform configuration.\"\n\n#: legacy/builder/recipe_runner.go:58\nmsgid \"Skipping: {0}\"\nmsgstr \"Skipping: {0}\"\n\n#: arduino/serialutils/serialutils.go:133\nmsgid \"TOUCH: error during reset: %s\"\nmsgstr \"TOUCH: error during reset: %s\"\n\n#: cli/daemon/daemon.go:56\nmsgid \"The TCP port the daemon will listen to\"\nmsgstr \"The TCP port the daemon will listen to\"\n\n#: cli/board/attach.go:45\nmsgid \"The connected devices search timeout, raise it if your board doesn't show up (e.g. to %s).\"\nmsgstr \"The connected devices search timeout, raise it if your board doesn't show up (e.g. to %s).\"\n\n#: cli/board/list.go:45\nmsgid \"The connected devices search timeout, raise it if your board doesn't show up e.g.: 10s\"\nmsgstr \"The connected devices search timeout, raise it if your board doesn't show up e.g.: 10s\"\n\n#: cli/cli.go:105\nmsgid \"The custom config file (if not specified the default will be used).\"\nmsgstr \"The custom config file (if not specified the default will be used).\"\n\n#: cli/core/install.go:66\nmsgid \"The flags --run-post-install and --skip-post-install can't be both set at the same time.\"\nmsgstr \"The flags --run-post-install and --skip-post-install can't be both set at the same time.\"\n\n#: cli/config/add.go:51\nmsgid \"The key '%[1]v' is not a list of items, can't add to it.\\n\"\n\"Maybe use '%[2]s'?\"\nmsgstr \"The key '%[1]v' is not a list of items, can't add to it.\\n\"\n\"Maybe use '%[2]s'?\"\n\n#: cli/config/remove.go:51\nmsgid \"The key '%[1]v' is not a list of items, can't remove from it.\\n\"\n\"Maybe use '%[2]s'?\"\nmsgstr \"The key '%[1]v' is not a list of items, can't remove from it.\\n\"\n\"Maybe use '%[2]s'?\"\n\n#: cli/cli.go:103\nmsgid \"The output format for the logs, can be {%s|%s}.\"\nmsgstr \"The output format for the logs, can be {%s|%s}.\"\n\n#: cli/cli.go:104\nmsgid \"The output format, can be {%s|%s}.\"\nmsgstr \"The output format, can be {%s|%s}.\"\n\n#: legacy/builder/phases/libraries_builder.go:151\nmsgid \"The platform does not support '{0}' for precompiled libraries.\"\nmsgstr \"The platform does not support '{0}' for precompiled libraries.\"\n\n#: cli/lib/upgrade.go:34\nmsgid \"This command upgrades an installed library to the latest available version. Multiple libraries can be passed separated by a space. If no arguments are provided, the command will upgrade all the installed libraries where an update is available.\"\nmsgstr \"This command upgrades an installed library to the latest available version. Multiple libraries can be passed separated by a space. If no arguments are provided, the command will upgrade all the installed libraries where an update is available.\"\n\n#: cli/outdated/outdated.go:39\nmsgid \"This commands shows a list of installed cores and/or libraries\\n\"\n\"that can be upgraded. If nothing needs to be updated the output is empty.\"\nmsgstr \"This commands shows a list of installed cores and/or libraries\\n\"\n\"that can be upgraded. If nothing needs to be updated the output is empty.\"\n\n#: commands/bundled_tools.go:45\n#: commands/core/install.go:80\n#: commands/instances.go:765\nmsgid \"Tool %s already installed\"\nmsgstr \"Tool %s already installed\"\n\n#: commands/core/uninstall.go:101\nmsgid \"Tool %s uninstalled\"\nmsgstr \"Tool %s uninstalled\"\n\n#: commands/debug/debug.go:133\nmsgid \"Toolchain '%s' is not supported\"\nmsgstr \"Toolchain '%s' is not supported\"\n\n#: cli/debug/debug.go:143\nmsgid \"Toolchain custom configurations\"\nmsgstr \"Toolchain custom configurations\"\n\n#: cli/debug/debug.go:137\nmsgid \"Toolchain path\"\nmsgstr \"Toolchain path\"\n\n#: cli/debug/debug.go:138\nmsgid \"Toolchain prefix\"\nmsgstr \"Toolchain prefix\"\n\n#: cli/debug/debug.go:136\nmsgid \"Toolchain type\"\nmsgstr \"Toolchain type\"\n\n#: legacy/builder/constants/constants.go:118\nmsgid \"Ts: {0} - Running: {1}\"\nmsgstr \"Ts: {0} - Running: {1}\"\n\n#: cli/burnbootloader/burnbootloader.go:56\nmsgid \"Turns on verbose mode.\"\nmsgstr \"Turns on verbose mode.\"\n\n#: cli/board/list.go:87\n#: cli/board/list.go:125\nmsgid \"Type\"\nmsgstr \"Type\"\n\n#: cli/lib/search.go:172\nmsgid \"Types: %s\"\nmsgstr \"Types: %s\"\n\n#: cli/board/details.go:169\nmsgid \"URL:\"\nmsgstr \"URL:\"\n\n#: legacy/builder/constants/constants.go:95\nmsgid \"Unable to cache built core, please tell {0} maintainers to follow %s\"\nmsgstr \"Unable to cache built core, please tell {0} maintainers to follow %s\"\n\n#: legacy/builder/constants/constants.go:101\nmsgid \"Unable to find {0} in {1}\"\nmsgstr \"Unable to find {0} in {1}\"\n\n#: configuration/configuration.go:125\nmsgid \"Unable to get Documents Folder: %v\"\nmsgstr \"Unable to get Documents Folder: %v\"\n\n#: configuration/configuration.go:100\nmsgid \"Unable to get Local App Data Folder: %v\"\nmsgstr \"Unable to get Local App Data Folder: %v\"\n\n#: configuration/configuration.go:88\n#: configuration/configuration.go:113\nmsgid \"Unable to get user home dir: %v\"\nmsgstr \"Unable to get user home dir: %v\"\n\n#: cli/cli.go:171\nmsgid \"Unable to open file for logging: %s\"\nmsgstr \"Unable to open file for logging: %s\"\n\n#: commands/core/uninstall.go:77\n#: commands/lib/uninstall.go:39\nmsgid \"Uninstalling %s\"\nmsgstr \"Uninstalling %s\"\n\n#: commands/core/uninstall.go:93\nmsgid \"Uninstalling %s, tool is no more required\"\nmsgstr \"Uninstalling %s, tool is no more required\"\n\n#: commands/instances.go:830\nmsgid \"Uninstalling %s: tool is no more required\"\nmsgstr \"Uninstalling %s: tool is no more required\"\n\n#: cli/core/uninstall.go:37\n#: cli/core/uninstall.go:38\nmsgid \"Uninstalls one or more cores and corresponding tool dependencies if no longer used.\"\nmsgstr \"Uninstalls one or more cores and corresponding tool dependencies if no longer used.\"\n\n#: cli/lib/uninstall.go:36\n#: cli/lib/uninstall.go:37\nmsgid \"Uninstalls one or more libraries.\"\nmsgstr \"Uninstalls one or more libraries.\"\n\n#: cli/board/list.go:157\nmsgid \"Unknown\"\nmsgstr \"Unknown\"\n\n#: commands/errors.go:141\nmsgid \"Unknown FQBN\"\nmsgstr \"Unknown FQBN\"\n\n#: legacy/builder/constants/constants.go:129\nmsgid \"Unknown sketch file extension: {0}\"\nmsgstr \"Unknown sketch file extension: {0}\"\n\n#: cli/update/update.go:40\nmsgid \"Updates the index of cores and libraries\"\nmsgstr \"Updates the index of cores and libraries\"\n\n#: cli/update/update.go:41\nmsgid \"Updates the index of cores and libraries to the latest versions.\"\nmsgstr \"Updates the index of cores and libraries to the latest versions.\"\n\n#: cli/core/update_index.go:36\nmsgid \"Updates the index of cores to the latest version.\"\nmsgstr \"Updates the index of cores to the latest version.\"\n\n#: cli/core/update_index.go:35\nmsgid \"Updates the index of cores.\"\nmsgstr \"Updates the index of cores.\"\n\n#: cli/lib/update_index.go:35\nmsgid \"Updates the libraries index to the latest version.\"\nmsgstr \"Updates the libraries index to the latest version.\"\n\n#: cli/lib/update_index.go:34\nmsgid \"Updates the libraries index.\"\nmsgstr \"Updates the libraries index.\"\n\n#: commands/instances.go:447\n#: commands/instances.go:473\n#: commands/instances.go:503\nmsgid \"Updating index: %s\"\nmsgstr \"Updating index: %s\"\n\n#: commands/instances.go:374\nmsgid \"Updating index: library_index.json.gz\"\nmsgstr \"Updating index: library_index.json.gz\"\n\n#: commands/instances.go:384\nmsgid \"Updating index: library_index.json.sig\"\nmsgstr \"Updating index: library_index.json.sig\"\n\n#: commands/instances.go:787\nmsgid \"Updating platform %s\"\nmsgstr \"Updating platform %s\"\n\n#: commands/core/upgrade.go:54\nmsgid \"Upgrade doesn't accept parameters with version\"\nmsgstr \"Upgrade doesn't accept parameters with version\"\n\n#: cli/upgrade/upgrade.go:40\nmsgid \"Upgrades installed cores and libraries to latest version.\"\nmsgstr \"Upgrades installed cores and libraries to latest version.\"\n\n#: cli/upgrade/upgrade.go:39\nmsgid \"Upgrades installed cores and libraries.\"\nmsgstr \"Upgrades installed cores and libraries.\"\n\n#: cli/lib/upgrade.go:33\nmsgid \"Upgrades installed libraries.\"\nmsgstr \"Upgrades installed libraries.\"\n\n#: cli/core/upgrade.go:39\n#: cli/core/upgrade.go:40\nmsgid \"Upgrades one or all installed platforms to the latest version.\"\nmsgstr \"Upgrades one or all installed platforms to the latest version.\"\n\n#: commands/core/install.go:114\nmsgid \"Upgrading platform %[1]s with %[2]s\"\nmsgstr \"Upgrading platform %[1]s with %[2]s\"\n\n#: cli/upload/upload.go:50\nmsgid \"Upload Arduino sketches.\"\nmsgstr \"Upload Arduino sketches.\"\n\n#: cli/upload/upload.go:51\nmsgid \"Upload Arduino sketches. This does NOT compile the sketch prior to upload.\"\nmsgstr \"Upload Arduino sketches. This does NOT compile the sketch prior to upload.\"\n\n#: cli/arguments/port.go:44\nmsgid \"Upload port address, e.g.: COM3 or /dev/ttyACM2\"\nmsgstr \"Upload port address, e.g.: COM3 or /dev/ttyACM2\"\n\n#: commands/upload/upload.go:409\nmsgid \"Upload port found on %s\"\nmsgstr \"Upload port found on %s\"\n\n#: cli/arguments/port.go:45\nmsgid \"Upload port protocol, e.g: serial\"\nmsgstr \"Upload port protocol, e.g: serial\"\n\n#: cli/compile/compile.go:100\nmsgid \"Upload the binary after the compilation.\"\nmsgstr \"Upload the binary after the compilation.\"\n\n#: cli/burnbootloader/burnbootloader.go:47\nmsgid \"Upload the bootloader on the board using an external programmer.\"\nmsgstr \"Upload the bootloader on the board using an external programmer.\"\n\n#: cli/burnbootloader/burnbootloader.go:46\nmsgid \"Upload the bootloader.\"\nmsgstr \"Upload the bootloader.\"\n\n#: cli/compile/compile.go:218\n#: cli/upload/upload.go:117\nmsgid \"Uploading to specified board using %s protocol requires the following info:\"\nmsgstr \"Uploading to specified board using %s protocol requires the following info:\"\n\n#: cli/usage.go:25\nmsgid \"Usage:\"\nmsgstr \"Usage:\"\n\n#: cli/usage.go:32\nmsgid \"Use %s for more information about a command.\"\nmsgstr \"Use %s for more information about a command.\"\n\n#: cli/burnbootloader/burnbootloader.go:57\nmsgid \"Use the specified programmer to upload.\"\nmsgstr \"Use the specified programmer to upload.\"\n\n#: arduino/libraries/librariesmanager/install.go:62\n#: arduino/libraries/librariesmanager/install.go:78\n#: arduino/libraries/librariesmanager/install.go:100\n#: arduino/libraries/librariesmanager/install.go:184\nmsgid \"User directory not set\"\nmsgstr \"User directory not set\"\n\n#: legacy/builder/constants/constants.go:132\nmsgid \"Using board '{0}' from platform in folder: {1}\"\nmsgstr \"Using board '{0}' from platform in folder: {1}\"\n\n#: legacy/builder/constants/constants.go:135\nmsgid \"Using cached library dependencies for file: {0}\"\nmsgstr \"Using cached library dependencies for file: {0}\"\n\n#: legacy/builder/constants/constants.go:133\nmsgid \"Using core '{0}' from platform in folder: {1}\"\nmsgstr \"Using core '{0}' from platform in folder: {1}\"\n\n#: legacy/builder/constants/constants.go:130\nmsgid \"Using library {0} at version {1} in folder: {2} {3}\"\nmsgstr \"Using library {0} at version {1} in folder: {2} {3}\"\n\n#: legacy/builder/constants/constants.go:131\nmsgid \"Using library {0} in folder: {1} {2}\"\nmsgstr \"Using library {0} in folder: {1} {2}\"\n\n#: legacy/builder/phases/core_builder.go:107\nmsgid \"Using precompiled core: {0}\"\nmsgstr \"Using precompiled core: {0}\"\n\n#: legacy/builder/phases/libraries_builder.go:98\n#: legacy/builder/phases/libraries_builder.go:106\nmsgid \"Using precompiled library in {0}\"\nmsgstr \"Using precompiled library in {0}\"\n\n#: legacy/builder/constants/constants.go:134\nmsgid \"Using previously compiled file: {0}\"\nmsgstr \"Using previously compiled file: {0}\"\n\n#: cli/core/download.go:36\n#: cli/core/install.go:37\nmsgid \"VERSION\"\nmsgstr \"VERSION\"\n\n#: cli/lib/check_deps.go:34\n#: cli/lib/install.go:38\nmsgid \"VERSION_NUMBER\"\nmsgstr \"VERSION_NUMBER\"\n\n#: cli/burnbootloader/burnbootloader.go:55\n#: cli/compile/compile.go:102\n#: cli/upload/upload.go:62\nmsgid \"Verify uploaded binary after the upload.\"\nmsgstr \"Verify uploaded binary after the upload.\"\n\n#: cli/core/search.go:114\nmsgid \"Version\"\nmsgstr \"Version\"\n\n#: cli/lib/search.go:173\nmsgid \"Versions: %s\"\nmsgstr \"Versions: %s\"\n\n#: commands/core/install.go:169\nmsgid \"WARNING cannot configure platform: %s\"\nmsgstr \"WARNING cannot configure platform: %s\"\n\n#: legacy/builder/constants/constants.go:136\nmsgid \"WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'\"\nmsgstr \"WARNING: Category '{0}' in library {1} is not valid. Setting to '{2}'\"\n\n#: legacy/builder/constants/constants.go:138\nmsgid \"WARNING: Spurious {0} folder in '{1}' library\"\nmsgstr \"WARNING: Spurious {0} folder in '{1}' library\"\n\n#: commands/instances.go:847\nmsgid \"WARNING: cannot run post install: %s\"\nmsgstr \"WARNING: cannot run post install: %s\"\n\n#: legacy/builder/constants/constants.go:110\nmsgid \"WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s).\"\nmsgstr \"WARNING: library {0} claims to run on {1} architecture(s) and may be incompatible with your current board which runs on {2} architecture(s).\"\n\n#: commands/upload/upload.go:398\nmsgid \"Waiting for upload port...\"\nmsgstr \"Waiting for upload port...\"\n\n#: legacy/builder/constants/constants.go:112\nmsgid \"Warning: Board {0}:{1}:{2} doesn''t define a %s preference. Auto-set to: {3}\"\nmsgstr \"Warning: Board {0}:{1}:{2} doesn''t define a %s preference. Auto-set to: {3}\"\n\n#: legacy/builder/constants/constants.go:137\nmsgid \"Warning: platform.txt from core '{0}' contains deprecated {1}, automatically converted to {2}. Consider upgrading this core.\"\nmsgstr \"Warning: platform.txt from core '{0}' contains deprecated {1}, automatically converted to {2}. Consider upgrading this core.\"\n\n#: commands/upload/upload.go:293\nmsgid \"Warning: tool '%s' is not installed. It might not be available for your OS.\"\nmsgstr \"Warning: tool '%s' is not installed. It might not be available for your OS.\"\n\n#: cli/lib/search.go:166\nmsgid \"Website: %s\"\nmsgstr \"Website: %s\"\n\n#: cli/compile/compile.go:103\nmsgid \"When specified, VID/PID specific build properties are used, if board supports them.\"\nmsgstr \"When specified, VID/PID specific build properties are used, if board supports them.\"\n\n#: cli/config/init.go:42\nmsgid \"Writes current configuration to a configuration file.\"\nmsgstr \"Writes current configuration to a configuration file.\"\n\n#: cli/config/init.go:45\nmsgid \"Writes current configuration to the configuration file in the data directory.\"\nmsgstr \"Writes current configuration to the configuration file in the data directory.\"\n\n#: cli/config/set.go:76\nmsgid \"Writing config file: %v\"\nmsgstr \"Writing config file: %v\"\n\n#: cli/core/list.go:88\n#: cli/core/search.go:118\nmsgid \"[DEPRECATED] %s\"\nmsgstr \"[DEPRECATED] %s\"\n\n#: arduino/resources/checksums.go:80\nmsgid \"archive hash differs from hash in index\"\nmsgstr \"archive hash differs from hash in index\"\n\n#: arduino/libraries/librariesmanager/install.go:131\nmsgid \"archive is not valid: multiple files found in zip file top level\"\nmsgstr \"archive is not valid: multiple files found in zip file top level\"\n\n#: cli/sketch/archive.go:38\nmsgid \"archivePath\"\nmsgstr \"archivePath\"\n\n#: legacy/builder/preprocess_sketch.go:103\nmsgid \"arduino-preprocessor pattern is missing\"\nmsgstr \"arduino-preprocessor pattern is missing\"\n\n#: commands/upload/upload.go:558\nmsgid \"autodetect build artifact: %s\"\nmsgstr \"autodetect build artifact: %s\"\n\n#: commands/upload/upload.go:543\nmsgid \"binary file not found in %s\"\nmsgstr \"binary file not found in %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:189\nmsgid \"board %s:%s not found\"\nmsgstr \"board %s:%s not found\"\n\n#: commands/board/list.go:40\nmsgid \"board not found\"\nmsgstr \"board not found\"\n\n#: cli/board/listall.go:35\n#: cli/board/search.go:36\nmsgid \"boardname\"\nmsgstr \"boardname\"\n\n#: arduino/discovery/discovery.go:297\n#: arduino/discovery/discovery.go:318\n#: arduino/discovery/discovery.go:338\n#: arduino/discovery/discovery.go:361\n#: arduino/discovery/discovery.go:384\n#: arduino/discovery/discovery.go:407\nmsgid \"calling %[1]s: %[2]w\"\nmsgstr \"calling %[1]s: %[2]w\"\n\n#: arduino/cores/status.go:123\nmsgid \"can't find latest release of %s\"\nmsgstr \"can't find latest release of %s\"\n\n#: arduino/sketch/sketch.go:101\nmsgid \"can't find main Sketch file in %s\"\nmsgstr \"can't find main Sketch file in %s\"\n\n#: arduino/cores/packagemanager/loader.go:749\nmsgid \"can't find pattern for discovery with id %s\"\nmsgstr \"can't find pattern for discovery with id %s\"\n\n#: executils/output.go:52\nmsgid \"can't retrieve standard error stream: %s\"\nmsgstr \"can't retrieve standard error stream: %s\"\n\n#: executils/output.go:34\nmsgid \"can't retrieve standard output stream: %s\"\nmsgstr \"can't retrieve standard output stream: %s\"\n\n#: commands/upload/upload.go:500\n#: commands/upload/upload.go:507\nmsgid \"cannot execute upload tool: %s\"\nmsgstr \"cannot execute upload tool: %s\"\n\n#: arduino/resources/install.go:39\nmsgid \"checking local archive integrity\"\nmsgstr \"checking local archive integrity\"\n\n#: legacy/builder/wipeout_build_path_if_build_options_changed.go:85\n#: legacy/builder/wipeout_build_path_if_build_options_changed.go:89\nmsgid \"cleaning build path\"\nmsgstr \"cleaning build path\"\n\n#: cli/cli.go:69\nmsgid \"command\"\nmsgstr \"command\"\n\n#: arduino/discovery/discovery.go:301\n#: arduino/discovery/discovery.go:322\n#: arduino/discovery/discovery.go:342\n#: arduino/discovery/discovery.go:365\n#: arduino/discovery/discovery.go:388\n#: arduino/discovery/discovery.go:411\nmsgid \"command failed: %s\"\nmsgstr \"command failed: %s\"\n\n#: arduino/discovery/discovery.go:299\nmsgid \"communication out of sync, expected 'hello', received '%s'\"\nmsgstr \"communication out of sync, expected 'hello', received '%s'\"\n\n#: arduino/discovery/discovery.go:386\nmsgid \"communication out of sync, expected 'list', received '%s'\"\nmsgstr \"communication out of sync, expected 'list', received '%s'\"\n\n#: arduino/discovery/discovery.go:363\nmsgid \"communication out of sync, expected 'quit', received '%s'\"\nmsgstr \"communication out of sync, expected 'quit', received '%s'\"\n\n#: arduino/discovery/discovery.go:320\nmsgid \"communication out of sync, expected 'start', received '%s'\"\nmsgstr \"communication out of sync, expected 'start', received '%s'\"\n\n#: arduino/discovery/discovery.go:409\nmsgid \"communication out of sync, expected 'start_sync', received '%s'\"\nmsgstr \"communication out of sync, expected 'start_sync', received '%s'\"\n\n#: arduino/discovery/discovery.go:340\nmsgid \"communication out of sync, expected 'stop', received '%s'\"\nmsgstr \"communication out of sync, expected 'stop', received '%s'\"\n\n#: arduino/resources/checksums.go:76\nmsgid \"computing hash: %s\"\nmsgstr \"computing hash: %s\"\n\n#: commands/upload/upload.go:615\nmsgid \"could not find a valid build artifact\"\nmsgstr \"could not find a valid build artifact\"\n\n#: arduino/cores/packagemanager/loader.go:721\nmsgid \"creating discovery: %s\"\nmsgstr \"creating discovery: %s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:45\nmsgid \"creating installed.json in %[1]s: %[2]s\"\nmsgstr \"creating installed.json in %[1]s: %[2]s\"\n\n#: arduino/resources/install.go:44\n#: arduino/resources/install.go:48\nmsgid \"creating temp dir for extraction: %s\"\nmsgstr \"creating temp dir for extraction: %s\"\n\n#: legacy/builder/phases/sizer.go:116\nmsgid \"data section exceeds available space in board\"\nmsgstr \"data section exceeds available space in board\"\n\n#: arduino/sketch/sketch.go:207\nmsgid \"decoding sketch metadata: %s\"\nmsgstr \"decoding sketch metadata: %s\"\n\n#: commands/lib/resolve_deps.go:54\nmsgid \"dependency '%s' is not available\"\nmsgstr \"dependency '%s' is not available\"\n\n#: legacy/builder/utils/utils.go:471\nmsgid \"destination already exists\"\nmsgstr \"destination already exists\"\n\n#: arduino/libraries/librariesmanager/install.go:69\nmsgid \"destination dir %s already exists, cannot install\"\nmsgstr \"destination dir %s already exists, cannot install\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:112\nmsgid \"discovery %[1]s process not started: %[2]w\"\nmsgstr \"discovery %[1]s process not started: %[2]w\"\n\n#: arduino/cores/packagemanager/loader.go:710\nmsgid \"discovery not found: %s\"\nmsgstr \"discovery not found: %s\"\n\n#: arduino/cores/packagemanager/loader.go:715\nmsgid \"discovery not installed: %s\"\nmsgstr \"discovery not installed: %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:478\nmsgid \"discovery release not found: %s\"\nmsgstr \"discovery release not found: %s\"\n\n#: cli/core/download.go:36\nmsgid \"download [%s:%s[@%s]]...\"\nmsgstr \"download [%s:%s[@%s]]...\"\n\n#: cli/core/install.go:42\nmsgid \"download a specific version (in this case 1.6.9).\"\nmsgstr \"download a specific version (in this case 1.6.9).\"\n\n#: cli/core/install.go:40\nmsgid \"download the latest version of Arduino SAMD core.\"\nmsgstr \"download the latest version of Arduino SAMD core.\"\n\n#: commands/instances.go:94\nmsgid \"downloading %[1]s tool: %[2]s\"\nmsgstr \"downloading %[1]s tool: %[2]s\"\n\n#: arduino/cores/fqbn.go:48\nmsgid \"empty board identifier\"\nmsgstr \"empty board identifier\"\n\n#: arduino/sketch/sketch.go:196\nmsgid \"encoding sketch metadata: %s\"\nmsgstr \"encoding sketch metadata: %s\"\n\n#: arduino/monitors/serial.go:44\nmsgid \"error opening serial monitor\"\nmsgstr \"error opening serial monitor\"\n\n#: cli/config/set.go:68\nmsgid \"error parsing value: %v\"\nmsgstr \"error parsing value: %v\"\n\n#: commands/board/list.go:81\nmsgid \"error processing response from server\"\nmsgstr \"error processing response from server\"\n\n#: commands/board/list.go:96\nmsgid \"error querying Arduino Cloud Api\"\nmsgstr \"error querying Arduino Cloud Api\"\n\n#: cli/upload/upload.go:72\nmsgid \"error: %s and %s flags cannot be used together\"\nmsgstr \"error: %s and %s flags cannot be used together\"\n\n#: arduino/resources/install.go:67\nmsgid \"extracting archive: %s\"\nmsgstr \"extracting archive: %s\"\n\n#: arduino/libraries/librariesmanager/install.go:119\nmsgid \"extracting archive: %w\"\nmsgstr \"extracting archive: %w\"\n\n#: arduino/resources/checksums.go:145\nmsgid \"failed to compute hash of file \\\"%s\\\"\"\nmsgstr \"failed to compute hash of file \\\"%s\\\"\"\n\n#: commands/board/list.go:64\nmsgid \"failed to initialize http client\"\nmsgstr \"failed to initialize http client\"\n\n#: arduino/resources/checksums.go:97\nmsgid \"fetched archive size differs from size specified in index\"\nmsgstr \"fetched archive size differs from size specified in index\"\n\n#: arduino/resources/install.go:132\nmsgid \"files in archive must be placed in a subdirectory\"\nmsgstr \"files in archive must be placed in a subdirectory\"\n\n#: arduino/cores/packagemanager/loader.go:66\nmsgid \"find abs path: %s\"\nmsgstr \"find abs path: %s\"\n\n#: commands/daemon/monitor.go:45\nmsgid \"first message must contain monitor configuration, not data\"\nmsgstr \"first message must contain monitor configuration, not data\"\n\n#: cli/cli.go:69\nmsgid \"flags\"\nmsgstr \"flags\"\n\n#: arduino/cores/packagemanager/loader.go:108\nmsgid \"following possible symlink %[1]s: %[2]s\"\nmsgstr \"following possible symlink %[1]s: %[2]s\"\n\n#: cli/core/download.go:41\nmsgid \"for a specific version (in this case 1.6.9).\"\nmsgstr \"for a specific version (in this case 1.6.9).\"\n\n#: cli/lib/download.go:39\nmsgid \"for a specific version.\"\nmsgstr \"for a specific version.\"\n\n#: cli/lib/check_deps.go:38\n#: cli/lib/download.go:38\n#: cli/lib/install.go:42\nmsgid \"for the latest version.\"\nmsgstr \"for the latest version.\"\n\n#: cli/lib/check_deps.go:39\n#: cli/lib/install.go:43\nmsgid \"for the specific version.\"\nmsgstr \"for the specific version.\"\n\n#: inventory/inventory.go:67\nmsgid \"generating installation.id: %w\"\nmsgstr \"generating installation.id: %w\"\n\n#: inventory/inventory.go:73\nmsgid \"generating installation.secret: %w\"\nmsgstr \"generating installation.secret: %w\"\n\n#: arduino/resources/helpers.go:68\nmsgid \"getting archive file info: %s\"\nmsgstr \"getting archive file info: %s\"\n\n#: arduino/resources/checksums.go:94\nmsgid \"getting archive info: %s\"\nmsgstr \"getting archive info: %s\"\n\n#: arduino/resources/checksums.go:67\n#: arduino/resources/checksums.go:90\n#: arduino/resources/helpers.go:40\n#: arduino/resources/helpers.go:49\n#: arduino/resources/install.go:55\nmsgid \"getting archive path: %s\"\nmsgstr \"getting archive path: %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:195\nmsgid \"getting build properties for board %[1]s: %[2]s\"\nmsgstr \"getting build properties for board %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/download.go:103\nmsgid \"getting discovery dependencies for platform %[1]s: %[2]s\"\nmsgstr \"getting discovery dependencies for platform %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:649\nmsgid \"getting parent dir of %[1]s: %[2]s\"\nmsgstr \"getting parent dir of %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/download.go:96\nmsgid \"getting tool dependencies for platform %[1]s: %[2]s\"\nmsgstr \"getting tool dependencies for platform %[1]s: %[2]s\"\n\n#: arduino/sketch/sketch.go:151\nmsgid \"importing sketch metadata: %s\"\nmsgstr \"importing sketch metadata: %s\"\n\n#: arduino/libraries/librariesmanager/install.go:86\nmsgid \"install directory not set\"\nmsgstr \"install directory not set\"\n\n#: commands/instances.go:98\nmsgid \"installing %[1]s tool: %[2]s\"\nmsgstr \"installing %[1]s tool: %[2]s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:37\nmsgid \"installing platform %[1]s: %[2]s\"\nmsgstr \"installing platform %[1]s: %[2]s\"\n\n#: arduino/discovery/discovery.go:184\nmsgid \"invalid 'add' message: missing port\"\nmsgstr \"invalid 'add' message: missing port\"\n\n#: arduino/discovery/discovery.go:195\nmsgid \"invalid 'remove' message: missing port\"\nmsgstr \"invalid 'remove' message: missing port\"\n\n#: arduino/resources/checksums.go:45\nmsgid \"invalid checksum format: %s\"\nmsgstr \"invalid checksum format: %s\"\n\n#: arduino/cores/fqbn.go:54\n#: arduino/cores/fqbn.go:59\nmsgid \"invalid config option: %s\"\nmsgstr \"invalid config option: %s\"\n\n#: cli/arguments/reference.go:82\nmsgid \"invalid empty core architecture '%s'\"\nmsgstr \"invalid empty core architecture '%s'\"\n\n#: cli/arguments/reference.go:58\nmsgid \"invalid empty core argument\"\nmsgstr \"invalid empty core argument\"\n\n#: cli/arguments/reference.go:78\nmsgid \"invalid empty core name '%s'\"\nmsgstr \"invalid empty core name '%s'\"\n\n#: cli/arguments/reference.go:62\nmsgid \"invalid empty core reference '%s'\"\nmsgstr \"invalid empty core reference '%s'\"\n\n#: cli/arguments/reference.go:67\nmsgid \"invalid empty core version: '%s'\"\nmsgstr \"invalid empty core version: '%s'\"\n\n#: cli/lib/args.go:49\nmsgid \"invalid empty library name\"\nmsgstr \"invalid empty library name\"\n\n#: cli/lib/args.go:54\nmsgid \"invalid empty library version: %s\"\nmsgstr \"invalid empty library version: %s\"\n\n#: arduino/cores/board.go:123\nmsgid \"invalid empty option found\"\nmsgstr \"invalid empty option found\"\n\n#: arduino/libraries/librariesmanager/install.go:250\nmsgid \"invalid git url\"\nmsgstr \"invalid git url\"\n\n#: arduino/resources/checksums.go:49\nmsgid \"invalid hash '%[1]s': %[2]s\"\nmsgstr \"invalid hash '%[1]s': %[2]s\"\n\n#: cli/arguments/reference.go:75\nmsgid \"invalid item %s\"\nmsgstr \"invalid item %s\"\n\n#: arduino/libraries/libraries_layout.go:53\nmsgid \"invalid library layout value: %d\"\nmsgstr \"invalid library layout value: %d\"\n\n#: arduino/libraries/libraries_layout.go:68\nmsgid \"invalid library layout: %s\"\nmsgstr \"invalid library layout: %s\"\n\n#: arduino/libraries/libraries_location.go:73\nmsgid \"invalid library location value: %d\"\nmsgstr \"invalid library location value: %d\"\n\n#: arduino/libraries/libraries_location.go:94\nmsgid \"invalid library location: %s\"\nmsgstr \"invalid library location: %s\"\n\n#: arduino/cores/board.go:125\nmsgid \"invalid option '%s'\"\nmsgstr \"invalid option '%s'\"\n\n#: inventory/inventory.go:85\nmsgid \"invalid path creating config dir: %[1]s error: %[2]w\"\nmsgstr \"invalid path creating config dir: %[1]s error: %[2]w\"\n\n#: inventory/inventory.go:91\nmsgid \"invalid path writing inventory file: %[1]s error: %[2]w\"\nmsgstr \"invalid path writing inventory file: %[1]s error: %[2]w\"\n\n#: arduino/cores/packageindex/index.go:239\nmsgid \"invalid platform archive size: %s\"\nmsgstr \"invalid platform archive size: %s\"\n\n#: commands/upload/upload.go:487\nmsgid \"invalid recipe '%[1]s': %[2]s\"\nmsgstr \"invalid recipe '%[1]s': %[2]s\"\n\n#: arduino/cores/board.go:109\nmsgid \"invalid value '%[1]s' for option '%[2]s'\"\nmsgstr \"invalid value '%[1]s' for option '%[2]s'\"\n\n#: arduino/cores/packagemanager/loader.go:280\nmsgid \"invalid version dir %[1]s: %[2]s\"\nmsgstr \"invalid version dir %[1]s: %[2]s\"\n\n#: commands/daemon/settings.go:108\nmsgid \"key not found in settings\"\nmsgstr \"key not found in settings\"\n\n#: cli/core/search.go:48\nmsgid \"keywords\"\nmsgstr \"keywords\"\n\n#: arduino/libraries/librariesmanager/install.go:157\n#: arduino/libraries/librariesmanager/install.go:200\nmsgid \"library %s already installed\"\nmsgstr \"library %s already installed\"\n\n#: arduino/libraries/librariesmanager/install.go:38\nmsgid \"library already installed\"\nmsgstr \"library already installed\"\n\n#: arduino/libraries/librariesmanager/install.go:269\nmsgid \"library is not valid: missing file \\\"library.properties\\\"\"\nmsgstr \"library is not valid: missing file \\\"library.properties\\\"\"\n\n#: arduino/libraries/librariesmanager/install.go:264\nmsgid \"library is not valid: missing header file \\\"%s\\\"\"\nmsgstr \"library is not valid: missing header file \\\"%s\\\"\"\n\n#: arduino/libraries/librariesmanager/librariesmanager.go:226\nmsgid \"library path does not exist: %s\"\nmsgstr \"library path does not exist: %s\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:222\nmsgid \"listing ports from discovery %[1]s: %[2]w\"\nmsgstr \"listing ports from discovery %[1]s: %[2]w\"\n\n#: arduino/serialutils/serialutils.go:61\nmsgid \"listing serial ports\"\nmsgstr \"listing serial ports\"\n\n#: arduino/cores/packagemanager/loader.go:307\n#: arduino/cores/packagemanager/loader.go:316\n#: arduino/cores/packagemanager/loader.go:321\nmsgid \"loading %[1]s: %[2]s\"\nmsgstr \"loading %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:356\nmsgid \"loading boards: %s\"\nmsgstr \"loading boards: %s\"\n\n#: arduino/cores/packagemanager/loader.go:604\nmsgid \"loading bundled tools from %[1]s: %[2]s\"\nmsgstr \"loading bundled tools from %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/package_manager.go:230\n#: arduino/cores/packagemanager/package_manager.go:245\nmsgid \"loading json index file %[1]s: %[2]s\"\nmsgstr \"loading json index file %[1]s: %[2]s\"\n\n#: arduino/libraries/librariesmanager/librariesmanager.go:205\n#: arduino/libraries/librariesmanager/librariesmanager.go:231\nmsgid \"loading library from %[1]s: %[2]s\"\nmsgstr \"loading library from %[1]s: %[2]s\"\n\n#: arduino/libraries/loader.go:47\nmsgid \"loading library.properties: %s\"\nmsgstr \"loading library.properties: %s\"\n\n#: arduino/cores/packagemanager/loader.go:256\n#: arduino/cores/packagemanager/loader.go:284\nmsgid \"loading platform release %[1]s: %[2]s\"\nmsgstr \"loading platform release %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:207\nmsgid \"loading platform.txt: %v\"\nmsgstr \"loading platform.txt: %v\"\n\n#: arduino/cores/packagemanager/loader.go:571\nmsgid \"loading tool release in %[1]s: %[2]s\"\nmsgstr \"loading tool release in %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:200\nmsgid \"looking for boards.txt in %[1]s: %[2]s\"\nmsgstr \"looking for boards.txt in %[1]s: %[2]s\"\n\n#: legacy/builder/container_setup.go:74\nmsgid \"main file missing from sketch\"\nmsgstr \"main file missing from sketch\"\n\n#: arduino/resources/checksums.go:41\nmsgid \"missing checksum for: %s\"\nmsgstr \"missing checksum for: %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:207\nmsgid \"missing package %[1]s referenced by board %[2]s\"\nmsgstr \"missing package %[1]s referenced by board %[2]s\"\n\n#: arduino/cores/packagemanager/package_manager.go:212\nmsgid \"missing platform %[1]s:%[2]s referenced by board %[3]s\"\nmsgstr \"missing platform %[1]s:%[2]s referenced by board %[3]s\"\n\n#: arduino/cores/packagemanager/package_manager.go:217\nmsgid \"missing platform release %[1]s:%[2]s referenced by board %[3]s\"\nmsgstr \"missing platform release %[1]s:%[2]s referenced by board %[3]s\"\n\n#: arduino/libraries/librariesmanager/install.go:174\n#: arduino/resources/install.go:94\nmsgid \"moving extracted archive to destination dir: %s\"\nmsgstr \"moving extracted archive to destination dir: %s\"\n\n#: commands/upload/upload.go:610\nmsgid \"multiple build artifacts found: '%[1]s' and '%[2]s'\"\nmsgstr \"multiple build artifacts found: '%[1]s' and '%[2]s'\"\n\n#: arduino/sketch/sketch.go:73\nmsgid \"multiple main sketch files found (%[1]v, %[2]v)\"\nmsgstr \"multiple main sketch files found (%[1]v, %[2]v)\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:127\nmsgid \"no compatible version of %s tools found for the current os\"\nmsgstr \"no compatible version of %s tools found for the current os\"\n\n#: executils/process.go:37\nmsgid \"no executable specified\"\nmsgstr \"no executable specified\"\n\n#: commands/daemon/daemon.go:94\nmsgid \"no instance specified\"\nmsgstr \"no instance specified\"\n\n#: commands/upload/upload.go:565\nmsgid \"no sketch or build directory/file specified\"\nmsgstr \"no sketch or build directory/file specified\"\n\n#: arduino/resources/install.go:128\nmsgid \"no unique root dir in archive, found '%[1]s' and '%[2]s'\"\nmsgstr \"no unique root dir in archive, found '%[1]s' and '%[2]s'\"\n\n#: commands/upload/upload.go:482\nmsgid \"no upload port provided\"\nmsgstr \"no upload port provided\"\n\n#: arduino/sketch/sketch.go:259\nmsgid \"no valid sketch found in %[1]s: missing %[2]s\"\nmsgstr \"no valid sketch found in %[1]s: missing %[2]s\"\n\n#: commands/core/download.go:84\nmsgid \"no versions available for the current OS\"\nmsgstr \"no versions available for the current OS\"\n\n#: arduino/resources/checksums.go:72\n#: arduino/resources/install.go:59\nmsgid \"opening archive file: %s\"\nmsgstr \"opening archive file: %s\"\n\n#: arduino/cores/packagemanager/loader.go:273\nmsgid \"opening boards.txt: %s\"\nmsgstr \"opening boards.txt: %s\"\n\n#: arduino/serialutils/serialutils.go:37\nmsgid \"opening port at 1200bps\"\nmsgstr \"opening port at 1200bps\"\n\n#: arduino/security/signatures.go:81\nmsgid \"opening signature file: %s\"\nmsgstr \"opening signature file: %s\"\n\n#: arduino/security/signatures.go:76\nmsgid \"opening target file: %s\"\nmsgstr \"opening target file: %s\"\n\n#: arduino/cores/packagemanager/download.go:73\n#: arduino/cores/status.go:88\n#: arduino/cores/status.go:113\nmsgid \"package %s not found\"\nmsgstr \"package %s not found\"\n\n#: arduino/cores/packagemanager/package_manager.go:259\nmsgid \"package '%s' not found\"\nmsgstr \"package '%s' not found\"\n\n#: arduino/cores/status.go:167\nmsgid \"package not found\"\nmsgstr \"package not found\"\n\n#: arduino/cores/packagemanager/loader.go:227\nmsgid \"parsing IDE bundled index: %s\"\nmsgstr \"parsing IDE bundled index: %s\"\n\n#: arduino/cores/board.go:139\n#: arduino/cores/packagemanager/package_manager.go:136\nmsgid \"parsing fqbn: %s\"\nmsgstr \"parsing fqbn: %s\"\n\n#: arduino/libraries/librariesindex/json.go:69\nmsgid \"parsing library_index.json: %s\"\nmsgstr \"parsing library_index.json: %s\"\n\n#: arduino/cores/packagemanager/loader.go:189\nmsgid \"path is not a platform directory: %s\"\nmsgstr \"path is not a platform directory: %s\"\n\n#: arduino/cores/packagemanager/download.go:77\nmsgid \"platform %[1]s not found in package %[2]s\"\nmsgstr \"platform %[1]s not found in package %[2]s\"\n\n#: arduino/cores/packagemanager/download.go:89\nmsgid \"platform %s has no available releases\"\nmsgstr \"platform %s has no available releases\"\n\n#: arduino/cores/packagemanager/package_manager.go:182\nmsgid \"platform %s is not installed\"\nmsgstr \"platform %s is not installed\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:65\n#: arduino/cores/packagemanager/install_uninstall.go:108\n#: arduino/cores/packagemanager/loader.go:433\n#: commands/compile/compile.go:127\nmsgid \"platform not installed\"\nmsgstr \"platform not installed\"\n\n#: cli/compile/compile.go:121\nmsgid \"please use --build-property instead.\"\nmsgstr \"please use --build-property instead.\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:67\nmsgid \"pluggable discovery already added: %s\"\nmsgstr \"pluggable discovery already added: %s\"\n\n#: cli/board/attach.go:35\nmsgid \"port\"\nmsgstr \"port\"\n\n#: cli/arguments/port.go:122\nmsgid \"port not found: %[1]s %[2]s\"\nmsgstr \"port not found: %[1]s %[2]s\"\n\n#: arduino/discovery/discovery.go:303\nmsgid \"protocol version not supported: requested 1, got %d\"\nmsgstr \"protocol version not supported: requested 1, got %d\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:188\nmsgid \"quitting discovery %[1]s: %[2]w\"\nmsgstr \"quitting discovery %[1]s: %[2]w\"\n\n#: arduino/cores/packagemanager/loader.go:78\nmsgid \"reading %[1]s directory: %[2]s\"\nmsgstr \"reading %[1]s directory: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:654\nmsgid \"reading %[1]s: %[2]s\"\nmsgstr \"reading %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:267\n#: arduino/libraries/librariesmanager/librariesmanager.go:196\nmsgid \"reading dir %[1]s: %[2]s\"\nmsgstr \"reading dir %[1]s: %[2]s\"\n\n#: arduino/cores/packagemanager/loader.go:162\n#: arduino/cores/packagemanager/loader.go:562\nmsgid \"reading directory %[1]s: %[2]s\"\nmsgstr \"reading directory %[1]s: %[2]s\"\n\n#: arduino/builder/sketch.go:76\nmsgid \"reading file %[1]s: %[2]s\"\nmsgstr \"reading file %[1]s: %[2]s\"\n\n#: arduino/sketch/sketch.go:229\nmsgid \"reading files: %v\"\nmsgstr \"reading files: %v\"\n\n#: inventory/inventory.go:57\nmsgid \"reading inventory file: %w\"\nmsgstr \"reading inventory file: %w\"\n\n#: arduino/libraries/librariesresolver/cpp.go:60\nmsgid \"reading lib headers: %s\"\nmsgstr \"reading lib headers: %s\"\n\n#: arduino/libraries/libraries.go:234\nmsgid \"reading lib src dir: %s\"\nmsgstr \"reading lib src dir: %s\"\n\n#: arduino/libraries/libraries.go:114\nmsgid \"reading library headers: %w\"\nmsgstr \"reading library headers: %w\"\n\n#: arduino/libraries/librariesindex/json.go:63\nmsgid \"reading library_index.json: %s\"\nmsgstr \"reading library_index.json: %s\"\n\n#: arduino/resources/install.go:118\nmsgid \"reading package root dir: %s\"\nmsgstr \"reading package root dir: %s\"\n\n#: arduino/sketch/sketch.go:188\nmsgid \"reading sketch metadata %[1]s: %[2]s\"\nmsgstr \"reading sketch metadata %[1]s: %[2]s\"\n\n#: commands/upload/upload.go:476\nmsgid \"recipe not found '%s'\"\nmsgstr \"recipe not found '%s'\"\n\n#: arduino/cores/packagemanager/package_manager.go:335\nmsgid \"release %[1]s not found for tool %[2]s\"\nmsgstr \"release %[1]s not found for tool %[2]s\"\n\n#: arduino/cores/status.go:82\n#: arduino/cores/status.go:106\nmsgid \"release cannot be nil\"\nmsgstr \"release cannot be nil\"\n\n#: arduino/cores/status.go:183\nmsgid \"release not found\"\nmsgstr \"release not found\"\n\n#: arduino/resources/helpers.go:59\nmsgid \"removing corrupted archive file: %s\"\nmsgstr \"removing corrupted archive file: %s\"\n\n#: arduino/libraries/librariesmanager/install.go:89\nmsgid \"removing lib directory: %s\"\nmsgstr \"removing lib directory: %s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:117\nmsgid \"removing platform files: %s\"\nmsgstr \"removing platform files: %s\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:169\nmsgid \"removing tool files: %s\"\nmsgstr \"removing tool files: %s\"\n\n#: arduino/cores/packagemanager/download.go:84\nmsgid \"required version %[1]s not found for platform %[2]s\"\nmsgstr \"required version %[1]s not found for platform %[2]s\"\n\n#: arduino/security/signatures.go:72\nmsgid \"retrieving Arduino public keys: %s\"\nmsgstr \"retrieving Arduino public keys: %s\"\n\n#: arduino/libraries/loader.go:109\n#: arduino/libraries/loader.go:140\nmsgid \"scanning examples: %s\"\nmsgstr \"scanning examples: %s\"\n\n#: arduino/cores/packagemanager/loader.go:640\nmsgid \"searching for builtin_tools_versions.txt in %[1]s: %[2]s\"\nmsgstr \"searching for builtin_tools_versions.txt in %[1]s: %[2]s\"\n\n#: arduino/resources/install.go:73\nmsgid \"searching package root dir: %s\"\nmsgstr \"searching package root dir: %s\"\n\n#: arduino/serialutils/serialutils.go:43\nmsgid \"setting DTR to OFF\"\nmsgstr \"setting DTR to OFF\"\n\n#: cli/board/attach.go:35\n#: cli/sketch/archive.go:38\nmsgid \"sketchPath\"\nmsgstr \"sketchPath\"\n\n#: arduino/cores/packagemanager/loader.go:496\nmsgid \"skipping loading of boards %s: malformed custom board options\"\nmsgstr \"skipping loading of boards %s: malformed custom board options\"\n\n#: legacy/builder/utils/utils.go:463\nmsgid \"source is not a directory\"\nmsgstr \"source is not a directory\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:149\nmsgid \"start syncing discovery %[1]s: %[2]w\"\nmsgstr \"start syncing discovery %[1]s: %[2]w\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:128\nmsgid \"starting discovery %[1]s: %[2]w\"\nmsgstr \"starting discovery %[1]s: %[2]w\"\n\n#: commands/board/list.go:277\nmsgid \"stopping discoveries: %s\"\nmsgstr \"stopping discoveries: %s\"\n\n#: arduino/discovery/discoverymanager/discoverymanager.go:172\nmsgid \"stopping discovery %[1]s: %[2]w\"\nmsgstr \"stopping discovery %[1]s: %[2]w\"\n\n#: arduino/resources/checksums.go:119\nmsgid \"testing archive checksum: %s\"\nmsgstr \"testing archive checksum: %s\"\n\n#: arduino/resources/checksums.go:112\nmsgid \"testing archive size: %s\"\nmsgstr \"testing archive size: %s\"\n\n#: arduino/resources/checksums.go:106\nmsgid \"testing if archive is cached: %s\"\nmsgstr \"testing if archive is cached: %s\"\n\n#: arduino/resources/install.go:37\nmsgid \"testing local archive integrity: %s\"\nmsgstr \"testing local archive integrity: %s\"\n\n#: legacy/builder/phases/sizer.go:111\nmsgid \"text section exceeds available space in board\"\nmsgstr \"text section exceeds available space in board\"\n\n#: arduino/libraries/librariesmanager/librariesmanager.go:65\nmsgid \"the library name is different from the set (%[1]s != %[2]s)\"\nmsgstr \"the library name is different from the set (%[1]s != %[2]s)\"\n\n#: commands/core/list.go:57\nmsgid \"the platform has no releases\"\nmsgstr \"the platform has no releases\"\n\n#: commands/board/list.go:72\nmsgid \"the server responded with status %s\"\nmsgstr \"the server responded with status %s\"\n\n#: arduino/discovery/discovery.go:228\nmsgid \"timeout waiting for message from %s\"\nmsgstr \"timeout waiting for message from %s\"\n\n#: cli/core/download.go:40\nmsgid \"to download the latest version of Arduino SAMD core.\\n\"\n\"\"\nmsgstr \"to download the latest version of Arduino SAMD core.\\n\"\n\"\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:165\nmsgid \"tool %s is not managed by package manager\"\nmsgstr \"tool %s is not managed by package manager\"\n\n#: arduino/cores/status.go:92\n#: arduino/cores/status.go:117\nmsgid \"tool %s not found\"\nmsgstr \"tool %s not found\"\n\n#: arduino/cores/packagemanager/package_manager.go:285\nmsgid \"tool '%[1]s' not found in package '%[2]s'\"\nmsgstr \"tool '%[1]s' not found in package '%[2]s'\"\n\n#: arduino/cores/packagemanager/download.go:114\nmsgid \"tool not available for your OS\"\nmsgstr \"tool not available for your OS\"\n\n#: arduino/cores/status.go:171\nmsgid \"tool not found\"\nmsgstr \"tool not found\"\n\n#: arduino/cores/packagemanager/install_uninstall.go:160\nmsgid \"tool not installed\"\nmsgstr \"tool not installed\"\n\n#: arduino/cores/packagemanager/package_manager.go:467\n#: arduino/cores/packagemanager/package_manager.go:533\nmsgid \"tool release not found: %s\"\nmsgstr \"tool release not found: %s\"\n\n#: arduino/cores/status.go:96\nmsgid \"tool version %s not found\"\nmsgstr \"tool version %s not found\"\n\n#: commands/lib/install.go:58\nmsgid \"two different versions of the library %[1]s are required: %[2]s and %[3]s\"\nmsgstr \"two different versions of the library %[1]s are required: %[2]s and %[3]s\"\n\n#: arduino/builder/sketch.go:69\n#: arduino/builder/sketch.go:117\nmsgid \"unable to compute relative path to the sketch for the item\"\nmsgstr \"unable to compute relative path to the sketch for the item\"\n\n#: arduino/builder/sketch.go:49\nmsgid \"unable to create a folder to save the sketch\"\nmsgstr \"unable to create a folder to save the sketch\"\n\n#: arduino/builder/sketch.go:111\nmsgid \"unable to create a folder to save the sketch files\"\nmsgstr \"unable to create a folder to save the sketch files\"\n\n#: arduino/builder/sketch.go:123\nmsgid \"unable to create the folder containing the item\"\nmsgstr \"unable to create the folder containing the item\"\n\n#: cli/config/dump.go:53\nmsgid \"unable to marshal config to YAML: %v\"\nmsgstr \"unable to marshal config to YAML: %v\"\n\n#: arduino/builder/sketch.go:161\nmsgid \"unable to read contents of the destination item\"\nmsgstr \"unable to read contents of the destination item\"\n\n#: arduino/builder/sketch.go:134\nmsgid \"unable to read contents of the source item\"\nmsgstr \"unable to read contents of the source item\"\n\n#: arduino/builder/sketch.go:55\nmsgid \"unable to save the sketch on disk\"\nmsgstr \"unable to save the sketch on disk\"\n\n#: arduino/builder/sketch.go:144\nmsgid \"unable to write to destination file\"\nmsgstr \"unable to write to destination file\"\n\n#: arduino/cores/packagemanager/package_manager.go:170\nmsgid \"unknown package %s\"\nmsgstr \"unknown package %s\"\n\n#: arduino/cores/packagemanager/package_manager.go:177\nmsgid \"unknown platform %s:%s\"\nmsgstr \"unknown platform %s:%s\"\n\n#: arduino/sketch/sketch.go:142\nmsgid \"unknown sketch file extension '%s'\"\nmsgstr \"unknown sketch file extension '%s'\"\n\n#: arduino/resources/checksums.go:62\nmsgid \"unsupported hash algorithm: %s\"\nmsgstr \"unsupported hash algorithm: %s\"\n\n#: cli/core/upgrade.go:44\nmsgid \"upgrade arduino:samd to the latest version\"\nmsgstr \"upgrade arduino:samd to the latest version\"\n\n#: cli/core/upgrade.go:42\nmsgid \"upgrade everything to the latest version\"\nmsgstr \"upgrade everything to the latest version\"\n\n#: commands/upload/upload.go:511\nmsgid \"uploading error: %s\"\nmsgstr \"uploading error: %s\"\n\n#: arduino/sketch/sketch.go:212\nmsgid \"writing sketch metadata %[1]s: %[2]s\"\nmsgstr \"writing sketch metadata %[1]s: %[2]s\"\n\n#: commands/board/list.go:88\nmsgid \"wrong format in server response\"\nmsgstr \"wrong format in server response\"\n\n#: legacy/builder/constants/constants.go:100\nmsgid \"{0} invalid\"\nmsgstr \"{0} invalid\"\n\n#: legacy/builder/constants/constants.go:102\nmsgid \"{0} is not a valid fully qualified board name. Required format is targetPackageName:targetPlatformName:targetBoardName.\"\nmsgstr \"{0} is not a valid fully qualified board name. Required format is targetPackageName:targetPlatformName:targetBoardName.\"\n\n#: legacy/builder/builder_utils/utils.go:323\n#: legacy/builder/builder_utils/utils.go:329\n#: legacy/builder/builder_utils/utils.go:393\nmsgid \"{0} newer than {1}\"\nmsgstr \"{0} newer than {1}\"\n\n#: legacy/builder/constants/constants.go:114\nmsgid \"{0}: Unknown package\"\nmsgstr \"{0}: Unknown package\"\n\n"), } file4 := &embedded.EmbeddedFile{ Filename: "it_IT.po", @@ -38,7 +38,7 @@ func init() { // define dirs dir1 := &embedded.EmbeddedDir{ Filename: "", - DirModTime: time.Unix(1629968478, 0), + DirModTime: time.Unix(1630310556, 0), ChildFiles: []*embedded.EmbeddedFile{ file2, // ".gitkeep" file3, // "en.po" @@ -54,7 +54,7 @@ func init() { // register embeddedBox embedded.RegisterEmbeddedBox(`./data`, &embedded.EmbeddedBox{ Name: `./data`, - Time: time.Unix(1629968478, 0), + Time: time.Unix(1630310556, 0), Dirs: map[string]*embedded.EmbeddedDir{ "": dir1, },