From 8c07823c10bde9409a42e7b90febb6cf19e7cb2b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 09:45:04 +0100 Subject: [PATCH 01/56] Moved a batch of function from commands/* subpackage to commands This commit is preparatory to move all the implementation of ArduinoCoreService interface directly as methods of ArduinoCoreService. The goal is to turn ArduinoCoreService into a proper implementation instead of being a mere proxy to global functions. --- .github/workflows/check-go-task.yml | 2 +- commands/instances.go | 2 - ...r.go => libraries_index_search_matcher.go} | 2 +- commands/{daemon/daemon.go => service.go} | 52 ++++++++----------- .../listall.go => service_board_listall.go} | 11 ++-- .../search.go => service_board_search.go} | 15 +++--- .../{daemon/debug.go => service_debug.go} | 2 +- ...ownload.go => service_library_download.go} | 8 +-- .../install.go => service_library_install.go} | 7 ++- .../{lib/list.go => service_library_list.go} | 2 +- ...eps.go => service_library_resolve_deps.go} | 5 +- .../search.go => service_library_search.go} | 2 +- ...test.go => service_library_search_test.go} | 8 +-- ...nstall.go => service_library_uninstall.go} | 5 +- .../upgrade.go => service_library_upgrade.go} | 5 +- ...wnload.go => service_platform_download.go} | 5 +- ...install.go => service_platform_install.go} | 7 ++- .../search.go => service_platform_search.go} | 7 ++- ...est.go => service_platform_search_test.go} | 21 +++++--- ...stall.go => service_platform_uninstall.go} | 5 +- ...upgrade.go => service_platform_upgrade.go} | 9 ++-- .../settings.go => service_settings.go} | 2 +- ...tings_test.go => service_settings_test.go} | 5 +- .../stream.go => service_stream_utility.go} | 2 +- commands/{daemon => }/term_example/main.go | 0 .../{daemon => }/testdata/arduino-cli.yml | 0 .../libraries}/full/library_index.json | 0 .../qualified_search/library_index.json | 0 .../libraries}/test1/library_index.json | 0 .../platform}/package_index.json | 0 docs/UPGRADING.md | 2 +- internal/cli/arguments/completion.go | 15 +++--- internal/cli/arguments/reference.go | 4 +- internal/cli/board/listall.go | 4 +- internal/cli/board/search.go | 4 +- internal/cli/compile/compile.go | 4 +- internal/cli/config/delete.go | 4 +- internal/cli/config/get.go | 4 +- internal/cli/core/download.go | 4 +- internal/cli/core/install.go | 4 +- internal/cli/core/list.go | 4 +- internal/cli/core/search.go | 3 +- internal/cli/core/uninstall.go | 4 +- internal/cli/core/upgrade.go | 6 +-- internal/cli/daemon/daemon.go | 4 +- internal/cli/lib/args.go | 4 +- internal/cli/lib/check_deps.go | 4 +- internal/cli/lib/download.go | 4 +- internal/cli/lib/examples.go | 4 +- internal/cli/lib/install.go | 8 +-- internal/cli/lib/list.go | 4 +- internal/cli/lib/search.go | 3 +- internal/cli/lib/uninstall.go | 4 +- internal/cli/lib/upgrade.go | 6 +-- internal/cli/upload/upload.go | 4 +- 55 files changed, 144 insertions(+), 162 deletions(-) rename commands/{lib/search_matcher.go => libraries_index_search_matcher.go} (99%) rename commands/{daemon/daemon.go => service.go} (94%) rename commands/{board/listall.go => service_board_listall.go} (91%) rename commands/{board/search.go => service_board_search.go} (87%) rename commands/{daemon/debug.go => service_debug.go} (99%) rename commands/{lib/download.go => service_library_download.go} (94%) rename commands/{lib/install.go => service_library_install.go} (96%) rename commands/{lib/list.go => service_library_list.go} (99%) rename commands/{lib/resolve_deps.go => service_library_resolve_deps.go} (97%) rename commands/{lib/search.go => service_library_search.go} (99%) rename commands/{lib/search_test.go => service_library_search_test.go} (95%) rename commands/{lib/uninstall.go => service_library_uninstall.go} (94%) rename commands/{lib/upgrade.go => service_library_upgrade.go} (95%) rename commands/{core/download.go => service_platform_download.go} (94%) rename commands/{core/install.go => service_platform_install.go} (92%) rename commands/{core/search.go => service_platform_search.go} (95%) rename commands/{core/search_test.go => service_platform_search_test.go} (94%) rename commands/{core/uninstall.go => service_platform_uninstall.go} (94%) rename commands/{core/upgrade.go => service_platform_upgrade.go} (88%) rename commands/{daemon/settings.go => service_settings.go} (99%) rename commands/{daemon/settings_test.go => service_settings_test.go} (98%) rename commands/{daemon/stream.go => service_stream_utility.go} (99%) rename commands/{daemon => }/term_example/main.go (100%) rename commands/{daemon => }/testdata/arduino-cli.yml (100%) rename commands/{lib/testdata => testdata/libraries}/full/library_index.json (100%) rename commands/{lib/testdata => testdata/libraries}/qualified_search/library_index.json (100%) rename commands/{lib/testdata => testdata/libraries}/test1/library_index.json (100%) rename commands/{core/testdata => testdata/platform}/package_index.json (100%) diff --git a/.github/workflows/check-go-task.yml b/.github/workflows/check-go-task.yml index 6e347253980..7388cc095e1 100644 --- a/.github/workflows/check-go-task.yml +++ b/.github/workflows/check-go-task.yml @@ -237,7 +237,7 @@ jobs: module: - path: internal/arduino/discovery/discovery_client - path: rpc/internal/client_example - - path: commands/daemon/term_example + - path: commands/term_example steps: - name: Checkout repository diff --git a/commands/instances.go b/commands/instances.go index df1d96f4c41..45f6a109f86 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -45,8 +45,6 @@ import ( "google.golang.org/grpc/status" ) -var tr = i18n.Tr - func installTool(pm *packagemanager.PackageManager, tool *cores.ToolRelease, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { pme, release := pm.NewExplorer() defer release() diff --git a/commands/lib/search_matcher.go b/commands/libraries_index_search_matcher.go similarity index 99% rename from commands/lib/search_matcher.go rename to commands/libraries_index_search_matcher.go index 3eec08b4ad9..f8ed7205c9d 100644 --- a/commands/lib/search_matcher.go +++ b/commands/libraries_index_search_matcher.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "strings" diff --git a/commands/daemon/daemon.go b/commands/service.go similarity index 94% rename from commands/daemon/daemon.go rename to commands/service.go index 97a2783e0e6..356c595baef 100644 --- a/commands/daemon/daemon.go +++ b/commands/service.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package daemon +package commands import ( "context" @@ -22,18 +22,14 @@ import ( "io" "sync/atomic" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/board" "github.com/arduino/arduino-cli/commands/cache" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/compile" - "github.com/arduino/arduino-cli/commands/core" - "github.com/arduino/arduino-cli/commands/lib" "github.com/arduino/arduino-cli/commands/monitor" "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/commands/updatecheck" "github.com/arduino/arduino-cli/commands/upload" - "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "google.golang.org/grpc/metadata" @@ -47,8 +43,6 @@ type ArduinoCoreServerImpl struct { VersionString string } -var tr = i18n.Tr - func convertErrorToRPCStatus(err error) error { if err == nil { return nil @@ -78,13 +72,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) + resp, err := BoardListAll(ctx, req) 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) + resp, err := BoardSearch(ctx, req) return resp, convertErrorToRPCStatus(err) } @@ -116,14 +110,14 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, s // Destroy FIXMEDOC func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { - resp, err := commands.Destroy(ctx, req) + resp, err := Destroy(ctx, req) return resp, convertErrorToRPCStatus(err) } // UpdateIndex FIXMEDOC func (s *ArduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream rpc.ArduinoCoreService_UpdateIndexServer) error { syncSend := NewSynchronizedSend(stream.Send) - res, err := commands.UpdateIndex(stream.Context(), req, + res, err := UpdateIndex(stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.UpdateIndexResponse{ Message: &rpc.UpdateIndexResponse_DownloadProgress{DownloadProgress: p}, @@ -141,7 +135,7 @@ func (s *ArduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream // UpdateLibrariesIndex FIXMEDOC func (s *ArduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesIndexRequest, stream rpc.ArduinoCoreService_UpdateLibrariesIndexServer) error { syncSend := NewSynchronizedSend(stream.Send) - res, err := commands.UpdateLibrariesIndex(stream.Context(), req, + res, err := UpdateLibrariesIndex(stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.UpdateLibrariesIndexResponse{ Message: &rpc.UpdateLibrariesIndexResponse_DownloadProgress{DownloadProgress: p}, @@ -165,14 +159,14 @@ func (s *ArduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque if len(userAgent) == 0 { userAgent = []string{"gRPCClientUnknown/0.0.0"} } - res, err := commands.Create(req, userAgent...) + res, err := Create(req, userAgent...) return res, convertErrorToRPCStatus(err) } // Init FIXMEDOC func (s *ArduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := commands.Init(req, func(message *rpc.InitResponse) { syncSend.Send(message) }) + err := Init(req, func(message *rpc.InitResponse) { syncSend.Send(message) }) return convertErrorToRPCStatus(err) } @@ -237,7 +231,7 @@ func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu // PlatformInstall FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - resp, err := core.PlatformInstall( + resp, err := PlatformInstall( stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformInstallResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) }, @@ -251,7 +245,7 @@ func (s *ArduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, // PlatformDownload FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadRequest, stream rpc.ArduinoCoreService_PlatformDownloadServer) error { syncSend := NewSynchronizedSend(stream.Send) - resp, err := core.PlatformDownload( + resp, err := PlatformDownload( stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformDownloadResponse{Progress: p}) }, ) @@ -264,7 +258,7 @@ func (s *ArduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadReques // PlatformUninstall FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequest, stream rpc.ArduinoCoreService_PlatformUninstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - resp, err := core.PlatformUninstall( + resp, err := PlatformUninstall( stream.Context(), req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) }, ) @@ -277,7 +271,7 @@ func (s *ArduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequ // PlatformUpgrade FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, stream rpc.ArduinoCoreService_PlatformUpgradeServer) error { syncSend := NewSynchronizedSend(stream.Send) - resp, err := core.PlatformUpgrade( + resp, err := PlatformUpgrade( stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{TaskProgress: p}) }, @@ -290,7 +284,7 @@ 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) + resp, err := PlatformSearch(req) return resp, convertErrorToRPCStatus(err) } @@ -387,7 +381,7 @@ func (s *ArduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Co // LibraryDownload FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, stream rpc.ArduinoCoreService_LibraryDownloadServer) error { syncSend := NewSynchronizedSend(stream.Send) - resp, err := lib.LibraryDownload( + resp, err := LibraryDownload( stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryDownloadResponse{Progress: p}) }, ) @@ -400,7 +394,7 @@ func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, // LibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, stream rpc.ArduinoCoreService_LibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := lib.LibraryInstall( + err := LibraryInstall( stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryInstallResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) }, @@ -411,7 +405,7 @@ func (s *ArduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s // LibraryUpgrade FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, stream rpc.ArduinoCoreService_LibraryUpgradeServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := lib.LibraryUpgrade( + err := LibraryUpgrade( stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{TaskProgress: p}) }, @@ -422,7 +416,7 @@ func (s *ArduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, s // LibraryUninstall FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallRequest, stream rpc.ArduinoCoreService_LibraryUninstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := lib.LibraryUninstall(stream.Context(), req, + err := LibraryUninstall(stream.Context(), req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) }, ) return convertErrorToRPCStatus(err) @@ -431,7 +425,7 @@ func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallReques // LibraryUpgradeAll FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, stream rpc.ArduinoCoreService_LibraryUpgradeAllServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := lib.LibraryUpgradeAll(req, + err := LibraryUpgradeAll(req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) }, ) @@ -440,19 +434,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) + resp, err := LibraryResolveDependencies(ctx, req) 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) + resp, err := LibrarySearch(ctx, req) 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) + resp, err := LibraryList(ctx, req) return resp, convertErrorToRPCStatus(err) } @@ -465,7 +459,7 @@ func (s *ArduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.Arch // ZipLibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequest, stream rpc.ArduinoCoreService_ZipLibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := lib.ZipLibraryInstall( + err := ZipLibraryInstall( stream.Context(), req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.ZipLibraryInstallResponse{TaskProgress: p}) }, ) @@ -475,7 +469,7 @@ func (s *ArduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequ // GitLibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequest, stream rpc.ArduinoCoreService_GitLibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := lib.GitLibraryInstall( + err := GitLibraryInstall( stream.Context(), req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.GitLibraryInstallResponse{TaskProgress: p}) }, ) diff --git a/commands/board/listall.go b/commands/service_board_listall.go similarity index 91% rename from commands/board/listall.go rename to commands/service_board_listall.go index 2b4e4d153e2..de20a7ce174 100644 --- a/commands/board/listall.go +++ b/commands/service_board_listall.go @@ -13,22 +13,21 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package board +package commands import ( "context" "sort" "strings" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/cores" "github.com/arduino/arduino-cli/internal/arduino/utils" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) -// ListAll FIXMEDOC -func ListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { +// BoardListAll FIXMEDOC +func BoardListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err @@ -47,8 +46,8 @@ func ListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListA } rpcPlatform := &rpc.Platform{ - Metadata: commands.PlatformToRPCPlatformMetadata(platform), - Release: commands.PlatformReleaseToRPC(installedPlatformRelease), + Metadata: PlatformToRPCPlatformMetadata(platform), + Release: PlatformReleaseToRPC(installedPlatformRelease), } toTest := []string{ diff --git a/commands/board/search.go b/commands/service_board_search.go similarity index 87% rename from commands/board/search.go rename to commands/service_board_search.go index 00ea3ac1e20..4bfd0906a20 100644 --- a/commands/board/search.go +++ b/commands/service_board_search.go @@ -13,24 +13,23 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package board +package commands import ( "context" "sort" "strings" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/utils" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) -// Search returns all boards that match the search arg. +// BoardSearch 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 BoardSearch(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err @@ -68,8 +67,8 @@ func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchR Fqbn: board.FQBN(), IsHidden: board.IsHidden(), Platform: &rpc.Platform{ - Metadata: commands.PlatformToRPCPlatformMetadata(platform), - Release: commands.PlatformReleaseToRPC(installedPlatformRelease), + Metadata: PlatformToRPCPlatformMetadata(platform), + Release: PlatformReleaseToRPC(installedPlatformRelease), }, }) } @@ -83,8 +82,8 @@ func Search(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchR foundBoards = append(foundBoards, &rpc.BoardListItem{ Name: strings.Trim(board.Name, " \n"), Platform: &rpc.Platform{ - Metadata: commands.PlatformToRPCPlatformMetadata(platform), - Release: commands.PlatformReleaseToRPC(latestPlatformRelease), + Metadata: PlatformToRPCPlatformMetadata(platform), + Release: PlatformReleaseToRPC(latestPlatformRelease), }, }) } diff --git a/commands/daemon/debug.go b/commands/service_debug.go similarity index 99% rename from commands/daemon/debug.go rename to commands/service_debug.go index d3de963bae4..363f77da862 100644 --- a/commands/daemon/debug.go +++ b/commands/service_debug.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package daemon +package commands import ( "context" diff --git a/commands/lib/download.go b/commands/service_library_download.go similarity index 94% rename from commands/lib/download.go rename to commands/service_library_download.go index 9d174ae1927..56102942ec2 100644 --- a/commands/lib/download.go +++ b/commands/service_library_download.go @@ -13,24 +13,20 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "context" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/httpclient" "github.com/arduino/arduino-cli/internal/arduino/libraries/librariesindex" - "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" ) -var tr = i18n.Tr - // LibraryDownload executes the download of the library. // A DownloadProgressCB callback function must be passed to monitor download progress. func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downloadCB rpc.DownloadProgressCB) (*rpc.LibraryDownloadResponse, error) { @@ -51,7 +47,7 @@ func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downl logrus.Info("Preparing download") - version, err := commands.ParseVersion(req.GetVersion()) + version, err := ParseVersion(req.GetVersion()) if err != nil { return nil, err } diff --git a/commands/lib/install.go b/commands/service_library_install.go similarity index 96% rename from commands/lib/install.go rename to commands/service_library_install.go index 873e442e4a0..b9fa369ebe0 100644 --- a/commands/lib/install.go +++ b/commands/service_library_install.go @@ -13,14 +13,13 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "context" "errors" "fmt" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/libraries" @@ -91,7 +90,7 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, downloa libReleasesToInstall := map[*librariesindex.Release]*librariesmanager.LibraryInstallPlan{} installLocation := libraries.FromRPCLibraryInstallLocation(req.GetInstallLocation()) for _, lib := range toInstall { - version, err := commands.ParseVersion(lib.GetVersionRequired()) + version, err := ParseVersion(lib.GetVersionRequired()) if err != nil { return err } @@ -137,7 +136,7 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, downloa } } - if err := commands.Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { return err } diff --git a/commands/lib/list.go b/commands/service_library_list.go similarity index 99% rename from commands/lib/list.go rename to commands/service_library_list.go index f5b28bdc426..84030341a43 100644 --- a/commands/lib/list.go +++ b/commands/service_library_list.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "context" diff --git a/commands/lib/resolve_deps.go b/commands/service_library_resolve_deps.go similarity index 97% rename from commands/lib/resolve_deps.go rename to commands/service_library_resolve_deps.go index b734e3d4ec7..5699cbf4052 100644 --- a/commands/lib/resolve_deps.go +++ b/commands/service_library_resolve_deps.go @@ -13,14 +13,13 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "context" "errors" "sort" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/libraries" @@ -48,7 +47,7 @@ func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDepe func libraryResolveDependencies(ctx context.Context, lme *librariesmanager.Explorer, li *librariesindex.Index, reqName, reqVersion string, noOverwrite bool) (*rpc.LibraryResolveDependenciesResponse, error) { - version, err := commands.ParseVersion(reqVersion) + version, err := ParseVersion(reqVersion) if err != nil { return nil, err } diff --git a/commands/lib/search.go b/commands/service_library_search.go similarity index 99% rename from commands/lib/search.go rename to commands/service_library_search.go index 7c2d21cdd70..d5ab7c86d80 100644 --- a/commands/lib/search.go +++ b/commands/service_library_search.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "context" diff --git a/commands/lib/search_test.go b/commands/service_library_search_test.go similarity index 95% rename from commands/lib/search_test.go rename to commands/service_library_search_test.go index faae69ef1a9..84f625b511e 100644 --- a/commands/lib/search_test.go +++ b/commands/service_library_search_test.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "strings" @@ -28,9 +28,9 @@ import ( ) var indexFilename, _ = globals.LibrariesIndexResource.IndexFileName() -var customIndexPath = paths.New("testdata", "test1", indexFilename) -var fullIndexPath = paths.New("testdata", "full", indexFilename) -var qualifiedSearchIndexPath = paths.New("testdata", "qualified_search", indexFilename) +var customIndexPath = paths.New("testdata", "libraries", "test1", indexFilename) +var fullIndexPath = paths.New("testdata", "libraries", "full", indexFilename) +var qualifiedSearchIndexPath = paths.New("testdata", "libraries", "qualified_search", indexFilename) func TestSearchLibrary(t *testing.T) { li, err := librariesindex.LoadIndex(customIndexPath) diff --git a/commands/lib/uninstall.go b/commands/service_library_uninstall.go similarity index 94% rename from commands/lib/uninstall.go rename to commands/service_library_uninstall.go index aee4ea68143..6f613760890 100644 --- a/commands/lib/uninstall.go +++ b/commands/service_library_uninstall.go @@ -13,12 +13,11 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "context" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/libraries" @@ -33,7 +32,7 @@ func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallRequest, tas return err } - version, err := commands.ParseVersion(req.GetVersion()) + version, err := ParseVersion(req.GetVersion()) if err != nil { return err } diff --git a/commands/lib/upgrade.go b/commands/service_library_upgrade.go similarity index 95% rename from commands/lib/upgrade.go rename to commands/service_library_upgrade.go index 0377744b972..75742a22dd3 100644 --- a/commands/lib/upgrade.go +++ b/commands/service_library_upgrade.go @@ -13,12 +13,11 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package lib +package commands import ( "context" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -42,7 +41,7 @@ func LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, downloadCB rpc.Downloa return err } - if err := commands.Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { return err } diff --git a/commands/core/download.go b/commands/service_platform_download.go similarity index 94% rename from commands/core/download.go rename to commands/service_platform_download.go index 7c686f4aee9..a8039af55b9 100644 --- a/commands/core/download.go +++ b/commands/service_platform_download.go @@ -13,12 +13,11 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package core +package commands import ( "context" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" @@ -36,7 +35,7 @@ func PlatformDownload(ctx context.Context, req *rpc.PlatformDownloadRequest, dow } defer release() - version, err := commands.ParseVersion(req.GetVersion()) + version, err := ParseVersion(req.GetVersion()) if err != nil { return nil, &cmderrors.InvalidVersionError{Cause: err} } diff --git a/commands/core/install.go b/commands/service_platform_install.go similarity index 92% rename from commands/core/install.go rename to commands/service_platform_install.go index a568a9dcfba..1fad3919f44 100644 --- a/commands/core/install.go +++ b/commands/service_platform_install.go @@ -13,13 +13,12 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package core +package commands import ( "context" "fmt" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" @@ -35,7 +34,7 @@ func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest, downl } defer release() - version, err := commands.ParseVersion(req.GetVersion()) + version, err := ParseVersion(req.GetVersion()) if err != nil { return &cmderrors.InvalidVersionError{Cause: err} } @@ -74,7 +73,7 @@ func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest, downl if err := install(); err != nil { return nil, err } - if err := commands.Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { return nil, err } return &rpc.PlatformInstallResponse{}, nil diff --git a/commands/core/search.go b/commands/service_platform_search.go similarity index 95% rename from commands/core/search.go rename to commands/service_platform_search.go index f68712c17e3..99f66ffa39a 100644 --- a/commands/core/search.go +++ b/commands/service_platform_search.go @@ -13,14 +13,13 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package core +package commands import ( "regexp" "sort" "strings" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/cores" "github.com/arduino/arduino-cli/internal/arduino/utils" @@ -82,7 +81,7 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse out := []*rpc.PlatformSummary{} for _, platform := range res { rpcPlatformSummary := &rpc.PlatformSummary{ - Metadata: commands.PlatformToRPCPlatformMetadata(platform), + Metadata: PlatformToRPCPlatformMetadata(platform), Releases: map[string]*rpc.PlatformRelease{}, } if installed := pme.GetInstalledPlatformRelease(platform); installed != nil { @@ -92,7 +91,7 @@ func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse rpcPlatformSummary.LatestVersion = latestCompatible.Version.String() } for _, platformRelease := range platform.GetAllReleases() { - rpcPlatformRelease := commands.PlatformReleaseToRPC(platformRelease) + rpcPlatformRelease := PlatformReleaseToRPC(platformRelease) rpcPlatformSummary.Releases[rpcPlatformRelease.GetVersion()] = rpcPlatformRelease } out = append(out, rpcPlatformSummary) diff --git a/commands/core/search_test.go b/commands/service_platform_search_test.go similarity index 94% rename from commands/core/search_test.go rename to commands/service_platform_search_test.go index e67c07c7e95..c6d7b789a2d 100644 --- a/commands/core/search_test.go +++ b/commands/service_platform_search_test.go @@ -13,13 +13,12 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package core +package commands import ( "testing" "github.com/arduino/arduino-cli/internal/cli/configuration" - "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" @@ -33,14 +32,20 @@ func TestPlatformSearch(t *testing.T) { dataDir.MkdirAll() downloadDir.MkdirAll() defer paths.TempDir().Join("test").RemoveAll() - err := paths.New("testdata").Join("package_index.json").CopyTo(dataDir.Join("package_index.json")) + err := paths.New("testdata", "platform", "package_index.json").CopyTo(dataDir.Join("package_index.json")) require.Nil(t, err) configuration.Settings = configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) - inst := instance.CreateAndInit() + createResp, err := Create(&rpc.CreateRequest{}) + require.NoError(t, err) + + inst := createResp.GetInstance() require.NotNil(t, inst) + err = Init(&rpc.InitRequest{Instance: inst}, nil) + require.NoError(t, err) + t.Run("SearchAllVersions", func(t *testing.T) { res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, @@ -327,13 +332,17 @@ func TestPlatformSearchSorting(t *testing.T) { dataDir.MkdirAll() downloadDir.MkdirAll() defer paths.TempDir().Join("test").RemoveAll() - err := paths.New("testdata").Join("package_index.json").CopyTo(dataDir.Join("package_index.json")) + err := paths.New("testdata", "platform", "package_index.json").CopyTo(dataDir.Join("package_index.json")) require.Nil(t, err) configuration.Settings = configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) - inst := instance.CreateAndInit() + createResp, err := Create(&rpc.CreateRequest{}) + require.NoError(t, err) + inst := createResp.GetInstance() require.NotNil(t, inst) + err = Init(&rpc.InitRequest{Instance: inst}, nil) + require.NoError(t, err) res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, diff --git a/commands/core/uninstall.go b/commands/service_platform_uninstall.go similarity index 94% rename from commands/core/uninstall.go rename to commands/service_platform_uninstall.go index d1c826ad210..26a2e404d58 100644 --- a/commands/core/uninstall.go +++ b/commands/service_platform_uninstall.go @@ -13,12 +13,11 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package core +package commands import ( "context" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" @@ -30,7 +29,7 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, t if err := platformUninstall(ctx, req, taskCB); err != nil { return nil, err } - if err := commands.Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { return nil, err } return &rpc.PlatformUninstallResponse{}, nil diff --git a/commands/core/upgrade.go b/commands/service_platform_upgrade.go similarity index 88% rename from commands/core/upgrade.go rename to commands/service_platform_upgrade.go index 57ba8de045e..2b8c5811364 100644 --- a/commands/core/upgrade.go +++ b/commands/service_platform_upgrade.go @@ -13,12 +13,11 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package core +package commands import ( "context" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/cores" "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" @@ -51,14 +50,14 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, downl platformRelease, err := upgrade() if platformRelease != nil { rpcPlatform = &rpc.Platform{ - Metadata: commands.PlatformToRPCPlatformMetadata(platformRelease.Platform), - Release: commands.PlatformReleaseToRPC(platformRelease), + Metadata: PlatformToRPCPlatformMetadata(platformRelease.Platform), + Release: PlatformReleaseToRPC(platformRelease), } } if err != nil { return &rpc.PlatformUpgradeResponse{Platform: rpcPlatform}, err } - if err := commands.Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { return nil, err } diff --git a/commands/daemon/settings.go b/commands/service_settings.go similarity index 99% rename from commands/daemon/settings.go rename to commands/service_settings.go index 2d8b9ca9039..806937fbb0c 100644 --- a/commands/daemon/settings.go +++ b/commands/service_settings.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package daemon +package commands import ( "context" diff --git a/commands/daemon/settings_test.go b/commands/service_settings_test.go similarity index 98% rename from commands/daemon/settings_test.go rename to commands/service_settings_test.go index 93f49174e50..ff2da8dac07 100644 --- a/commands/daemon/settings_test.go +++ b/commands/service_settings_test.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package daemon +package commands import ( "context" @@ -127,8 +127,7 @@ func TestGetMergedValue(t *testing.T) { func TestGetValueNotFound(t *testing.T) { key := &rpc.SettingsGetValueRequest{Key: "DOESNTEXIST"} _, err := svc.SettingsGetValue(context.Background(), key) - require.NotNil(t, err) - require.Equal(t, `key not found in settings`, err.Error()) + require.Error(t, err) } func TestSetValue(t *testing.T) { diff --git a/commands/daemon/stream.go b/commands/service_stream_utility.go similarity index 99% rename from commands/daemon/stream.go rename to commands/service_stream_utility.go index aa5e70fb770..4b285c443fc 100644 --- a/commands/daemon/stream.go +++ b/commands/service_stream_utility.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package daemon +package commands import ( "errors" diff --git a/commands/daemon/term_example/main.go b/commands/term_example/main.go similarity index 100% rename from commands/daemon/term_example/main.go rename to commands/term_example/main.go diff --git a/commands/daemon/testdata/arduino-cli.yml b/commands/testdata/arduino-cli.yml similarity index 100% rename from commands/daemon/testdata/arduino-cli.yml rename to commands/testdata/arduino-cli.yml diff --git a/commands/lib/testdata/full/library_index.json b/commands/testdata/libraries/full/library_index.json similarity index 100% rename from commands/lib/testdata/full/library_index.json rename to commands/testdata/libraries/full/library_index.json diff --git a/commands/lib/testdata/qualified_search/library_index.json b/commands/testdata/libraries/qualified_search/library_index.json similarity index 100% rename from commands/lib/testdata/qualified_search/library_index.json rename to commands/testdata/libraries/qualified_search/library_index.json diff --git a/commands/lib/testdata/test1/library_index.json b/commands/testdata/libraries/test1/library_index.json similarity index 100% rename from commands/lib/testdata/test1/library_index.json rename to commands/testdata/libraries/test1/library_index.json diff --git a/commands/core/testdata/package_index.json b/commands/testdata/platform/package_index.json similarity index 100% rename from commands/core/testdata/package_index.json rename to commands/testdata/platform/package_index.json diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md index ef245d67a75..8e5f0967ffc 100644 --- a/docs/UPGRADING.md +++ b/docs/UPGRADING.md @@ -1698,7 +1698,7 @@ https://arduino.github.io/arduino-cli/dev/rpc/commands/#monitorresponse https://arduino.github.io/arduino-cli/dev/rpc/commands/#enumeratemonitorportsettingsrequest https://arduino.github.io/arduino-cli/dev/rpc/commands/#enumeratemonitorportsettingsresponse -https://github.com/arduino/arduino-cli/blob/master/commands/daemon/term_example/main.go +https://github.com/arduino/arduino-cli/blob/752709af9bf1bf8f6c1e6f689b1e8b86cc4e884e/commands/daemon/term_example/main.go ## 0.23.0 diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index 4243a0fd409..8cc3df895a4 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -18,9 +18,8 @@ package arguments import ( "context" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/board" - "github.com/arduino/arduino-cli/commands/core" - "github.com/arduino/arduino-cli/commands/lib" "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -32,7 +31,7 @@ import ( func GetInstalledBoards() []string { inst := instance.CreateAndInit() - list, _ := board.ListAll(context.Background(), &rpc.BoardListAllRequest{ + list, _ := commands.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ Instance: inst, SearchArgs: nil, IncludeHiddenBoards: false, @@ -56,7 +55,7 @@ func GetInstalledProgrammers() []string { SearchArgs: nil, IncludeHiddenBoards: false, } - list, _ := board.ListAll(context.Background(), listAllReq) + list, _ := commands.BoardListAll(context.Background(), listAllReq) installedProgrammers := make(map[string]string) for _, board := range list.GetBoards() { @@ -83,7 +82,7 @@ func GetInstalledProgrammers() []string { func GetUninstallableCores() []string { inst := instance.CreateAndInit() - platforms, _ := core.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, ManuallyInstalled: true, }) @@ -104,7 +103,7 @@ func GetUninstallableCores() []string { func GetInstallableCores() []string { inst := instance.CreateAndInit() - platforms, _ := core.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "", }) @@ -132,7 +131,7 @@ func GetUninstallableLibraries() []string { func getLibraries(all bool) []string { inst := instance.CreateAndInit() - libs, _ := lib.LibraryList(context.Background(), &rpc.LibraryListRequest{ + libs, _ := commands.LibraryList(context.Background(), &rpc.LibraryListRequest{ Instance: inst, All: all, Updatable: false, @@ -152,7 +151,7 @@ func getLibraries(all bool) []string { func GetInstallableLibs() []string { inst := instance.CreateAndInit() - libs, _ := lib.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ + libs, _ := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ Instance: inst, SearchArgs: "", // if no query is specified all the libs are returned }) diff --git a/internal/cli/arguments/reference.go b/internal/cli/arguments/reference.go index bf4e327fed1..7593fd4e54e 100644 --- a/internal/cli/arguments/reference.go +++ b/internal/cli/arguments/reference.go @@ -19,8 +19,8 @@ import ( "fmt" "strings" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/core" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" @@ -95,7 +95,7 @@ func ParseReference(arg string) (*Reference, error) { // Now that we have the required informations in `ret` we can // try to use core.PlatformList to optimize what the user typed // (by replacing the PackageName and Architecture in ret with the content of core.GetPlatform()) - platforms, _ := core.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: instance.CreateAndInit(), }) foundPlatforms := []string{} diff --git a/internal/cli/board/listall.go b/internal/cli/board/listall.go index a4782b41d3c..82c5c7a0d2e 100644 --- a/internal/cli/board/listall.go +++ b/internal/cli/board/listall.go @@ -21,7 +21,7 @@ import ( "os" "sort" - "github.com/arduino/arduino-cli/commands/board" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -55,7 +55,7 @@ func runListAllCommand(cmd *cobra.Command, args []string) { logrus.Info("Executing `arduino-cli board listall`") - list, err := board.ListAll(context.Background(), &rpc.BoardListAllRequest{ + list, err := commands.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ Instance: inst, SearchArgs: args, IncludeHiddenBoards: showHiddenBoard, diff --git a/internal/cli/board/search.go b/internal/cli/board/search.go index b590ddb6e15..b52a704c1dc 100644 --- a/internal/cli/board/search.go +++ b/internal/cli/board/search.go @@ -22,7 +22,7 @@ import ( "sort" "strings" - "github.com/arduino/arduino-cli/commands/board" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -52,7 +52,7 @@ func runSearchCommand(cmd *cobra.Command, args []string) { logrus.Info("Executing `arduino-cli board search`") - res, err := board.Search(context.Background(), &rpc.BoardSearchRequest{ + res, err := commands.BoardSearch(context.Background(), &rpc.BoardSearchRequest{ Instance: inst, SearchArgs: strings.Join(args, " "), IncludeHiddenBoards: showHiddenBoard, diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 2b607b78536..13db316f12b 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -24,9 +24,9 @@ import ( "os" "strings" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/compile" - "github.com/arduino/arduino-cli/commands/core" "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/arguments" @@ -384,7 +384,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) { if profileArg.String() == "" { res.Error += fmt.Sprintln() - if platform, err := core.PlatformSearch(&rpc.PlatformSearchRequest{ + if platform, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: platformErr.Platform, }); err != nil { diff --git a/internal/cli/config/delete.go b/internal/cli/config/delete.go index ae5bd7976b5..2102a2581d7 100644 --- a/internal/cli/config/delete.go +++ b/internal/cli/config/delete.go @@ -18,7 +18,7 @@ package config import ( "os" - "github.com/arduino/arduino-cli/commands/daemon" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -47,7 +47,7 @@ func runDeleteCommand(cmd *cobra.Command, args []string) { logrus.Info("Executing `arduino-cli config delete`") toDelete := args[0] - svc := daemon.ArduinoCoreServerImpl{} + svc := commands.ArduinoCoreServerImpl{} _, err := svc.SettingsDelete(cmd.Context(), &rpc.SettingsDeleteRequest{Key: toDelete}) if err != nil { feedback.Fatal(tr("Cannot delete the key %[1]s: %[2]v", toDelete, err), feedback.ErrGeneric) diff --git a/internal/cli/config/get.go b/internal/cli/config/get.go index cb2a5cb0072..74fcd93fa72 100644 --- a/internal/cli/config/get.go +++ b/internal/cli/config/get.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/daemon" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -50,7 +50,7 @@ func initGetCommand() *cobra.Command { func runGetCommand(cmd *cobra.Command, args []string) { logrus.Info("Executing `arduino-cli config get`") - svc := daemon.ArduinoCoreServerImpl{} + svc := commands.ArduinoCoreServerImpl{} for _, toGet := range args { resp, err := svc.SettingsGetValue(cmd.Context(), &rpc.SettingsGetValueRequest{Key: toGet}) if err != nil { diff --git a/internal/cli/core/download.go b/internal/cli/core/download.go index daa87f04ef2..6fafe678b5e 100644 --- a/internal/cli/core/download.go +++ b/internal/cli/core/download.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/core" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" @@ -63,7 +63,7 @@ func runDownloadCommand(cmd *cobra.Command, args []string) { Architecture: platformRef.Architecture, Version: platformRef.Version, } - _, err := core.PlatformDownload(context.Background(), platformDownloadreq, feedback.ProgressBar()) + _, err := commands.PlatformDownload(context.Background(), platformDownloadreq, feedback.ProgressBar()) if err != nil { feedback.Fatal(tr("Error downloading %[1]s: %[2]v", args[i], err), feedback.ErrNetwork) } diff --git a/internal/cli/core/install.go b/internal/cli/core/install.go index 8193a8b4344..98dc7c4135d 100644 --- a/internal/cli/core/install.go +++ b/internal/cli/core/install.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/core" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" @@ -75,7 +75,7 @@ func runInstallCommand(args []string, scriptFlags arguments.PrePostScriptsFlags, NoOverwrite: noOverwrite, SkipPreUninstall: scriptFlags.DetectSkipPreUninstallValue(), } - _, err := core.PlatformInstall(context.Background(), platformInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) + _, err := commands.PlatformInstall(context.Background(), platformInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) if err != nil { feedback.Fatal(tr("Error during install: %v", err), feedback.ErrGeneric) } diff --git a/internal/cli/core/list.go b/internal/cli/core/list.go index a2434ab676f..db5fbbaf927 100644 --- a/internal/cli/core/list.go +++ b/internal/cli/core/list.go @@ -18,7 +18,7 @@ package core import ( "os" - "github.com/arduino/arduino-cli/commands/core" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -60,7 +60,7 @@ func List(inst *rpc.Instance, all bool, updatableOnly bool) { // GetList returns a list of installed platforms. func GetList(inst *rpc.Instance, all bool, updatableOnly bool) []*rpc.PlatformSummary { - platforms, err := core.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, ManuallyInstalled: true, }) diff --git a/internal/cli/core/search.go b/internal/cli/core/search.go index d24e486ade7..6a6b559a5cf 100644 --- a/internal/cli/core/search.go +++ b/internal/cli/core/search.go @@ -23,7 +23,6 @@ import ( "time" "github.com/arduino/arduino-cli/commands" - "github.com/arduino/arduino-cli/commands/core" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -74,7 +73,7 @@ func runSearchCommand(cmd *cobra.Command, args []string, allVersions bool) { arguments := strings.ToLower(strings.Join(args, " ")) logrus.Infof("Executing `arduino-cli core search` with args: '%s'", arguments) - resp, err := core.PlatformSearch(&rpc.PlatformSearchRequest{ + resp, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: arguments, }) diff --git a/internal/cli/core/uninstall.go b/internal/cli/core/uninstall.go index 10992ef9bdf..c8e3c212ac1 100644 --- a/internal/cli/core/uninstall.go +++ b/internal/cli/core/uninstall.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/core" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" @@ -63,7 +63,7 @@ func runUninstallCommand(args []string, preUninstallFlags arguments.PrePostScrip } } for _, platformRef := range platformsRefs { - _, err := core.PlatformUninstall(context.Background(), &rpc.PlatformUninstallRequest{ + _, err := commands.PlatformUninstall(context.Background(), &rpc.PlatformUninstallRequest{ Instance: inst, PlatformPackage: platformRef.PackageName, Architecture: platformRef.Architecture, diff --git a/internal/cli/core/upgrade.go b/internal/cli/core/upgrade.go index e98dd72b244..9bd400fc9fb 100644 --- a/internal/cli/core/upgrade.go +++ b/internal/cli/core/upgrade.go @@ -21,8 +21,8 @@ import ( "fmt" "os" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/core" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" @@ -60,7 +60,7 @@ func runUpgradeCommand(args []string, skipPostInstall bool, skipPreUninstall boo func Upgrade(inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUninstall bool) { // if no platform was passed, upgrade allthethings if len(args) == 0 { - platforms, err := core.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, }) if err != nil { @@ -122,7 +122,7 @@ func Upgrade(inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUni SkipPostInstall: skipPostInstall, SkipPreUninstall: skipPreUninstall, } - response, err := core.PlatformUpgrade(context.Background(), r, feedback.ProgressBar(), feedback.TaskProgress()) + response, err := commands.PlatformUpgrade(context.Background(), r, feedback.ProgressBar(), feedback.TaskProgress()) warningMissingIndex(response) if err != nil { var alreadyAtLatestVersionErr *cmderrors.PlatformAlreadyAtTheLatestVersionError diff --git a/internal/cli/daemon/daemon.go b/internal/cli/daemon/daemon.go index fcda04024f4..a96f5a3ffff 100644 --- a/internal/cli/daemon/daemon.go +++ b/internal/cli/daemon/daemon.go @@ -24,7 +24,7 @@ import ( "strings" "syscall" - "github.com/arduino/arduino-cli/commands/daemon" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/i18n" @@ -102,7 +102,7 @@ func runDaemonCommand(cmd *cobra.Command, args []string) { configuration.Settings.Set("network.user_agent_ext", "daemon") // register the commands service - srv_commands.RegisterArduinoCoreServiceServer(s, &daemon.ArduinoCoreServerImpl{ + srv_commands.RegisterArduinoCoreServiceServer(s, &commands.ArduinoCoreServerImpl{ VersionString: version.VersionInfo.VersionString, }) diff --git a/internal/cli/lib/args.go b/internal/cli/lib/args.go index 75639b8bc84..b69b0664910 100644 --- a/internal/cli/lib/args.go +++ b/internal/cli/lib/args.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) @@ -76,7 +76,7 @@ func ParseLibraryReferenceArgs(args []string) ([]*LibraryReferenceArg, error) { // 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, _ := ParseLibraryReferenceArg(arg) - res, err := lib.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ + res, err := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ Instance: instance, SearchArgs: libRef.Name, }) diff --git a/internal/cli/lib/check_deps.go b/internal/cli/lib/check_deps.go index 557983298fb..248ac85843b 100644 --- a/internal/cli/lib/check_deps.go +++ b/internal/cli/lib/check_deps.go @@ -21,7 +21,7 @@ import ( "os" "sort" - "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -61,7 +61,7 @@ func runDepsCommand(args []string, noOverwrite bool) { feedback.Fatal(tr("Arguments error: %v", err), feedback.ErrBadArgument) } - deps, err := lib.LibraryResolveDependencies(context.Background(), &rpc.LibraryResolveDependenciesRequest{ + deps, err := commands.LibraryResolveDependencies(context.Background(), &rpc.LibraryResolveDependenciesRequest{ Instance: instance, Name: libRef.Name, Version: libRef.Version, diff --git a/internal/cli/lib/download.go b/internal/cli/lib/download.go index 3616584a91d..733e3567fe7 100644 --- a/internal/cli/lib/download.go +++ b/internal/cli/lib/download.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" @@ -60,7 +60,7 @@ func runDownloadCommand(cmd *cobra.Command, args []string) { Name: library.Name, Version: library.Version, } - _, err := lib.LibraryDownload(context.Background(), libraryDownloadRequest, feedback.ProgressBar()) + _, err := commands.LibraryDownload(context.Background(), libraryDownloadRequest, feedback.ProgressBar()) if err != nil { feedback.Fatal(tr("Error downloading %[1]s: %[2]v", library, err), feedback.ErrNetwork) } diff --git a/internal/cli/lib/examples.go b/internal/cli/lib/examples.go index 11fadebdbef..beca10871a5 100644 --- a/internal/cli/lib/examples.go +++ b/internal/cli/lib/examples.go @@ -22,7 +22,7 @@ import ( "sort" "strings" - "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -63,7 +63,7 @@ func runExamplesCommand(cmd *cobra.Command, args []string) { name = args[0] } - res, err := lib.LibraryList(context.Background(), &rpc.LibraryListRequest{ + res, err := commands.LibraryList(context.Background(), &rpc.LibraryListRequest{ Instance: instance, All: true, Name: name, diff --git a/internal/cli/lib/install.go b/internal/cli/lib/install.go index 72a2a0592f9..7bd5c53764b 100644 --- a/internal/cli/lib/install.go +++ b/internal/cli/lib/install.go @@ -21,7 +21,7 @@ import ( "os" "strings" - "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" @@ -89,7 +89,7 @@ func runInstallCommand(args []string, noDeps bool, noOverwrite bool, gitURL bool if zipPath { for _, path := range args { - err := lib.ZipLibraryInstall(context.Background(), &rpc.ZipLibraryInstallRequest{ + err := commands.ZipLibraryInstall(context.Background(), &rpc.ZipLibraryInstallRequest{ Instance: instance, Path: path, Overwrite: !noOverwrite, @@ -110,7 +110,7 @@ func runInstallCommand(args []string, noDeps bool, noOverwrite bool, gitURL bool } url = wd.String() } - err := lib.GitLibraryInstall(context.Background(), &rpc.GitLibraryInstallRequest{ + err := commands.GitLibraryInstall(context.Background(), &rpc.GitLibraryInstallRequest{ Instance: instance, Url: url, Overwrite: !noOverwrite, @@ -140,7 +140,7 @@ func runInstallCommand(args []string, noDeps bool, noOverwrite bool, gitURL bool NoOverwrite: noOverwrite, InstallLocation: installLocation, } - err := lib.LibraryInstall(context.Background(), libraryInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) + err := commands.LibraryInstall(context.Background(), libraryInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) if err != nil { feedback.Fatal(tr("Error installing %s: %v", libRef.Name, err), feedback.ErrGeneric) } diff --git a/internal/cli/lib/list.go b/internal/cli/lib/list.go index dca14c6f407..1c0ba7dd6c1 100644 --- a/internal/cli/lib/list.go +++ b/internal/cli/lib/list.go @@ -22,7 +22,7 @@ import ( "sort" "strings" - "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -84,7 +84,7 @@ func GetList( name = args[0] } - res, err := lib.LibraryList(context.Background(), &rpc.LibraryListRequest{ + res, err := commands.LibraryList(context.Background(), &rpc.LibraryListRequest{ Instance: instance, All: all, Updatable: updatable, diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index 913344f582d..2e1e27d4e9b 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -23,7 +23,6 @@ import ( "time" "github.com/arduino/arduino-cli/commands" - "github.com/arduino/arduino-cli/commands/lib" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/instance" @@ -119,7 +118,7 @@ func runSearchCommand(args []string, namesOnly bool, omitReleasesDetails bool) { instance.Init(inst) } - searchResp, err := lib.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ + searchResp, err := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ Instance: inst, SearchArgs: strings.Join(args, " "), OmitReleasesDetails: omitReleasesDetails, diff --git a/internal/cli/lib/uninstall.go b/internal/cli/lib/uninstall.go index 897b0203320..2a03a463aa1 100644 --- a/internal/cli/lib/uninstall.go +++ b/internal/cli/lib/uninstall.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" @@ -54,7 +54,7 @@ func runUninstallCommand(cmd *cobra.Command, args []string) { } for _, library := range refs { - err := lib.LibraryUninstall(context.Background(), &rpc.LibraryUninstallRequest{ + err := commands.LibraryUninstall(context.Background(), &rpc.LibraryUninstallRequest{ Instance: instance, Name: library.Name, Version: library.Version, diff --git a/internal/cli/lib/upgrade.go b/internal/cli/lib/upgrade.go index 5375e5d6795..e83b54f20ac 100644 --- a/internal/cli/lib/upgrade.go +++ b/internal/cli/lib/upgrade.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/lib" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -53,14 +53,14 @@ func Upgrade(instance *rpc.Instance, libraries []string) { var upgradeErr error if len(libraries) == 0 { req := &rpc.LibraryUpgradeAllRequest{Instance: instance} - upgradeErr = lib.LibraryUpgradeAll(req, feedback.ProgressBar(), feedback.TaskProgress()) + upgradeErr = commands.LibraryUpgradeAll(req, feedback.ProgressBar(), feedback.TaskProgress()) } else { for _, libName := range libraries { req := &rpc.LibraryUpgradeRequest{ Instance: instance, Name: libName, } - upgradeErr = lib.LibraryUpgrade(context.Background(), req, feedback.ProgressBar(), feedback.TaskProgress()) + upgradeErr = commands.LibraryUpgrade(context.Background(), req, feedback.ProgressBar(), feedback.TaskProgress()) if upgradeErr != nil { break } diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 46ec877fc8b..7f04e731a83 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -22,8 +22,8 @@ import ( "os" "strings" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/core" sk "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/arguments" @@ -135,7 +135,7 @@ func runUploadCommand(args []string, uploadFieldsArgs map[string]string) { } msg += "\n" - if platform, err := core.PlatformSearch(&rpc.PlatformSearchRequest{ + if platform, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: platformErr.Platform, }); err != nil { From 3d8f50a5c87719207576fa6a3acb6b280aaac728 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 10:26:24 +0100 Subject: [PATCH 02/56] Moved a batch of function from commands/* subpackage to commands (part 2) --- commands/board/board.go | 20 - commands/board/testdata/package_index.json | 2523 ----------------- commands/service.go | 10 +- .../details.go => service_board_details.go} | 6 +- .../{board/list.go => service_board_list.go} | 10 +- ...ist_test.go => service_board_list_test.go} | 19 +- .../compile.go => service_compile.go} | 5 +- internal/cli/arguments/completion.go | 3 +- internal/cli/arguments/port.go | 6 +- internal/cli/arguments/programmer.go | 8 +- internal/cli/board/details.go | 4 +- internal/cli/board/list.go | 6 +- internal/cli/compile/compile.go | 3 +- 13 files changed, 41 insertions(+), 2582 deletions(-) delete mode 100644 commands/board/board.go delete mode 100644 commands/board/testdata/package_index.json rename commands/{board/details.go => service_board_details.go} (96%) rename commands/{board/list.go => service_board_list.go} (95%) rename commands/{board/list_test.go => service_board_list_test.go} (91%) rename commands/{compile/compile.go => service_compile.go} (99%) diff --git a/commands/board/board.go b/commands/board/board.go deleted file mode 100644 index 3baebc26d27..00000000000 --- a/commands/board/board.go +++ /dev/null @@ -1,20 +0,0 @@ -// 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 board - -import "github.com/arduino/arduino-cli/internal/i18n" - -var tr = i18n.Tr diff --git a/commands/board/testdata/package_index.json b/commands/board/testdata/package_index.json deleted file mode 100644 index e36f45cb5b0..00000000000 --- a/commands/board/testdata/package_index.json +++ /dev/null @@ -1,2523 +0,0 @@ -{ - "packages": [ - { - "name": "arduino", - "maintainer": "Arduino", - "websiteURL": "http://www.arduino.cc/", - "email": "packages@arduino.cc", - "help": { - "online": "http://www.arduino.cc/en/Reference/HomePage" - }, - "platforms": [ - { - "name": "Arduino AVR Boards", - "architecture": "avr", - "version": "1.8.3", - "category": "Arduino", - "help": { - "online": "http://www.arduino.cc/en/Reference/HomePage" - }, - "url": "http://downloads.arduino.cc/cores/avr-1.8.3.tar.bz2", - "archiveFileName": "avr-1.8.3.tar.bz2", - "checksum": "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", - "size": "4941548", - "boards": [ - { "name": "Arduino Yún" }, - { "name": "Arduino Uno" }, - { "name": "Arduino Uno WiFi" }, - { "name": "Arduino Diecimila" }, - { "name": "Arduino Nano" }, - { "name": "Arduino Mega" }, - { "name": "Arduino MegaADK" }, - { "name": "Arduino Leonardo" }, - { "name": "Arduino Leonardo Ethernet" }, - { "name": "Arduino Micro" }, - { "name": "Arduino Esplora" }, - { "name": "Arduino Mini" }, - { "name": "Arduino Ethernet" }, - { "name": "Arduino Fio" }, - { "name": "Arduino BT" }, - { "name": "Arduino LilyPadUSB" }, - { "name": "Arduino Lilypad" }, - { "name": "Arduino Pro" }, - { "name": "Arduino ATMegaNG" }, - { "name": "Arduino Robot Control" }, - { "name": "Arduino Robot Motor" }, - { "name": "Arduino Gemma" }, - { "name": "Adafruit Circuit Playground" }, - { "name": "Arduino Yún Mini" }, - { "name": "Arduino Industrial 101" }, - { "name": "Linino One" } - ], - "toolsDependencies": [ - { - "packager": "arduino", - "name": "avr-gcc", - "version": "7.3.0-atmel3.6.1-arduino7" - }, - { - "packager": "arduino", - "name": "avrdude", - "version": "6.3.0-arduino17" - }, - { - "packager": "arduino", - "name": "arduinoOTA", - "version": "1.3.0" - } - ] - } - ], - "tools": [ - { - "name": "arm-none-eabi-gcc", - "version": "4.8.3-2014q1", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-arm.tar.bz2", - "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-arm.tar.bz2", - "checksum": "SHA-256:ebe96b34c4f434667cab0187b881ed585e7c7eb990fe6b69be3c81ec7e11e845", - "size": "44423906" - }, - { - "host": "i686-mingw32", - "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-windows.tar.gz", - "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-windows.tar.gz", - "checksum": "SHA-256:fd8c111c861144f932728e00abd3f7d1107e186eb9cd6083a54c7236ea78b7c2", - "size": "84537449" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-mac.tar.gz", - "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-mac.tar.gz", - "checksum": "SHA-256:3598acf21600f17a8e4a4e8e193dc422b894dc09384759b270b2ece5facb59c2", - "size": "52518522" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-linux64.tar.gz", - "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-linux64.tar.gz", - "checksum": "SHA-256:d23f6626148396d6ec42a5b4d928955a703e0757829195fa71a939e5b86eecf6", - "size": "51395093" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-linux32.tar.gz", - "archiveFileName": "gcc-arm-none-eabi-4.8.3-2014q1-linux32.tar.gz", - "checksum": "SHA-256:ba1994235f69c526c564f65343f22ddbc9822b2ea8c5ee07dd79d89f6ace2498", - "size": "51029223" - } - ] - }, - { - "name": "arm-none-eabi-gcc", - "version": "7-2017q4", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2019-q4-major-linuxarm.tar.bz2", - "archiveFileName": "gcc-arm-none-eabi-7-2019-q4-major-linuxarm.tar.bz2", - "checksum": "SHA-256:34180943d95f759c66444a40b032f7dd9159a562670fc334f049567de140c51b", - "size": "96613739" - }, - { - "host": "aarch64-linux-gnu", - "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2018-q2-update-linuxarm64.tar.bz2", - "archiveFileName": "gcc-arm-none-eabi-7-2018-q2-update-linuxarm64.tar.bz2", - "checksum": "SHA-256:6fb5752fb4d11012bd0a1ceb93a19d0641ff7cf29d289b3e6b86b99768e66f76", - "size": "99558726" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2017-q4-major-win32-arduino1.zip", - "archiveFileName": "gcc-arm-none-eabi-7-2017-q4-major-win32-arduino1.zip", - "checksum": "SHA-256:96dd0091856f4d2eb21046eba571321feecf7d50b9c156f708b2a8b683903382", - "size": "131761924" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2017-q4-major-mac.tar.bz2", - "archiveFileName": "gcc-arm-none-eabi-7-2017-q4-major-mac.tar.bz2", - "checksum": "SHA-256:89b776c7cf0591c810b5b60067e4dc113b5b71bc50084a536e71b894a97fdccb", - "size": "104550003" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2017-q4-major-linux64.tar.bz2", - "archiveFileName": "gcc-arm-none-eabi-7-2017-q4-major-linux64.tar.bz2", - "checksum": "SHA-256:96a029e2ae130a1210eaa69e309ea40463028eab18ba19c1086e4c2dafe69a6a", - "size": "99857645" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/gcc-arm-none-eabi-7-2018-q2-update-linux32.tar.bz2", - "archiveFileName": "gcc-arm-none-eabi-7-2018-q2-update-linux32.tar.bz2", - "checksum": "SHA-256:090a0bc2b1956bc49392dff924a6c30fa57c88130097b1972204d67a45ce3cf3", - "size": "97427309" - } - ] - }, - { - "name": "bossac", - "version": "1.3-arduino", - "systems": [ - { - "host": "i686-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.3a-arduino-i686-linux-gnu.tar.bz2", - "archiveFileName": "bossac-1.3a-arduino-i686-linux-gnu.tar.bz2", - "checksum": "SHA-256:d6d10362f40729a7877e43474fcf02ad82cf83321cc64ca931f5c82b2d25d24f", - "size": "147359" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.3a-arduino-x86_64-pc-linux-gnu.tar.bz2", - "archiveFileName": "bossac-1.3a-arduino-x86_64-pc-linux-gnu.tar.bz2", - "checksum": "SHA-256:c1daed033251296768fa8b63ad283e053da93427c0f3cd476a71a9188e18442c", - "size": "26179" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/bossac-1.3a-arduino-i686-mingw32.tar.bz2", - "archiveFileName": "bossac-1.3a-arduino-i686-mingw32.tar.bz2", - "checksum": "SHA-256:a37727622e0f86cb4f2856ad0209568a5d804234dba3dc0778829730d61a5ec7", - "size": "265647" - }, - { - "host": "i386-apple-darwin11", - "url": "http://downloads.arduino.cc/tools/bossac-1.3a-arduino-i386-apple-darwin11.tar.bz2", - "archiveFileName": "bossac-1.3a-arduino-i386-apple-darwin11.tar.bz2", - "checksum": "SHA-256:40770b225753e7a52bb165e8f37e6b760364f5c5e96048168d0178945bd96ad6", - "size": "39475" - } - ] - }, - { - "name": "avr-gcc", - "version": "4.8.1-arduino2", - "systems": [ - { - "size": "24443285", - "checksum": "SHA-256:c19a7526235c364d7f62ec1a993d9b495973ba1813869ccf0241c65905896852", - "host": "i386-apple-darwin11", - "archiveFileName": "avr-gcc-4.8.1-arduino2-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino2-i386-apple-darwin11.tar.bz2" - }, - { - "size": "27152002", - "checksum": "SHA-256:24a931877bee5f36dc00a88877219a6d2f6a1fb7abb989fd04556b8432d2e14e", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-4.8.1-arduino2-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino2-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "25876628", - "checksum": "SHA-256:2d701b4efbc8cec62dc299cde01730c5eebcf23d7e4393db8cf7744a9bf1d3de", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-4.8.1-arduino2-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino2-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "46046691", - "checksum": "SHA-256:2eafb49fb803fa4d2c32d35e24c0b372fcd520ca0a790fa537a847179e382000", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-4.8.1-arduino2-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino2-i686-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.0.1-arduino2", - "systems": [ - { - "size": "264965", - "checksum": "SHA-256:71117cce0096dad6c091e2c34eb0b9a3386d3aec7d863d2da733d9e5eac3a6b1", - "host": "i386-apple-darwin11", - "archiveFileName": "avrdude-6.0.1-arduino2-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i386-apple-darwin11.tar.bz2" - }, - { - "size": "292541", - "checksum": "SHA-256:2489004d1d98177eaf69796760451f89224007c98b39ebb5577a9a34f51425f1", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.0.1-arduino2-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "283209", - "checksum": "SHA-256:6f633dd6270ad0d9ef19507bcbf8697b414a15208e4c0f71deec25ef89cdef3f", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.0.1-arduino2-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "241618", - "checksum": "SHA-256:6c5483800ba753c80893607e30cade8ab77b182808fcc5ea15fa3019c63d76ae", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.0.1-arduino2-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino2-i686-mingw32.zip" - } - ] - }, - { - "name": "avr-gcc", - "version": "4.8.1-arduino3", - "systems": [ - { - "size": "24447175", - "checksum": "SHA-256:28e207c66b3dc405367d0c5e68ce3c278e5ec3abb0e4974e7927fe0f9a532c40", - "host": "i386-apple-darwin11", - "archiveFileName": "avr-gcc-4.8.1-arduino3-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino3-i386-apple-darwin11.tar.bz2" - }, - { - "size": "30556996", - "checksum": "SHA-256:028340abec6eb3085b82404dfc7ed143e1bb05b2da961b539ddcdba4a6f65533", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-4.8.1-arduino3-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino3-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "28768022", - "checksum": "SHA-256:37796548ba9653267568f959cd8c7ebfe5b4bce4599898cf9f876d64e616cb87", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-4.8.1-arduino3-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino3-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "46046917", - "checksum": "SHA-256:d6f0527793f9800f060408392a99eb290ed205730edbae43a1a25cbf6b6b588f", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-4.8.1-arduino3-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino3-i686-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.0.1-arduino3", - "systems": [ - { - "size": "264682", - "checksum": "SHA-256:df7cd4a76e45ab3767eb964f845f4d5e9d643df950ec32812923da1e9843d072", - "host": "i386-apple-darwin11", - "archiveFileName": "avrdude-6.0.1-arduino3-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino3-i386-apple-darwin11.tar.bz2" - }, - { - "size": "748634", - "checksum": "SHA-256:bb7bff48f20a68e1fe559c3f3f644574df12ab5c98eb6a1491079f3c760434ad", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.0.1-arduino3-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino3-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "495482", - "checksum": "SHA-256:96a0cfb83fe0452366159e3bf4e19ff10906a8957d1feafd3d98b49ab4b14405", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.0.1-arduino3-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino3-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "241619", - "checksum": "SHA-256:ea59bfc2ee85039c85318b2ba52c47ef0573513444a785b72f59b22586a950f9", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.0.1-arduino3-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino3-i686-mingw32.zip" - } - ] - }, - { - "name": "avr-gcc", - "version": "4.8.1-arduino5", - "systems": [ - { - "size": "24403768", - "checksum": "SHA-256:c8ffcd2db7a651b48ab4ea19db4b34fbae3e7f0210a0f294592af2bdabf2154b", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avr-gcc-4.8.1-arduino5-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "24437400", - "checksum": "SHA-256:111b3ef00d737d069eb237a8933406cbb928e4698689e24663cffef07688a901", - "host": "i386-apple-darwin11", - "archiveFileName": "avr-gcc-4.8.1-arduino5-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-i386-apple-darwin11.tar.bz2" - }, - { - "size": "27093036", - "checksum": "SHA-256:9054fcc174397a419ba56c4ce1bfcbcad275a6a080cc144905acc9b0351ee9cc", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-4.8.1-arduino5-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "25882375", - "checksum": "SHA-256:7648b7f549b37191da0b0be53bae791b652f82ac3cb4e7877f85075aaf32141f", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-4.8.1-arduino5-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "46044779", - "checksum": "SHA-256:d4303226a7b41d3c445d901b5aa5903458def3fc7b7ff4ffef37cabeb37d424d", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-4.8.1-arduino5-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.8.1-arduino5-i686-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.0.1-arduino5", - "systems": [ - { - "size": "267095", - "checksum": "SHA-256:23ea1341dbc117ec067f2eb1a498ad2bdd7d11fff0143c00b2e018c39804f6b4", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avrdude-6.0.1-arduino5-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "264894", - "checksum": "SHA-256:41af8d3b0a586853c8317b4fb5163ca0db594a1870ddf680fd988c42166fc3e5", - "host": "i386-apple-darwin11", - "archiveFileName": "avrdude-6.0.1-arduino5-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-i386-apple-darwin11.tar.bz2" - }, - { - "size": "292629", - "checksum": "SHA-256:d826cca7383461f7e8adde686372cf900e9cb3afd639555cf2d6c645b283a476", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.0.1-arduino5-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "283121", - "checksum": "SHA-256:5933d66927bce46ababa9b68a8b7f1d53f68c4f3ff7a5ce4b85d7cf4e6c6bfee", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.0.1-arduino5-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "241634", - "checksum": "SHA-256:41f667f1f6a0ab8df46b4ffacd023176dcdef331d6db3b74bddd37d18cca0a44", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.0.1-arduino5-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.0.1-arduino5-i686-mingw32.zip" - } - ] - }, - { - "name": "avr-gcc", - "version": "4.9.2-atmel3.5.3-arduino", - "systems": [ - { - "size": "27046965", - "checksum": "SHA-256:adeee70be27cc3ee0e4b9e844610d9c534c7b21dae24ec3fa49808c2f04958de", - "host": "i386-apple-darwin11", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino-i386-apple-darwin11.tar.bz2" - }, - { - "size": "27400001", - "checksum": "SHA-256:02dba9ee77694c23a4c304416a3808949c8faedf07f25a225a4189d850615ec6", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "29904544", - "checksum": "SHA-256:0711e885c0430859e7fea3831af8c69a0c25f92a90ecfda9281799a0acec7455", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "29077606", - "checksum": "SHA-256:fe0bb1d6369694779ceb671d457ccadbeafe855a11f6746b7db20055cea4df33", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "43847566", - "checksum": "SHA-256:445ce3117e87be7e196809fbbea373976160689b6d4b43dbf185eb4c914d1469", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino-i686-mingw32.zip" - } - ] - }, - { - "name": "avr-gcc", - "version": "4.9.2-atmel3.5.3-arduino2", - "systems": [ - { - "size": "27400889", - "checksum": "SHA-256:77f300d519bc6b9a25df17b36cb303218e9a258c059b2f6bff8f71a0d8f96821", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino2-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino2-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "27048070", - "checksum": "SHA-256:311258af188defe24a4b341e4e1f4dc93ca6c80516d3e3b55a2fc07a7050248b", - "host": "i386-apple-darwin11", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino2-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino2-i386-apple-darwin11.tar.bz2" - }, - { - "size": "43847945", - "checksum": "SHA-256:f8e6ede8746c70be01ec79a30803277cd94360cc5b2e104762da0fbcf536fcc6", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino2-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino2-i686-mingw32.zip" - }, - { - "size": "29292729", - "checksum": "SHA-256:f108951e7c4dc90926d1fc76cc27549f6ea63c702a2bb7ff39647a19ae86ec68", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino2-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino2-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "29882960", - "checksum": "SHA-256:3903a6d1bb9fdd91727e504b5993d5501f119bcb7f99f7aee98a2101e5629188", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.3-arduino2-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.3-arduino2-x86_64-pc-linux-gnu.tar.bz2" - } - ] - }, - { - "name": "avr-gcc", - "version": "4.9.2-atmel3.5.4-arduino2", - "systems": [ - { - "size": "27764772", - "checksum": "SHA-256:ee36009e19bd238d1f6351cbc9aa5db69714761f67dec4c1d69d5d5d7758720c", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.4-arduino2-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.4-arduino2-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "28574644", - "checksum": "SHA-256:67b3ed3555eacf0b4fc6f62240773b9f0220171fe4de26bb8d711547fc884730", - "host": "i386-apple-darwin11", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.4-arduino2-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.4-arduino2-i386-apple-darwin11.tar.bz2" - }, - { - "size": "44386446", - "checksum": "SHA-256:6044551cd729d88ea6ffcccf10aad1934c5b164d61f4f5890b0e78524ffff853", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.4-arduino2-i686-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.4-arduino2-i686-mingw32.zip" - }, - { - "size": "29723974", - "checksum": "SHA-256:63a9d4cebbac06fd5fa8f48a2e2ba7d513837dcddc97f560129b4e466af901b5", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.4-arduino2-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.4-arduino2-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "30374404", - "checksum": "SHA-256:19480217f1524d78467b83cd742f503182bbcc76b5440093261f146828aa588c", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-4.9.2-atmel3.5.4-arduino2-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-4.9.2-atmel3.5.4-arduino2-x86_64-pc-linux-gnu.tar.bz2" - } - ] - }, - { - "name": "avr-gcc", - "version": "5.4.0-atmel3.6.1-arduino2", - "systems": [ - { - "size": "31449123", - "checksum": "SHA-256:6741f95cc3182a8729cf9670eb13d8dc5a19e881639ca61e53a2d78346a4e99f", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avr-gcc-5.4.0-atmel3.6.1-arduino2-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-5.4.0-atmel3.6.1-arduino2-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "33141295", - "checksum": "SHA-256:0fa9e4f2d6d09782dbc84dd91a302849cde2f192163cb9f29484c5f32785269a", - "host": "aarch64-linux-gnu", - "archiveFileName": "avr-gcc-5.4.0-atmel3.6.1-arduino2-aarch64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-5.4.0-atmel3.6.1-arduino2-aarch64-pc-linux-gnu.tar.bz2" - }, - { - "size": "31894498", - "checksum": "SHA-256:abc50137543ba73e227b4d1b8510fff50a474bacd24f2c794f852904963849f8", - "host": "i386-apple-darwin11", - "archiveFileName": "avr-gcc-5.4.0-atmel3.6.1-arduino2-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-5.4.0-atmel3.6.1-arduino2-i386-apple-darwin11.tar.bz2" - }, - { - "size": "45923772", - "checksum": "SHA-256:7eb5691a379b547798fae535b05d68bc02d3969f12d051b8a5a5f2f350ab0a7f", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-5.4.0-atmel3.6.1-arduino2-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-5.4.0-atmel3.6.1-arduino2-i686-w64-mingw32.zip" - }, - { - "size": "33022916", - "checksum": "SHA-256:51f87e04f3cdaa73565c751051ac118e02904ad8478f1475b300e1bffcd5538f", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-5.4.0-atmel3.6.1-arduino2-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-5.4.0-atmel3.6.1-arduino2-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "33522375", - "checksum": "SHA-256:05422b0d73b10357c12ea938f02cf50529422b89a4722756e70024aed3e69185", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-5.4.0-atmel3.6.1-arduino2-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-5.4.0-atmel3.6.1-arduino2-x86_64-pc-linux-gnu.tar.bz2" - } - ] - }, - { - "name": "avr-gcc", - "version": "7.3.0-atmel3.6.1-arduino5", - "systems": [ - { - "size": "34462042", - "checksum": "SHA-256:f4acd5531c6b82c715e2edfa0aadb13fb718b4095b3ea1aa1f7fbde680069639", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino5-arm-linux-gnueabihf.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-arm-linux-gnueabihf.tar.bz2" - }, - { - "size": "39381972", - "checksum": "SHA-256:dd9c70190be370a44fb47dab1514de6d8852b861dfa527964b65c740d8d50c10", - "host": "aarch64-linux-gnu", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino5-aarch64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-aarch64-pc-linux-gnu.tar.bz2" - }, - { - "size": "38492678", - "checksum": "SHA-256:f48706317f04452544ab90e75bd1bb193f8af2cb1002f53aa702f27202c1b38f", - "host": "x86_64-apple-darwin14", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino5-x86_64-apple-darwin14.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-x86_64-apple-darwin14.tar.bz2" - }, - { - "size": "53727984", - "checksum": "SHA-256:6d4a5d089a36e5b5252befc73da204555b49e376ce7577ee19ca7f028b295830", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino5-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-i686-w64-mingw32.zip" - }, - { - "size": "38710087", - "checksum": "SHA-256:2ff12739d7ed09688d6b3c2c126e8df69b5bda1a07ab558799f0e576571e0e1d", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino5-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "39114120", - "checksum": "SHA-256:3effed8ffa1978b6e4a46f1aa2acc629e440b4d77244f71f9b79a916025206fb", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino5-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino5-x86_64-pc-linux-gnu.tar.bz2" - } - ] - }, - { - "name": "avr-gcc", - "version": "7.3.0-atmel3.6.1-arduino7", - "systems": [ - { - "size": "34683056", - "checksum": "SHA-256:3903553d035da59e33cff9941b857c3cb379cb0638105dfdf69c97f0acc8e7b5", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2" - }, - { - "size": "38045723", - "checksum": "SHA-256:03d322b9df6da17289e9e7c6233c34a8535d9c645c19efc772ba19e56914f339", - "host": "aarch64-linux-gnu", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-aarch64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-aarch64-pc-linux-gnu.tar.bz2" - }, - { - "size": "36684546", - "checksum": "SHA-256:f6ed2346953fcf88df223469088633eb86de997fa27ece117fd1ef170d69c1f8", - "host": "x86_64-apple-darwin14", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-x86_64-apple-darwin14.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-x86_64-apple-darwin14.tar.bz2" - }, - { - "size": "52519412", - "checksum": "SHA-256:a54f64755fff4cb792a1495e5defdd789902a2a3503982e81b898299cf39800e", - "host": "i686-mingw32", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-i686-w64-mingw32.zip" - }, - { - "size": "37176991", - "checksum": "SHA-256:954bbffb33545bcdcd473af993da2980bf32e8461ff55a18e0eebc7b2ef69a4c", - "host": "i686-linux-gnu", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "37630618", - "checksum": "SHA-256:bd8c37f6952a2130ac9ee32c53f6a660feb79bee8353c8e289eb60fdcefed91e", - "host": "x86_64-linux-gnu", - "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-x86_64-pc-linux-gnu.tar.bz2" - } - ] - }, - { - "name": "avrdude", - "version": "6.3.0-arduino2", - "systems": [ - { - "size": "643484", - "checksum": "SHA-256:26af86137d8a872f64d217cb262734860b36fe26d6d34faf72e951042f187885", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avrdude-6.3.0-arduino2-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino2-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "653968", - "checksum": "SHA-256:32525ea3696c861030e1a6006a5f11971d1dad331e45bfa68dac35126476b04f", - "host": "i386-apple-darwin11", - "archiveFileName": "avrdude-6.3.0-arduino2-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino2-i386-apple-darwin11.tar.bz2" - }, - { - "size": "745081", - "checksum": "SHA-256:9635af5a35bdca11804c07582d7beec458140fb6e3308168c3deda18dc6790fa", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino2-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino2-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "731802", - "checksum": "SHA-256:790b6cb610c48e73a2a0f65dcee9903d2fd7f1b0a1f75008a9a21f50a60c7251", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino2-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino2-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "608496", - "checksum": "SHA-256:8eaf98ea41fbd4450483488ef31710cbcc43c0412dbc8e1e1b582feaab6eca30", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.3.0-arduino2-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino2-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.3.0-arduino6", - "systems": [ - { - "size": "644600", - "checksum": "SHA-256:2426207423d58eb0e5fc4df9493418f1cb54ba3f328fdc7c3bb582f920b9cbe7", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avrdude-6.3.0-arduino6-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino6-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "696273", - "checksum": "SHA-256:d9a039c9e92d3dbb2011e75e6c044a1a4a2789e2fbf8386b1d580994811be084", - "host": "i386-apple-darwin11", - "archiveFileName": "avrdude-6.3.0-arduino6-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino6-i386-apple-darwin11.tar.bz2" - }, - { - "size": "746653", - "checksum": "SHA-256:97b4875cad6110c70101bb776f3ac37b64a2e73f036cd0b10afb6f4be96a6621", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino6-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino6-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "733127", - "checksum": "SHA-256:5f4bc4b0957b1d34cec9908b7f84a7c297b894b39fe16a4992c284b24c00d6fb", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino6-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino6-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "645859", - "checksum": "SHA-256:7468a1bcdfa459d175a095b102c0de28efc466accfb104305fbcad7832659ddc", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.3.0-arduino6-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino6-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.3.0-arduino8", - "systems": [ - { - "size": "644550", - "checksum": "SHA-256:25a6834ae48019fccf37024236a1f79fe21760414292a4f3fa058d937ceee1ce", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avrdude-6.3.0-arduino8-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino8-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "697268", - "checksum": "SHA-256:be8a33a7ec01bb7123279466ffa31371e0aa4fccefffcc23ce71810b59531947", - "host": "i386-apple-darwin11", - "archiveFileName": "avrdude-6.3.0-arduino8-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino8-i386-apple-darwin11.tar.bz2" - }, - { - "size": "711544", - "checksum": "SHA-256:85f38d02e2398d3b7f93da2ca8b830ee65bb73f66cc7a7b30c466d3cebf2da6e", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino8-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino8-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "701718", - "checksum": "SHA-256:8e2e4bc71d22e9d11ed143763b97f3aa2d164cdeee678a9deaf5b36e245b2d20", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino8-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino8-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "645996", - "checksum": "SHA-256:3a7592f6c33efd658b820c73d1058d3c868a297cbddb37da5644973c3b516d5e", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.3.0-arduino8-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino8-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.3.0-arduino9", - "systems": [ - { - "size": "644550", - "checksum": "SHA-256:25a6834ae48019fccf37024236a1f79fe21760414292a4f3fa058d937ceee1ce", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avrdude-6.3.0-arduino9-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino9-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "697309", - "checksum": "SHA-256:bfa06bc042dff252d3a8eded98da159484e75b46d2697da4d9446dcd2aea8465", - "host": "i386-apple-darwin11", - "archiveFileName": "avrdude-6.3.0-arduino9-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino9-i386-apple-darwin11.tar.bz2" - }, - { - "size": "711229", - "checksum": "SHA-256:c8cccb84e2fe49ee837b24f0a60a99e9c371dae26e84c5b0b22b6b6aab2f1f6a", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino9-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino9-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "701590", - "checksum": "SHA-256:4235a2d58e3c3224c603d6c5f0610507ed6c48ebf4051fdcce9f77a7646e218b", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino9-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino9-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "645974", - "checksum": "SHA-256:f3c5cfa8d0b3b0caee81c5b35fb6acff89c342ef609bf4266734c6266a256d4f", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.3.0-arduino9-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino9-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.3.0-arduino14", - "systems": [ - { - "size": "219616", - "checksum": "SHA-256:d1a06275490d59a431c419788bbc53ffd5a79510dac1a35e63cf488621ba5589", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avrdude-6.3.0-arduino14-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "229688", - "checksum": "SHA-256:439f5de150695e3732dd598bb182dae6ec1e3a5cdb580f855d9b58e485e84e66", - "host": "aarch64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino14-aarch64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-aarch64-pc-linux-gnu.tar.bz2" - }, - { - "size": "256917", - "checksum": "SHA-256:47d03991522722ce92120c60c4118685b7861909d895f34575001137961e4a63", - "host": "i386-apple-darwin11", - "archiveFileName": "avrdude-6.3.0-arduino14-i386-apple-darwin12.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-i386-apple-darwin11.tar.bz2" - }, - { - "size": "253366", - "checksum": "SHA-256:7986e8f3059353dc08f9234f7dbc98d9b2fa2242f046f02a8243a060f7358bfc", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino14-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "244293", - "checksum": "SHA-256:4f100e3843c635064997df91d2a079ab15cd30d1d7fa227280abe6a7c3bc74ca", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino14-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "328363", - "checksum": "SHA-256:69293e0de2eff8de89f553477795c25005f674a320bbba4b0222beb0194aa297", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.3.0-arduino14-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino14-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.3.0-arduino16", - "systems": [ - { - "size": "219642", - "checksum": "SHA-256:6fc443445440f0e2d95d70013ed075bceffc2a1babc1e7d4f1ae69c3fe268c57", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avrdude-6.3.0-arduino16-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino16-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "229997", - "checksum": "SHA-256:7a2726ab2fd18b910abc3d9dd33c4b40d18c34cf12c46f3367932e7fd87c0197", - "host": "aarch64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino16-aarch64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino16-aarch64-pc-linux-gnu.tar.bz2" - }, - { - "size": "279172", - "checksum": "SHA-256:f93dc12a4b30a335ab24b3c628e6cad0ebf2f8adfb7ef50f87c0fc17165b2156", - "host": "x86_64-apple-darwin15", - "archiveFileName": "avrdude-6.3.0-arduino16-i386-apple-darwin11.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino16-i386-apple-darwin11.tar.bz2" - }, - { - "size": "254085", - "checksum": "SHA-256:57856d6e388d333d924afa3e2d5525161dbe0dc670e7caae2720e249606175a7", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino16-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino16-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "244393", - "checksum": "SHA-256:bdf73358991243a9a8de11a42c80c4ec4b14c82f2222cb0c3c181f62656c41fb", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino16-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino16-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "328456", - "checksum": "SHA-256:781c16a8bf813fa68fc0f47d427279053c9e098c3aed7165449ac4f0137304dd", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.3.0-arduino16-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino16-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "avrdude", - "version": "6.3.0-arduino17", - "systems": [ - { - "size": "219631", - "checksum": "SHA-256:2a8e68c5d803aa6f902ef219f177ec3a4c28275d85cbe272962ad2cd374f50d1", - "host": "arm-linux-gnueabihf", - "archiveFileName": "avrdude-6.3.0-arduino17-armhf-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-armhf-pc-linux-gnu.tar.bz2" - }, - { - "size": "229852", - "checksum": "SHA-256:6cf948f751acfe7b96684537f2291c766ec8b54b4f7dc95539864821456fa9fc", - "host": "aarch64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino17-aarch64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-aarch64-pc-linux-gnu.tar.bz2" - }, - { - "size": "279045", - "checksum": "SHA-256:120cc9edaae699e7e9ac50b1b8eb0e7d51fdfa555bac54233c2511e6ee5418c9", - "host": "x86_64-apple-darwin12", - "archiveFileName": "avrdude-6.3.0-arduino17-x86_64-apple-darwin12.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-x86_64-apple-darwin12.tar.bz2" - }, - { - "size": "254271", - "checksum": "SHA-256:accdfb920af2aabf4f7461d2ac73c0751760f525216dc4e7657427a78c60d13d", - "host": "x86_64-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino17-x86_64-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-x86_64-pc-linux-gnu.tar.bz2" - }, - { - "size": "244550", - "checksum": "SHA-256:5c8cc6c17db9300e1451fe41cd7178b0442b4490ee6fdbc0aed9811aef96c05f", - "host": "i686-linux-gnu", - "archiveFileName": "avrdude-6.3.0-arduino17-i686-pc-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-i686-pc-linux-gnu.tar.bz2" - }, - { - "size": "328460", - "checksum": "SHA-256:e99188873c7c5ad8f8f906f068c33600e758b2e36cce3adbd518a21bd266749d", - "host": "i686-mingw32", - "archiveFileName": "avrdude-6.3.0-arduino17-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/avrdude-6.3.0-arduino17-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "arduinoOTA", - "version": "1.0.0", - "systems": [ - { - "size": "2044124", - "checksum": "SHA-256:850a86876403cb45c944590a8cc7f9d8ef6d53ed853f7a9593ec395c4c1c6b2d", - "host": "i686-linux-gnu", - "archiveFileName": "arduinoOTA-1.0.0-linux32.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.0.0-linux32.tar.bz2" - }, - { - "size": "2178772", - "checksum": "SHA-256:f01f25e02787492a8a30414230635adae76ed85228045437433892d185991f9e", - "host": "x86_64-linux-gnu", - "archiveFileName": "arduinoOTA-1.0.0-linux64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.0.0-linux64.tar.bz2" - }, - { - "size": "1961623", - "checksum": "SHA-256:0ca6c0a93bfad50be0b6e62dc51ba6c3267b809bab4ec91ef9606ab7d838e46b", - "host": "arm-linux-gnueabihf", - "archiveFileName": "arduinoOTA-1.0.0-linuxarm.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.0.0-linuxarm.tar.bz2" - }, - { - "size": "2180617", - "checksum": "SHA-256:e63c6034da2c1a7fe453eaa29c22df88627cc0aa3c5cbab7635c19367b74ee59", - "host": "i386-apple-darwin11", - "archiveFileName": "arduinoOTA-1.0.0-osx.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.0.0-osx.tar.bz2" - }, - { - "size": "2247970", - "checksum": "SHA-256:7bced1489217e07661ea1e75702a10a874b54f6146e2414ee47684c7eac014d1", - "host": "i686-mingw32", - "archiveFileName": "arduinoOTA-1.0.0-windows.zip", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.0.0-windows.zip" - } - ] - }, - { - "name": "arduinoOTA", - "version": "1.1.1", - "systems": [ - { - "size": "2045036", - "checksum": "SHA-256:7ac91ef1d5b357c0ceb790be02ef54986db598ba5a42fffbd6c8ecbdd6a271ef", - "host": "i686-linux-gnu", - "archiveFileName": "arduinoOTA-1.1.1-linux_386.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.1.1-linux_386.tar.bz2" - }, - { - "size": "2178288", - "checksum": "SHA-256:eb5ad0a457dd7f610f7f9b85454399c36755673d61a16f9d07cdfcbbb32ec277", - "host": "x86_64-linux-gnu", - "archiveFileName": "arduinoOTA-1.1.1-linux_amd64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.1.1-linux_amd64.tar.bz2" - }, - { - "size": "1962115", - "checksum": "SHA-256:e4880d83df3d3f6f4b7b7bcde161e80a0556877468803a3c6066ee4ad18a374c", - "host": "arm-linux-gnueabihf", - "archiveFileName": "arduinoOTA-1.1.1-linux_arm.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.1.1-linux_arm.tar.bz2" - }, - { - "size": "2181376", - "checksum": "SHA-256:a1ce7cf578982f3af5e4fab6b5839e44830d7a41cb093faba5c4b45952a6fa55", - "host": "i386-apple-darwin11", - "archiveFileName": "arduinoOTA-1.1.1-darwin_amd64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.1.1-darwin_amd64.tar.bz2" - }, - { - "size": "2248431", - "checksum": "SHA-256:b2d3610c77f969a68cd75b6ea66bf63ec10c263937009d99147fbcd975c90006", - "host": "i686-mingw32", - "archiveFileName": "arduinoOTA-1.1.1-windows_386.zip", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.1.1-windows_386.zip" - } - ] - }, - { - "name": "arduinoOTA", - "version": "1.2.0", - "systems": [ - { - "size": "1839854", - "checksum": "SHA-256:7157a0b56620fb43b8dfb4afd958f8b294476a5ce4322c212167ca5d4092f2d9", - "host": "i686-linux-gnu", - "archiveFileName": "arduinoOTA-1.2.0-linux_386.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.0-linux_386.tar.bz2" - }, - { - "size": "1974030", - "checksum": "SHA-256:f672c1c407c4cb10729a1d891bdb8b010e2043e5415e1c2559bf39cdeaede78c", - "host": "x86_64-linux-gnu", - "archiveFileName": "arduinoOTA-1.2.0-linux_amd64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.0-linux_amd64.tar.bz2" - }, - { - "size": "1787138", - "checksum": "SHA-256:ac49ffcd3239a6a52215f89dbda012d28f1296e6d79fc0efc3df06f919105744", - "host": "arm-linux-gnueabihf", - "archiveFileName": "arduinoOTA-1.2.0-linux_arm.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.0-linux_arm.tar.bz2" - }, - { - "size": "1992476", - "checksum": "SHA-256:160e83e77d7a60514ca40fedf34f539124aac4b9ae0e2bfdf8fda11d958de38f", - "host": "i386-apple-darwin11", - "archiveFileName": "arduinoOTA-1.2.0-darwin_amd64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.0-darwin_amd64.tar.bz2" - }, - { - "size": "2003964", - "checksum": "SHA-256:9d26747093ab7966bfeffced9dbd7def0e164bba0db89f5efb3f7f8011496c8f", - "host": "i686-mingw32", - "archiveFileName": "arduinoOTA-1.2.0-windows_386.zip", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.0-windows_386.zip" - } - ] - }, - { - "name": "arduinoOTA", - "version": "1.2.1", - "systems": [ - { - "size": "2133779", - "checksum": "SHA-256:2ffdf64b78486c1d0bf28dc23d0ca36ab75ca92e84b9487246da01888abea6d4", - "host": "i686-linux-gnu", - "archiveFileName": "arduinoOTA-1.2.1-linux_386.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-linux_386.tar.bz2" - }, - { - "size": "2257689", - "checksum": "SHA-256:5b82310d53688480f34a916aac31cd8f2dd2be65dd8fa6c2445262262e1948f9", - "host": "x86_64-linux-gnu", - "archiveFileName": "arduinoOTA-1.2.1-linux_amd64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-linux_amd64.tar.bz2" - }, - { - "size": "2093132", - "checksum": "SHA-256:ad54b3dcd586212941fd992bab573b53d13207a419a3f2981c970a085ae0e9e0", - "host": "arm-linux-gnueabihf", - "archiveFileName": "arduinoOTA-1.2.1-linux_arm.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-linux_arm.tar.bz2" - }, - { - "size": "2093132", - "checksum": "SHA-256:ad54b3dcd586212941fd992bab573b53d13207a419a3f2981c970a085ae0e9e0", - "host": "aarch64-linux-gnu", - "archiveFileName": "arduinoOTA-1.2.1-linux_arm.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-linux_arm.tar.bz2" - }, - { - "size": "2244088", - "checksum": "SHA-256:93a6d9f9c0c765d237be1665bf7a0a8e2b0b6d2a8531eae92db807f5515088a7", - "host": "i386-apple-darwin11", - "archiveFileName": "arduinoOTA-1.2.1-darwin_amd64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-darwin_amd64.tar.bz2" - }, - { - "size": "2237511", - "checksum": "SHA-256:e1ebf21f2c073fce25c09548c656da90d4ef6c078401ec6f323e0c58335115e5", - "host": "i686-mingw32", - "archiveFileName": "arduinoOTA-1.2.1-windows_386.zip", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.2.1-windows_386.zip" - } - ] - }, - { - "name": "arduinoOTA", - "version": "1.3.0", - "systems": [ - { - "size": "2633516", - "checksum": "SHA-256:3e7f59d6fbc7a724598303f0d3289d0c4fd137a8973437980658379a024887b2", - "host": "i686-linux-gnu", - "archiveFileName": "arduinoOTA-1.3.0-linux_386.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.3.0-linux_386.tar.bz2" - }, - { - "size": "2716248", - "checksum": "SHA-256:aa45ee2441ffc3a122daec5802941d1fa2ac47adf5c5c481b5e0daa4dc259ffa", - "host": "x86_64-linux-gnu", - "archiveFileName": "arduinoOTA-1.3.0-linux_amd64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.3.0-linux_amd64.tar.bz2" - }, - { - "size": "2567435", - "checksum": "SHA-256:1888587409b56aef4ba0ab0e6703b3dccba7cc3a022756ba9b908247e5d5a656", - "host": "arm-linux-gnueabihf", - "archiveFileName": "arduinoOTA-1.3.0-linux_arm.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.3.0-linux_arm.tar.bz2" - }, - { - "size": "2472427", - "checksum": "SHA-256:835ed8f37cffac37e979d1b0f6041559592d3d98be52f0e8611b76c4858e4113", - "host": "aarch64-linux-gnu", - "archiveFileName": "arduinoOTA-1.3.0-linux_arm64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.3.0-linux_arm64.tar.bz2" - }, - { - "size": "2766116", - "checksum": "SHA-256:d5d0f82ff829c0e434d12a2ee640a6fbd78f893ab37782edbb8b5bf2359d119e", - "host": "i386-apple-darwin11", - "archiveFileName": "arduinoOTA-1.3.0-darwin_amd64.tar.bz2", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.3.0-darwin_amd64.tar.bz2" - }, - { - "size": "2768948", - "checksum": "SHA-256:051943844eee442460d2c709edefadca184287fffd2b6c100dd53aa742aa05f6", - "host": "i686-mingw32", - "archiveFileName": "arduinoOTA-1.3.0-windows_386.zip", - "url": "http://downloads.arduino.cc/tools/arduinoOTA-1.3.0-windows_386.zip" - } - ] - }, - { - "name": "bossac", - "version": "1.5-arduino", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/bossac-1.5-arduino2-arm-linux-gnueabihf.tar.bz2", - "archiveFileName": "bossac-1.5-arduino2-arm-linux-gnueabihf.tar.bz2", - "checksum": "SHA-256:7b61b7814e5b57bcbd853439fc9cd3e98af4abfdd369bf039c6917f9599e44b9", - "size": "199550" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/bossac-1.5-arduino2-mingw32.tar.gz", - "archiveFileName": "bossac-1.5-arduino2-mingw32.tar.gz", - "checksum": "SHA-256:9d849a34f0b26c25c6a8c4d741cd749dea238cade73b57a3048f248c431d9cc9", - "size": "222283" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/bossac-1.5-arduino2-i386-apple-darwin14.3.0.tar.gz", - "archiveFileName": "bossac-1.5-arduino2-i386-apple-darwin14.3.0.tar.gz", - "checksum": "SHA-256:8f07e50a1f887cb254092034c6a4482d73209568cd83cb624d6625d66794f607", - "size": "64120" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/bossac-1.5-arduino2-x86_64-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.5-arduino2-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:42785329155dcb39872d4d30a2a9d31e0f0ce3ae7e34a3ed3d840cbc909c4657", - "size": "30431" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/bossac-1.5-arduino2-i486-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.5-arduino2-i486-linux-gnu.tar.gz", - "checksum": "SHA-256:ac56e553bbd6d992fa5592ace90996806230ab582f2bf9f8590836fec9dabef6", - "size": "29783" - } - ] - }, - { - "name": "bossac", - "version": "1.6-arduino", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/bossac-1.6-arduino-mingw32.tar.gz", - "archiveFileName": "bossac-1.6-arduino-mingw32.tar.gz", - "checksum": "SHA-256:b59d64d3f7a43c894d0fba2dd1241bbaeefedf8c902130a24d8ec63b08f9ff6a", - "size": "222517" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/bossac-1.6-arduino-i386-apple-darwin14.4.0.tar.gz", - "archiveFileName": "bossac-1.6-arduino-i386-apple-darwin14.4.0.tar.gz", - "checksum": "SHA-256:6b3b686a782b6587c64c85db80085c9089c5ea1b051e49e5af17b3c6109c8efa", - "size": "64538" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.6-arduino-x86_64-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.6-arduino-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:2ce7a54d609b4ce3b678147202b2556dd1ce5b318de48a018c676521b994c7a7", - "size": "30649" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.6-arduino-i486-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.6-arduino-i486-linux-gnu.tar.gz", - "checksum": "SHA-256:5c320bf5cfdbf03e3f648642e6de325e459a061fcf96b2215cb955263f7467b2", - "size": "30072" - } - ] - }, - { - "name": "bossac", - "version": "1.6.1-arduino", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/bossac-1.6.1-arduino-arm-linux-gnueabihf.tar.bz2", - "archiveFileName": "bossac-1.6.1-arduino-arm-linux-gnueabihf.tar.bz2", - "checksum": "SHA-256:8c4e63db982178919c824e7a35580dffc95c3426afa7285de3eb583982d4d391", - "size": "201341" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/bossac-1.6.1-arduino-mingw32.tar.gz", - "archiveFileName": "bossac-1.6.1-arduino-mingw32.tar.gz", - "checksum": "SHA-256:d59f43e2e83a337d04c4ae88b195a4ee175b8d87fff4c43144d23412a4a9513b", - "size": "222918" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/bossac-1.6.1-arduino-i386-apple-darwin14.5.0.tar.gz", - "archiveFileName": "bossac-1.6.1-arduino-i386-apple-darwin14.5.0.tar.gz", - "checksum": "SHA-256:2f80ef569a3fb19da60ab3489e49d8fe7d4699876acf30ff4938c632230a09aa", - "size": "64587" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/bossac-1.6.1-arduino-x86_64-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.6.1-arduino-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:b78afc66c00ccfdd69a08bd3959c260a0c64ccce78a71d5a1135ae4437ff40db", - "size": "30869" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/bossac-1.6.1-arduino-i486-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.6.1-arduino-i486-linux-gnu.tar.gz", - "checksum": "SHA-256:1e211347569d75193b337296a10dd25b0ce04419e3d7dc644355178b6b514f92", - "size": "30320" - } - ] - }, - { - "name": "bossac", - "version": "1.7.0", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-mingw32.tar.gz", - "archiveFileName": "bossac-1.7.0-mingw32.tar.gz", - "checksum": "SHA-256:9ef7d11b4fabca0adc17102a0290957d5cc26ce46b422c3a5344722c80acc7b2", - "size": "243066" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-i386-apple-darwin15.6.0.tar.gz", - "archiveFileName": "bossac-1.7.0-i386-apple-darwin15.6.0.tar.gz", - "checksum": "SHA-256:feac36ab38876c163dcf51bdbcfbed01554eede3d41c59a0e152e170fe5164d2", - "size": "63822" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-x86_64-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.7.0-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:9475c0c8596c1ba12dcbce60e48fef7559087fa8eccbea7bab732113f3c181ee", - "size": "31373" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-i686-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.7.0-i686-linux-gnu.tar.gz", - "checksum": "SHA-256:17003b0bdc698d52eeb91b09c34aec501c6e0285b4aa88659ab7cc407a451a4d", - "size": "31086" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arm-linux-gnueabihf.tar.gz", - "archiveFileName": "bossac-1.7.0-arm-linux-gnueabihf.tar.gz", - "checksum": "SHA-256:09e46d0af61b2189caaac0bc6d4dd15cb22c167fdedc56ec98602dd5f10e68e0", - "size": "27382" - } - ] - }, - { - "name": "bossac", - "version": "1.7.0-arduino3", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-windows.tar.gz", - "archiveFileName": "bossac-1.7.0-arduino3-windows.tar.gz", - "checksum": "SHA-256:62745cc5a98c26949ec9041ef20420643c561ec43e99dae659debf44e6836526", - "size": "3607421" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-osx.tar.gz", - "archiveFileName": "bossac-1.7.0-arduino3-osx.tar.gz", - "checksum": "SHA-256:adb3c14debd397d8135e9e970215c6972f0e592c7af7532fa15f9ce5e64b991f", - "size": "75510" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux64.tar.gz", - "archiveFileName": "bossac-1.7.0-arduino3-linux64.tar.gz", - "checksum": "SHA-256:1ae54999c1f97234a5c603eb99ad39313b11746a4ca517269a9285afa05f9100", - "size": "207271" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linux32.tar.gz", - "archiveFileName": "bossac-1.7.0-arduino3-linux32.tar.gz", - "checksum": "SHA-256:4ac4354746d1a09258f49a43ef4d1baf030d81c022f8434774268b00f55d3ec3", - "size": "193577" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linuxarm.tar.gz", - "archiveFileName": "bossac-1.7.0-arduino3-linuxarm.tar.gz", - "checksum": "SHA-256:626c6cc548046901143037b782bf019af1663bae0d78cf19181a876fb9abbb90", - "size": "193941" - }, - { - "host": "aarch64-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.7.0-arduino3-linuxaarch64.tar.gz", - "archiveFileName": "bossac-1.7.0-arduino3-linuxaarch64.tar.gz", - "checksum": "SHA-256:a098b2cc23e29f0dc468416210d097c4a808752cd5da1a7b9b8b7b931a04180b", - "size": "268365" - } - ] - }, - { - "name": "bossac", - "version": "1.8.0-48-gb176eee", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/bossac-1.8-48-gb176eee-i686-w64-mingw32.tar.gz", - "archiveFileName": "bossac-1.8-48-gb176eee-i686-w64-mingw32.tar.gz", - "checksum": "SHA-256:4523a6897f3dfd673fe821c5cfbac8d6a12782e7a36b312b9ee7d41deec2a10a", - "size": "91219" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/bossac-1.8-48-gb176eee-i386-apple-darwin16.1.0.tar.gz", - "archiveFileName": "bossac-1.8-48-gb176eee-i386-apple-darwin16.1.0.tar.gz", - "checksum": "SHA-256:581ecc16021de36638ae14e9e064ffb4a1d532a11502f4252da8bcdf5ce1d649", - "size": "39150" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.8-48-gb176eee-x86_64-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.8-48-gb176eee-x86_64-linux-gnu.tar.gz", - "checksum": "SHA-256:1347eec67f5b90b785abdf6c8a8aa59129d0c016de7ff9b5ac1690378eacca3c", - "size": "37798" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.8-48-gb176eee-i486-linux-gnu.tar.gz", - "archiveFileName": "bossac-1.8-48-gb176eee-i486-linux-gnu.tar.gz", - "checksum": "SHA-256:4c7492f876b8269aa9d8bcaad3aeda31acf1a0292383093b6d9f5f1d23fdafc3", - "size": "37374" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/bossac-1.8-48-gb176eee-arm-linux-gnueabihf.tar.gz", - "archiveFileName": "bossac-1.8-48-gb176eee-arm-linux-gnueabihf.tar.gz", - "checksum": "SHA-256:2001e4a592f3aefd22f213b1ddd6f5d8d5e74bd04080cf1b97c24cbaa81b10ed", - "size": "34825" - } - ] - }, - { - "name": "bossac", - "version": "1.9.1-arduino1", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino1-windows.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino1-windows.tar.gz", - "checksum": "SHA-256:fe2d6ef78ca711c78e104e258357ed06b09e95e9356dc72d8d2c9f6670af4b7a", - "size": "1260118" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino1-osx.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino1-osx.tar.gz", - "checksum": "SHA-256:c356632f98d5bae9b4f5d3ad823a5ee89b23078c2b835e8ac39a208f4855b0e6", - "size": "47835" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino1-linux64.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino1-linux64.tar.gz", - "checksum": "SHA-256:d3d324a3503a8db825c01f3b38519e4d4824c4d0e42cb399a16c1e074f9a9a86", - "size": "399453" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino1-linux32.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino1-linux32.tar.gz", - "checksum": "SHA-256:eec622b8b5a8642af94ec23febfe14c928edd734f144db73b146bf6708d2057f", - "size": "384792" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino1-linuxarm.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino1-linuxarm.tar.gz", - "checksum": "SHA-256:b42061d2fa2dbd6910d0d295e024f2cff7bb44f3e2ecc0bc2fe71a1f31b0ecba", - "size": "361799" - }, - { - "host": "aarch64-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino1-linuxaarch64.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino1-linuxaarch64.tar.gz", - "checksum": "SHA-256:b271013841e1e25ee55f241e8c50a56ed775d3b322844e1e3099231ba17f3868", - "size": "442657" - } - ] - }, - { - "name": "bossac", - "version": "1.9.1-arduino2", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino2-windows.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino2-windows.tar.gz", - "checksum": "SHA-256:5c994d04354f0db8e4bea136f49866d2ba537f0af74b2e78026f2d4fc75e3e39", - "size": "1260628" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino2-osx.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino2-osx.tar.gz", - "checksum": "SHA-256:b7732129364a378676604db6579c9b8dab50dd965fb50d7a3afff1839c97ff80", - "size": "47870" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino2-linux64.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino2-linux64.tar.gz", - "checksum": "SHA-256:9eb549874391521999cee13dc823a2cfc8866b8246945339a281808d99c72d2c", - "size": "399532" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino2-linux32.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino2-linux32.tar.gz", - "checksum": "SHA-256:10d69f53f169f25afee2dd583dfd9dc803c10543e6c5260d106725cb0d174900", - "size": "384951" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino2-linuxarm.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino2-linuxarm.tar.gz", - "checksum": "SHA-256:c9539d161d23231b5beb1d09a71829744216c7f5bc2857a491999c3e567f5b19", - "size": "361915" - }, - { - "host": "aarch64-linux-gnu", - "url": "http://downloads.arduino.cc/tools/bossac-1.9.1-arduino2-linuxaarch64.tar.gz", - "archiveFileName": "bossac-1.9.1-arduino2-linuxaarch64.tar.gz", - "checksum": "SHA-256:c167fa0ea223966f4d21f5592da3888bcbfbae385be6c5c4e41f8abff35f5cb1", - "size": "442853" - } - ] - }, - { - "name": "openocd", - "version": "0.9.0-arduino", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/OpenOCD-0.9.0-arduino-arm-linux-gnueabihf.tar.bz2", - "archiveFileName": "OpenOCD-0.9.0-dev-arduino-arm-linux-gnueabihf.tar.bz2", - "checksum": "SHA-256:a84e7c4cba853f2c937d77286f8a0ca317447d3873e51cbd2a2d41424e044a18", - "size": "1402283" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/OpenOCD-0.9.0-arduino-i686-pc-cygwin.tar.bz2", - "archiveFileName": "OpenOCD-0.9.0-arduino-i686-pc-cygwin.tar.bz2", - "checksum": "SHA-256:5310bdd3730168a33b09b68558e908ca8b2fec25620c488f50a5fb35d0d1effd", - "size": "2360705" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/OpenOCD-0.9.0-arduino-x86_64-apple-darwin14.3.0.tar.bz2", - "archiveFileName": "OpenOCD-0.9.0-arduino-x86_64-apple-darwin14.3.0.tar.bz2", - "checksum": "SHA-256:ef90769c07b8018cec3a5054e690ac6c196e03720e102ac5038c3f9da4e44782", - "size": "2275101" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/OpenOCD-0.9.0-arduino-x86_64-linux-gnu.tar.bz2", - "archiveFileName": "OpenOCD-0.9.0-arduino-x86_64-linux-gnu.tar.bz2", - "checksum": "SHA-256:c350409f7badf213dfcc516ea34289461ad92d87806e8e33945508a2c6b2c0b3", - "size": "1210796" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/OpenOCD-0.9.0-arduino-i486-linux-gnu.tar.bz2", - "archiveFileName": "OpenOCD-0.9.0-arduino-i486-linux-gnu.tar.bz2", - "checksum": "SHA-256:4c9793dfd7822b0fc959d039e5ecabfa89092ee2911abfdc7b5905deb171499a", - "size": "1129654" - } - ] - }, - { - "name": "openocd", - "version": "0.9.0-arduino5-static", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino5-static-arm-linux-gnueabihf.tar.bz2", - "archiveFileName": "openocd-0.9.0-arduino5-static-arm-linux-gnueabihf.tar.bz2", - "checksum": "SHA-256:cef48c1448664612dd25168f0a56962aec4ce2f1d7c06dafd86a1b606dc8ae20", - "size": "1319000" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino5-static-i686-w64-mingw32.zip", - "archiveFileName": "openocd-0.9.0-arduino5-static-i686-w64-mingw32.zip", - "checksum": "SHA-256:54c70a0bfa1b0a3a592d6ee9ab532f9715e1dede2e7d46a3232abd72de274c5a", - "size": "1641209" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino5-static-x86_64-apple-darwin15.6.0.tar.bz2", - "archiveFileName": "openocd-0.9.0-arduino5-static-x86_64-apple-darwin15.6.0.tar.bz2", - "checksum": "SHA-256:14be5c5400e1a32c3d6a15f9c8d2f438634974ab263ff437b91b527e5b5d53a4", - "size": "1235752" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino5-static-x86_64-linux-gnu.tar.bz2", - "archiveFileName": "openocd-0.9.0-arduino5-static-x86_64-linux-gnu.tar.bz2", - "checksum": "SHA-256:8e378bdcd71c93a39818c16b49b91128c8028e3d9675551ba7eff39462391ba2", - "size": "1393855" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino5-static-i686-linux-gnu.tar.bz2", - "archiveFileName": "openocd-0.9.0-arduino5-static-i686-linux-gnu.tar.bz2", - "checksum": "SHA-256:8e0787f54e204fe6e9071b2b7edf8a5e695492696f1182d447647fe5c0bd55bd", - "size": "1341739" - } - ] - }, - { - "name": "openocd", - "version": "0.9.0-arduino6-static", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino6-static-arm-linux-gnueabihf.tar.bz2", - "archiveFileName": "openocd-0.9.0-arduino6-static-arm-linux-gnueabihf.tar.bz2", - "checksum": "SHA-256:5d596c90510f80d66f64a3615d74063a6a61f07b79be475592a3c76bf0deb3ca", - "size": "1319020" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino6-static-i686-w64-mingw32.zip", - "archiveFileName": "openocd-0.9.0-arduino6-static-i686-w64-mingw32.zip", - "checksum": "SHA-256:dde6c8cd42c179e819eeebee1d09829b0768ecb89b75fb10e1f053c1c65f9cf1", - "size": "1641514" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino6-static-x86_64-apple-darwin15.6.0.tar.bz2", - "archiveFileName": "openocd-0.9.0-arduino6-static-x86_64-apple-darwin15.6.0.tar.bz2", - "checksum": "SHA-256:00cd65339bc981ff0d4ab4876df8f89b1e60e476441fabca31d5fc2968bad9be", - "size": "1222523" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino6-static-x86_64-linux-gnu.tar.bz2", - "archiveFileName": "openocd-0.9.0-arduino6-static-x86_64-linux-gnu.tar.bz2", - "checksum": "SHA-256:d2f58bbd0661b755fdb8a307d197f119d838b066f5510b25ee766e47d1774543", - "size": "1394293" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/openocd-0.9.0-arduino6-static-i686-linux-gnu.tar.bz2", - "archiveFileName": "openocd-0.9.0-arduino6-static-i686-linux-gnu.tar.bz2", - "checksum": "SHA-256:88d948c2062c73c0c93e649e099aaac4b009018cff365f44cfc5b47907043dc9", - "size": "1340444" - } - ] - }, - { - "name": "openocd", - "version": "0.10.0-arduino7", - "systems": [ - { - "size": "1638575", - "checksum": "SHA-256:f8e0d783e80a3d5f75ee82e9542315871d46e1e283a97447735f1cbcd8986b06", - "host": "arm-linux-gnueabihf", - "archiveFileName": "openocd-0.10.0-arduino7-static-arm-linux-gnueabihf.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-arm-linux-gnueabihf.tar.bz2" - }, - { - "size": "1580739", - "checksum": "SHA-256:d47d728a9a8d98f28dc22e31d7127ced9de0d5e268292bf935e050ef1d2bdfd0", - "host": "aarch64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino7-static-aarch64-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-aarch64-linux-gnu.tar.bz2" - }, - { - "size": "1498970", - "checksum": "SHA-256:1e539a587a0c54a551ce0dc542af10a2520b1c93bbfe2ca4ebaef4c83411df1a", - "host": "i386-apple-darwin11", - "archiveFileName": "openocd-0.10.0-arduino7-static-x86_64-apple-darwin13.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-x86_64-apple-darwin13.tar.bz2" - }, - { - "size": "1701581", - "checksum": "SHA-256:91d418bd309ec1e98795c622cd25c936aa537c0b3828fa5bcb191389378a1b27", - "host": "x86_64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino7-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2" - }, - { - "size": "1626347", - "checksum": "SHA-256:08a18f39d72a5626383503053a30a5da89eed7fdccb6f514b20b77403eb1b2b4", - "host": "i686-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino7-static-i686-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-i686-ubuntu12.04-linux-gnu.tar.bz2" - }, - { - "size": "2016965", - "checksum": "SHA-256:f251aec5471296e18aa540c3078d66475357a76a77c16c06a2d9345f4e12b3d5", - "host": "i686-mingw32", - "archiveFileName": "openocd-0.10.0-arduino7-static-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino7-static-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "openocd", - "version": "0.10.0-arduino8", - "systems": [ - { - "size": "1714346", - "checksum": "SHA-256:86c4ea3086b4a1475fd8a1e1daf4585748be093dad4160e816b1bf2502501fb2", - "host": "arm-linux-gnueabihf", - "archiveFileName": "openocd-0.10.0-arduino8-static-arm-linux-gnueabihf.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino8-static-arm-linux-gnueabihf.tar.bz2" - }, - { - "size": "1778371", - "checksum": "SHA-256:500cb112ee92092bbfce69649b90d0284752c5766f5aaf5c24dc754100788ef9", - "host": "aarch64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino8-static-aarch64-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino8-static-aarch64-linux-gnu.tar.bz2" - }, - { - "size": "1653652", - "checksum": "SHA-256:584b513ebbc4a645a68234d964ba56f042aaf7668d84ba47398a07a294516cc4", - "host": "i386-apple-darwin11", - "archiveFileName": "openocd-0.10.0-arduino8-static-x86_64-apple-darwin13.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino8-static-x86_64-apple-darwin13.tar.bz2" - }, - { - "size": "1845547", - "checksum": "SHA-256:455d4123146bf6b4b095de86d3340fd01e39bba9c70b2f0bb8e979ac4dddac39", - "host": "x86_64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino8-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino8-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2" - }, - { - "size": "1781892", - "checksum": "SHA-256:5b44889984daefa966b8251edb98445169107ca32f974ca598d4c59e7d2c8901", - "host": "i686-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino8-static-i686-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino8-static-i686-ubuntu12.04-linux-gnu.tar.bz2" - }, - { - "size": "2190397", - "checksum": "SHA-256:35a92f32f2762ef9405d2c684ec7bea2e70c01068f380251aecd9290f5bd5b24", - "host": "i686-mingw32", - "archiveFileName": "openocd-0.10.0-arduino8-static-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino8-static-i686-w64-mingw32.zip" - } - ] - }, - { - "name": "openocd", - "version": "0.10.0-arduino9", - "systems": [ - { - "size": "1714657", - "checksum": "SHA-256:b814b16b52cef21eacf456cc7a89d7b5d4cb1385bfb8fb82963b7d8151824d93", - "host": "aarch64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino9-static-aarch64-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino9-static-aarch64-linux-gnu.tar.bz2" - }, - { - "size": "1778177", - "checksum": "SHA-256:f0443e771f5e3a779949498d3c9bfffd1dd27cdf0ad7136a2db5e80447a7175a", - "host": "arm-linux-gnueabihf", - "archiveFileName": "openocd-0.10.0-arduino9-static-arm-linux-gnueabihf.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino9-static-arm-linux-gnueabihf.tar.bz2" - }, - { - "size": "1782958", - "checksum": "SHA-256:a22872918df899cb808f9286141d42438ae5611156c143cfb692069f52a2bddd", - "host": "i686-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino9-static-i686-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino9-static-i686-ubuntu12.04-linux-gnu.tar.bz2" - }, - { - "size": "2190484", - "checksum": "SHA-256:f53f9a2b7f48a2ebc00ea9196bf559d15987d3779bcea4118ebec8925da5a1f6", - "host": "i686-mingw32", - "archiveFileName": "openocd-0.10.0-arduino9-static-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino9-static-i686-w64-mingw32.zip" - }, - { - "size": "1655311", - "checksum": "SHA-256:6d47f97919f317bb6e5f1f903127604271d66d149f4625f29b8e0eb5f6c94c64", - "host": "i386-apple-darwin11", - "archiveFileName": "openocd-0.10.0-arduino9-static-x86_64-apple-darwin13.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino9-static-x86_64-apple-darwin13.tar.bz2" - }, - { - "size": "1844365", - "checksum": "SHA-256:f624552b5ba56aa78d0c1a0e5d18cf2b5694db2ed44080968e22aa1af8f23c1b", - "host": "x86_64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino9-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino9-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2" - } - ] - }, - { - "name": "openocd", - "version": "0.10.0-arduino12", - "systems": [ - { - "size": "1778706", - "checksum": "SHA-256:86e15186a44b87c00f5ddd9c05849d2ec107783dd18a5ac984ce2a71e34084ed", - "host": "aarch64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino12-static-aarch64-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino12-static-aarch64-linux-gnu.tar.bz2" - }, - { - "size": "1855234", - "checksum": "SHA-256:5c6ca6189f61894ee77b29bc342f96cd14e4d7627fabeb2a8d2e2c534316cc38", - "host": "arm-linux-gnueabihf", - "archiveFileName": "openocd-0.10.0-arduino12-static-arm-linux-gnueabihf.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino12-static-arm-linux-gnueabihf.tar.bz2" - }, - { - "size": "1844359", - "checksum": "SHA-256:4938742d3fec62941187666b8ded44d8f6c7a404920ff49d97fca484b9fd08af", - "host": "i686-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino12-static-i686-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino12-static-i686-ubuntu12.04-linux-gnu.tar.bz2" - }, - { - "size": "2276602", - "checksum": "SHA-256:1e23c0f1f809725db3e1f8d1e1f460a37fb7b2cf95e93c6e328e527501ab084c", - "host": "i686-mingw32", - "archiveFileName": "openocd-0.10.0-arduino12-static-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino12-static-i686-w64-mingw32.zip" - }, - { - "size": "1723600", - "checksum": "SHA-256:b40d135449401870302bec073326d6f1df79da38d9dd21326314a5a90189a06e", - "host": "i386-apple-darwin11", - "archiveFileName": "openocd-0.10.0-arduino12-static-x86_64-apple-darwin13.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino12-static-x86_64-apple-darwin13.tar.bz2" - }, - { - "size": "1918845", - "checksum": "SHA-256:bc48be10916f69f3a4b050f04babc14ee99dad1fc5da55ce606077991edab1d0", - "host": "x86_64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino12-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino12-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2" - } - ] - }, - { - "name": "openocd", - "version": "0.10.0-arduino13", - "systems": [ - { - "size": "1820630", - "checksum": "SHA-256:47ae7a1a7961ac9daef001b011505b38777baac3c02dd7e673f62601df841427", - "host": "aarch64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino13-static-aarch64-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino13-static-aarch64-linux-gnu.tar.bz2" - }, - { - "size": "1896478", - "checksum": "SHA-256:4dd38b701019ad2fbb58173a3bc6c58effd39501a4a8266256dfe169e7516655", - "host": "arm-linux-gnueabihf", - "archiveFileName": "openocd-0.10.0-arduino13-static-arm-linux-gnueabihf.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino13-static-arm-linux-gnueabihf.tar.bz2" - }, - { - "size": "1883854", - "checksum": "SHA-256:788093504b25d2b9b772657215254ba178ed37773364ce240de68281efe40bd5", - "host": "i686-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino13-static-i686-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino13-static-i686-ubuntu12.04-linux-gnu.tar.bz2" - }, - { - "size": "2334654", - "checksum": "SHA-256:2f3b87c644569f47780b16b071cd0929a64a8899ec769f4ca7480d20d5503365", - "host": "i686-mingw32", - "archiveFileName": "openocd-0.10.0-arduino13-static-i686-w64-mingw32.zip", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino13-static-i686-w64-mingw32.zip" - }, - { - "size": "1767137", - "checksum": "SHA-256:0f3f6e5e03355ffbbc84c4b4750e63c9315b7638c56d63df1b7795968208e6ba", - "host": "i386-apple-darwin11", - "archiveFileName": "openocd-0.10.0-arduino13-static-x86_64-apple-darwin13.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino13-static-x86_64-apple-darwin13.tar.bz2" - }, - { - "size": "1955043", - "checksum": "SHA-256:e4b2ffbc9a29be21c32c6921c2e7c0ee39c664c4faca28a5f839c1df32d3bd24", - "host": "x86_64-linux-gnu", - "archiveFileName": "openocd-0.10.0-arduino13-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2", - "url": "http://downloads.arduino.cc/tools/openocd-0.10.0-arduino13-static-x86_64-ubuntu12.04-linux-gnu.tar.bz2" - } - ] - }, - { - "name": "CMSIS", - "version": "4.0.0-atmel", - "systems": [ - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/CMSIS-4.0.0.tar.bz2", - "archiveFileName": "CMSIS-4.0.0.tar.bz2", - "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", - "size": "17642623" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/CMSIS-4.0.0.tar.bz2", - "archiveFileName": "CMSIS-4.0.0.tar.bz2", - "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", - "size": "17642623" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/CMSIS-4.0.0.tar.bz2", - "archiveFileName": "CMSIS-4.0.0.tar.bz2", - "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", - "size": "17642623" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-4.0.0.tar.bz2", - "archiveFileName": "CMSIS-4.0.0.tar.bz2", - "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", - "size": "17642623" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-4.0.0.tar.bz2", - "archiveFileName": "CMSIS-4.0.0.tar.bz2", - "checksum": "SHA-256:7d637d2d7a0c6bacc22065848a201db2fff124268e4a56868260d0f472b4bbb7", - "size": "17642623" - } - ] - }, - { - "name": "CMSIS", - "version": "4.5.0", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2", - "archiveFileName": "CMSIS-4.5.0.tar.bz2", - "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d", - "size": "31525196" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2", - "archiveFileName": "CMSIS-4.5.0.tar.bz2", - "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d", - "size": "31525196" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2", - "archiveFileName": "CMSIS-4.5.0.tar.bz2", - "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d", - "size": "31525196" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2", - "archiveFileName": "CMSIS-4.5.0.tar.bz2", - "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d", - "size": "31525196" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2", - "archiveFileName": "CMSIS-4.5.0.tar.bz2", - "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d", - "size": "31525196" - }, - { - "host": "aarch64-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2", - "archiveFileName": "CMSIS-4.5.0.tar.bz2", - "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d", - "size": "31525196" - }, - { - "host": "all", - "url": "http://downloads.arduino.cc/CMSIS-4.5.0.tar.bz2", - "archiveFileName": "CMSIS-4.5.0.tar.bz2", - "checksum": "SHA-256:cd8f7eae9fc7c8b4a1b5e40b89b9666d33953b47d3d2eb81844f5af729fa224d", - "size": "31525196" - } - ] - }, - { - "name": "CMSIS-Atmel", - "version": "1.0.0", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.0.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.0.0.tar.bz2", - "checksum": "SHA-256:b3c954570a2f8d9821c372e0864f5f0b86cfbeab8114ce95821f5c49758c7256", - "size": "1281654" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.0.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.0.0.tar.bz2", - "checksum": "SHA-256:b3c954570a2f8d9821c372e0864f5f0b86cfbeab8114ce95821f5c49758c7256", - "size": "1281654" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.0.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.0.0.tar.bz2", - "checksum": "SHA-256:b3c954570a2f8d9821c372e0864f5f0b86cfbeab8114ce95821f5c49758c7256", - "size": "1281654" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.0.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.0.0.tar.bz2", - "checksum": "SHA-256:b3c954570a2f8d9821c372e0864f5f0b86cfbeab8114ce95821f5c49758c7256", - "size": "1281654" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.0.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.0.0.tar.bz2", - "checksum": "SHA-256:b3c954570a2f8d9821c372e0864f5f0b86cfbeab8114ce95821f5c49758c7256", - "size": "1281654" - }, - { - "host": "all", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.0.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.0.0.tar.bz2", - "checksum": "SHA-256:b3c954570a2f8d9821c372e0864f5f0b86cfbeab8114ce95821f5c49758c7256", - "size": "1281654" - } - ] - }, - { - "name": "CMSIS-Atmel", - "version": "1.1.0", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.1.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.1.0.tar.bz2", - "checksum": "SHA-256:3ea5ec0451f42dc2b97f869b027a9cf696241cfc927cfc48d74ccc7b396ba41b", - "size": "1659108" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.1.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.1.0.tar.bz2", - "checksum": "SHA-256:3ea5ec0451f42dc2b97f869b027a9cf696241cfc927cfc48d74ccc7b396ba41b", - "size": "1659108" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.1.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.1.0.tar.bz2", - "checksum": "SHA-256:3ea5ec0451f42dc2b97f869b027a9cf696241cfc927cfc48d74ccc7b396ba41b", - "size": "1659108" - }, - { - "host": "i686-pc-linux-gnu", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.1.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.1.0.tar.bz2", - "checksum": "SHA-256:3ea5ec0451f42dc2b97f869b027a9cf696241cfc927cfc48d74ccc7b396ba41b", - "size": "1659108" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.1.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.1.0.tar.bz2", - "checksum": "SHA-256:3ea5ec0451f42dc2b97f869b027a9cf696241cfc927cfc48d74ccc7b396ba41b", - "size": "1659108" - }, - { - "host": "all", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.1.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.1.0.tar.bz2", - "checksum": "SHA-256:3ea5ec0451f42dc2b97f869b027a9cf696241cfc927cfc48d74ccc7b396ba41b", - "size": "1659108" - } - ] - }, - { - "name": "CMSIS-Atmel", - "version": "1.2.0", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2", - "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5", - "size": "2221805" - }, - { - "host": "x86_64-apple-darwin", - "url": "http://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2", - "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5", - "size": "2221805" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2", - "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5", - "size": "2221805" - }, - { - "host": "i686-pc-linux-gnu", - "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2", - "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5", - "size": "2221805" - }, - { - "host": "arm-linux-gnueabihf", - "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2", - "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5", - "size": "2221805" - }, - { - "host": "aarch64-linux-gnu", - "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2", - "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5", - "size": "2221805" - }, - { - "host": "all", - "url": "https://downloads.arduino.cc/CMSIS-Atmel-1.2.0.tar.bz2", - "archiveFileName": "CMSIS-Atmel-1.2.0.tar.bz2", - "checksum": "SHA-256:5e02670be7e36be9691d059bee0b04ee8b249404687531f33893922d116b19a5", - "size": "2221805" - } - ] - }, - { - "name": "dfu-util", - "version": "0.9.0-arduino1", - "systems": [ - { - "host": "i386-apple-darwin11", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino1-osx.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino1-osx.tar.bz2", - "size": "68361", - "checksum": "SHA-256:ea9216c627b7aa2d3a9bffab97df937e3c580cce66753c428dc697c854a35271" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino1-arm.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino1-arm.tar.bz2", - "size": "194826", - "checksum": "SHA-256:480637bf578e74b19753666a049f267d8ebcd9dfc8660d48f246bb76d5b806f9" - }, - { - "host": "x86_64-linux-gnu", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino1-linux64.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino1-linux64.tar.bz2", - "size": "66230", - "checksum": "SHA-256:e8a4d5477ab8c44d8528f35bc7dfafa5f3f04dace513906514aea31adc6fd3ba" - }, - { - "host": "i686-linux-gnu", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino1-linux32.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino1-linux32.tar.bz2", - "size": "62608", - "checksum": "SHA-256:17d69213914da04dadd6464d8adbcd3581dd930eb666b8f3336ab5383ce2127f" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino1-windows.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino1-windows.tar.bz2", - "size": "377537", - "checksum": "SHA-256:29be01b298348be8b822391be7147b71a969d47bd5457d5b24cfa5981dbce78e" - } - ] - }, - { - "name": "dfu-util", - "version": "0.9.0-arduino2", - "systems": [ - { - "host": "i386-apple-darwin11", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino2-osx.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino2-osx.tar.bz2", - "size": "65137", - "checksum": "SHA-256:00e87178b81d5721f334d4b688267f19f36eed1d9710a912c9e44bb1a748f766" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino2-arm.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino2-arm.tar.bz2", - "size": "198568", - "checksum": "SHA-256:b364a8fe1de697d7dd6c4135d341ddff6dbda7e33c707321c7dceab85dfc560b" - }, - { - "host": "x86_64-linux-gnu", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino2-linux64.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino2-linux64.tar.bz2", - "size": "70996", - "checksum": "SHA-256:628e01772007e622dff6af82220c27bcdf1d0726ba886bd2b36807601f66e4e8" - }, - { - "host": "i686-linux-gnu", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino2-linux32.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino2-linux32.tar.bz2", - "size": "71002", - "checksum": "SHA-256:7a6cec3d89c65119c52b6109cd92a9ec84bdf8a9d12083444d2c89e7ac16c84b" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/dfu-util-0.9.0-arduino2-windows.tar.bz2", - "archiveFileName": "dfu-util-0.9.0-arduino2-windows.tar.bz2", - "size": "394993", - "checksum": "SHA-256:8ec0e66acdc41941b6e25545f8c12e7eb7ba01a0bafae0b4ab4c99a70deb2ea5" - } - ] - }, - { - "name": "windows-drivers", - "version": "1.6.9", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/drivers-arduino-windows-1.6.9.zip", - "archiveFileName": "drivers-arduino-windows-1.6.9.zip", - "checksum": "SHA-256:10d456ab18d164d42545255db8bef4ac9e1bf660cc89acb7a0980b5a486654ac", - "size": "7071714" - } - ] - }, - { - "name": "windows-drivers", - "version": "1.8.0", - "systems": [ - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/drivers-arduino-windows-1.8.0.zip", - "archiveFileName": "drivers-arduino-windows-1.8.0.zip", - "checksum": "SHA-256:60614b326ad6860ed0cb99eb4cb2cb69f9ba6ba3784396d5441fe3f99004f8ec", - "size": "16302148" - } - ] - }, - { - "name": "dfu-util", - "version": "0.8.0-stm32-arduino1", - "systems": [ - { - "archiveFileName": "dfu-util-0.8.0-stm32-arduino1-darwin_amd64.tar.bz2", - "checksum": "SHA-256:bb146803a4152ce2647d72b2cde68ff95eb3017c2460f24c4db922adac1fbd12", - "host": "i386-apple-darwin11", - "size": "68381", - "url": "http://downloads.arduino.cc/arduino.org/dfu-util-0.8.0-stm32-arduino1-darwin_amd64.tar.bz2" - }, - { - "archiveFileName": "dfu-util-0.8.0-stm32-arduino1-linux_arm.tar.bz2", - "checksum": "SHA-256:607e6b0f2d2787ed7837f26da30b100131e3db207f84b8aca94a377db6e9ae50", - "host": "arm-linux-gnueabihf", - "size": "213760", - "url": "http://downloads.arduino.cc/arduino.org/dfu-util-0.8.0-stm32-arduino1-linux_arm.tar.bz2" - }, - { - "archiveFileName": "dfu-util-0.8.0-stm32-arduino1-stm32-linux_amd64.tar.bz2", - "checksum": "SHA-256:e44287494ebd22f59fc79766a94e20306e59c6c799f5bb1cddeed80db95000d9", - "host": "x86_64-linux-gnu", - "size": "68575", - "url": "http://downloads.arduino.cc/arduino.org/dfu-util-0.8.0-stm32-arduino1-linux_amd64.tar.bz2" - }, - { - "archiveFileName": "dfu-util-0.8.0-stm32-arduino1-linux_386.tar.bz2", - "checksum": "SHA-256:58131e35ad5d7053b281bc6176face7b117c5ad63331e43c6801f8ccd57f59a4", - "host": "i686-linux-gnu", - "size": "69097", - "url": "http://downloads.arduino.cc/arduino.org/dfu-util-0.8.0-stm32-arduino1-linux_386.tar.bz2" - }, - { - "archiveFileName": "dfu-util-0.8.0-stm32-arduino1-windows_386.tar.bz2", - "checksum": "SHA-256:25c2f84e1acf1f10fd2aa1afced441366d4545fd41eae56e64f0b990b4ce9f55", - "host": "i686-mingw32", - "size": "159753", - "url": "http://downloads.arduino.cc/arduino.org/dfu-util-0.8.0-stm32-arduino1-windows_386.tar.bz2" - } - ] - }, - { - "name": "arduinoSTM32load", - "version": "2.0.0", - "systems": [ - { - "archiveFileName": "arduinoSTM32load-2.0.0-darwin_amd64.tar.bz2", - "checksum": "SHA-256:92fb9714091850febaa9d159501cbca5ba68d03020e5e2d4eff596154040bfaa", - "host": "i386-apple-darwin11", - "size": "807514", - "url": "http://downloads.arduino.cc/arduino.org/arduinoSTM32load-2.0.0-darwin_amd64.tar.bz2" - }, - { - "archiveFileName": "arduinoSTM32load-2.0.0-linux_arm.tar.bz2", - "checksum": "SHA-256:fc0d8058b57bda849e1ffc849f83f54b0b85f97954176db317da1c745c174e08", - "host": "arm-linux-gnueabihf", - "size": "809480", - "url": "http://downloads.arduino.cc/arduino.org/arduinoSTM32load-2.0.0-linux_arm.tar.bz2" - }, - { - "archiveFileName": "arduinoSTM32load-2.0.0-linux_amd64.tar.bz2", - "checksum": "SHA-256:0ed5cf1ea05fe6c33567817c54daf9c296d058a3607c428e0b0bd9aad89b9809", - "host": "x86_64-linux-gnu", - "size": "818885", - "url": "http://downloads.arduino.cc/arduino.org/arduinoSTM32load-2.0.0-linux_amd64.tar.bz2" - }, - { - "archiveFileName": "arduinoSTM32load-2.0.0-linux_386.tar.bz2", - "checksum": "SHA-256:fad50abaaca034e6d647d09b042291b761982aabfd42b6156411c86e4f873ca7", - "host": "i686-linux-gnu", - "size": "814283", - "url": "http://downloads.arduino.cc/arduino.org/arduinoSTM32load-2.0.0-linux_386.tar.bz2" - }, - { - "archiveFileName": "arduinoSTM32load-2.0.0-windows_386.tar.bz2", - "checksum": "SHA-256:79467c0cde4b88c4884acb09445a2186af4e41f901eee56e99b5d89b7065d085", - "host": "i686-mingw32", - "size": "786335", - "url": "http://downloads.arduino.cc/arduino.org/arduinoSTM32load-2.0.0-windows_386.tar.bz2" - } - ] - }, - { - "name": "openocd", - "version": "0.10.0-arduino1-static", - "systems": [ - { - "host": "i386-apple-darwin11", - "url": "http://downloads.arduino.cc/arduino.org/OpenOCD-0.10.0-nrf52-osx-static.tar.gz", - "archiveFileName": "OpenOCD-0.10.0-nrf52-osx-static.tar.gz", - "size": "1529841", - "checksum": "SHA-256:46bd02c1d42c5d94c4936e4d4a0ff29697b621840be9a6f882e316203122049d" - }, - { - "host": "x86_64-linux-gnu", - "url": "http://downloads.arduino.cc/arduino.org/OpenOCD-0.10.0-nrf52-linux64-static.tar.gz", - "archiveFileName": "OpenOCD-0.10.0-nrf52-linux64-static.tar.gz", - "size": "1777984", - "checksum": "SHA-256:1c9ae77930dd7377d8c13f84abe7307b67fdcd6da74cc1ce269a79e138e7a00a" - }, - { - "host": "i686-linux-gnu", - "url": "http://downloads.arduino.cc/arduino.org/OpenOCD-0.10.0-nrf52-linux32-static.tar.gz", - "archiveFileName": "OpenOCD-0.10.0-nrf52-linux32-static.tar.gz", - "size": "1713236", - "checksum": "SHA-256:777371df34828810e1bea623b0f7c98f28fedf30fd3bc8e7d8f0a5745fb4e258" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/arduino.org/OpenOCD-0.10.0-nrf52-win32-static.zip", - "archiveFileName": "OpenOCD-0.10.0-nrf52-win32-static.zip", - "size": "1773642", - "checksum": "SHA-256:9371b25d000bd589c058a5bf10720617adb91fd8b8a21d2e887cf45eaa2df93c" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/arduino.org/OpenOCD-0.10.0-nrf52-arm-static.tar.gz", - "archiveFileName": "OpenOCD-0.10.0-nrf52-arm-static.tar.gz", - "size": "1526863", - "checksum": "SHA-256:b5172422077f87ff05b76ff40034979678c9c640e9d08cee15ce55e40dd8c929" - } - ] - }, - { - "name": "fwupdater", - "version": "0.0.6", - "systems": [ - { - "host": "i686-linux-gnu", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.6-linux32.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.6-linux32.tar.bz2", - "checksum": "SHA-256:8c4e562a8e6fa3d916c4bf6bb24d7eec0df013d8cc45dff187e5c63086a92c11", - "size": "7334059" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.6-linux64.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.6-linux64.tar.bz2", - "checksum": "SHA-256:0e9132518acfe66e5a4e17ba4b6dd0c89dbd90cc0d9b4a54e007ac24d51fd36a", - "size": "7383853" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.6-windows.zip", - "archiveFileName": "FirmwareUpdater-0.0.6-windows.zip", - "checksum": "SHA-256:33a92661f43b8d025ca5f57be1116537ed153703067d9c86297619d58988feff", - "size": "7580663" - }, - { - "host": "i386-apple-darwin11", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.6-osx.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.6-osx.tar.bz2", - "checksum": "SHA-256:3584d7581ff2469bdfde9de6f57d87b2a0370de5c902e9df687b7322a5405018", - "size": "7368819" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.6-linuxarm.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.6-linuxarm.tar.bz2", - "checksum": "SHA-256:276f027e552eb620064b09591c7a7c79927c93c017428436c81f71bad666803c", - "size": "7180391" - }, - { - "host": "aarch64-linux-gnu", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.6-linuxarm64.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.6-linuxarm64.tar.bz2", - "checksum": "SHA-256:d6a2e72b4869c031b434380da6e6a8a4a6269f8ee6312a3d23e85ea133a37ae9", - "size": "7149332" - } - ] - }, - { - "name": "fwupdater", - "version": "0.0.7", - "systems": [ - { - "host": "i686-linux-gnu", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.7-linux32.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.7-linux32.tar.bz2", - "checksum": "SHA-256:05e26d5df253246cf68ba8a8f5f2de1032ac6f4d7af5310b8080ef6f54030fb4", - "size": "13077590" - }, - { - "host": "x86_64-pc-linux-gnu", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.7-linux64.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.7-linux64.tar.bz2", - "checksum": "SHA-256:e8a36b7ae19060748b8b0540c9c0c9341d8d4c7a630441922a030223f767258d", - "size": "13134534" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.7-windows.zip", - "archiveFileName": "FirmwareUpdater-0.0.7-windows.zip", - "checksum": "SHA-256:e881dd8a4bbb35f7271157e8dd226c2e032ac1115106170b0aaf9c969817df86", - "size": "13337495" - }, - { - "host": "i386-apple-darwin11", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.7-osx.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.7-osx.tar.bz2", - "checksum": "SHA-256:647ad713d68a1531ba56c88e5b3db9516cc0072ca1d401de5142d85ffcfd931a", - "size": "13064291" - }, - { - "host": "arm-linux-gnueabihf", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.7-linuxarm.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.7-linuxarm.tar.bz2", - "checksum": "SHA-256:b6e09c07e816a35935585db07e07437023d44e66d1d2f05861708ea6ceff7629", - "size": "12929770" - }, - { - "host": "aarch64-linux-gnu", - "url": "http://downloads.arduino.cc/tools/FirmwareUpdater-0.0.7-linuxarm64.tar.bz2", - "archiveFileName": "FirmwareUpdater-0.0.7-linuxarm64.tar.bz2", - "checksum": "SHA-256:620f81148b13f70cdecbe59bbcbf605c7e0aae85f9cbee8ec48202f6018f23ce", - "size": "12897349" - } - ] - }, - { - "name": "nrf5x-cl-tools", - "version": "9.3.1", - "systems": [ - { - "host": "i386-apple-darwin11", - "url": "http://downloads.arduino.cc/arduino.org/nRF5x-Command-Line-Tools_9_3_1_OSX.tar.bz2", - "archiveFileName": "nRF5x-Command-Line-Tools_9_3_1_OSX.tar.bz2", - "size": "341674", - "checksum": "SHA-256:41e4580271b39459a7ef1b078d11ee08d8f4f23fab7ff03f3fe8c3bc986a0ed4" - }, - { - "host": "x86_64-linux-gnu", - "url": "http://downloads.arduino.cc/arduino.org/nRF5x-Command-Line-Tools_9_3_1_Linux-x86_64.tar.bz2", - "archiveFileName": "nRF5x-Command-Line-Tools_9_3_1_Linux-x86_64.tar.bz2", - "size": "167414", - "checksum": "SHA-256:4074fffe678d60968006a72edd182c6506b264472c9957bc3eaa39336bfcf972" - }, - { - "host": "i686-linux-gnu", - "url": "http://downloads.arduino.cc/arduino.org/nRF5x-Command-Line-Tools_9_3_1_Linux-i386.tar.bz2", - "archiveFileName": "nRF5x-Command-Line-Tools_9_3_1_Linux-i386.tar.bz2", - "size": "155680", - "checksum": "SHA-256:e880059b303e5aad3a8b34c83dfd8c22beee77ae2074fbd37511e3baa91464a5" - }, - { - "host": "i686-mingw32", - "url": "http://downloads.arduino.cc/arduino.org/nRF5x-Command-Line-Tools_9_3_1_Win32.tar.bz2", - "archiveFileName": "nRF5x-Command-Line-Tools_9_3_1_Win32.tar.bz2", - "size": "812257", - "checksum": "SHA-256:a4467350e39314690cec2e96b80e7e3cab463c84eff9b81593ad57754d76ee00" - } - ] - } - ] - } - ] -} diff --git a/commands/service.go b/commands/service.go index 356c595baef..7121ab48be2 100644 --- a/commands/service.go +++ b/commands/service.go @@ -22,10 +22,8 @@ import ( "io" "sync/atomic" - "github.com/arduino/arduino-cli/commands/board" "github.com/arduino/arduino-cli/commands/cache" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/compile" "github.com/arduino/arduino-cli/commands/monitor" "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/commands/updatecheck" @@ -55,13 +53,13 @@ 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) + resp, err := BoardDetails(ctx, req) return resp, convertErrorToRPCStatus(err) } // BoardList FIXMEDOC func (s *ArduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { - ports, _, err := board.List(req) + ports, _, err := BoardList(req) if err != nil { return nil, convertErrorToRPCStatus(err) } @@ -94,7 +92,7 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, s return err } - eventsChan, err := board.Watch(stream.Context(), req) + eventsChan, err := BoardListWatch(stream.Context(), req) if err != nil { return convertErrorToRPCStatus(err) } @@ -211,7 +209,7 @@ func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu Message: &rpc.CompileResponse_Progress{Progress: p}, }) } - compileRes, compileErr := compile.Compile(stream.Context(), req, outStream, errStream, progressStream) + compileRes, compileErr := Compile(stream.Context(), req, outStream, errStream, progressStream) outStream.Close() errStream.Close() var compileRespSendErr error diff --git a/commands/board/details.go b/commands/service_board_details.go similarity index 96% rename from commands/board/details.go rename to commands/service_board_details.go index 22cfb36a354..d6637416688 100644 --- a/commands/board/details.go +++ b/commands/service_board_details.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package board +package commands import ( "context" @@ -25,9 +25,9 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) -// Details returns all details for a board including tools and HW identifiers. +// BoardDetails 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 BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/commands/board/list.go b/commands/service_board_list.go similarity index 95% rename from commands/board/list.go rename to commands/service_board_list.go index 25c6ef53401..5607d932bb9 100644 --- a/commands/board/list.go +++ b/commands/service_board_list.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package board +package commands import ( "context" @@ -201,10 +201,10 @@ func identify(pme *packagemanager.Explorer, port *discovery.Port) ([]*rpc.BoardL return boards, nil } -// List returns a list of boards found by the loaded discoveries. +// BoardList returns a list of boards found by the loaded discoveries. // In case of errors partial results from discoveries that didn't fail // are returned. -func List(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, discoveryStartErrors []error, e error) { +func BoardList(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, discoveryStartErrors []error, e error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, nil, err @@ -258,8 +258,8 @@ func hasMatchingBoard(b *rpc.DetectedPort, fqbnFilter *cores.FQBN) bool { return false } -// Watch returns a channel that receives boards connection and disconnection events. -func Watch(ctx context.Context, req *rpc.BoardListWatchRequest) (<-chan *rpc.BoardListWatchResponse, error) { +// BoardListWatch returns a channel that receives boards connection and disconnection events. +func BoardListWatch(ctx context.Context, req *rpc.BoardListWatchRequest) (<-chan *rpc.BoardListWatchResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/commands/board/list_test.go b/commands/service_board_list_test.go similarity index 91% rename from commands/board/list_test.go rename to commands/service_board_list_test.go index f6e46f19a46..2db649e4554 100644 --- a/commands/board/list_test.go +++ b/commands/service_board_list_test.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package board +package commands import ( "fmt" @@ -30,11 +30,9 @@ import ( semver "go.bug.st/relaxed-semver" ) -func init() { - configuration.Settings = configuration.Init("") -} - func TestGetByVidPid(t *testing.T) { + configuration.Settings = configuration.Init("") + configuration.Settings.Set("locale", "en") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, ` { @@ -63,6 +61,8 @@ func TestGetByVidPid(t *testing.T) { } func TestGetByVidPidNotFound(t *testing.T) { + configuration.Settings = configuration.Init("") + configuration.Settings.Set("locale", "en") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) })) @@ -75,6 +75,8 @@ func TestGetByVidPidNotFound(t *testing.T) { } func TestGetByVidPid5xx(t *testing.T) { + configuration.Settings = configuration.Init("") + configuration.Settings.Set("locale", "en") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("500 - Ooooops!")) @@ -89,6 +91,8 @@ func TestGetByVidPid5xx(t *testing.T) { } func TestGetByVidPidMalformedResponse(t *testing.T) { + configuration.Settings = configuration.Init("") + configuration.Settings.Set("locale", "en") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "{}") })) @@ -102,12 +106,17 @@ func TestGetByVidPidMalformedResponse(t *testing.T) { } func TestBoardDetectionViaAPIWithNonUSBPort(t *testing.T) { + configuration.Settings = configuration.Init("") + configuration.Settings.Set("locale", "en") items, err := identifyViaCloudAPI(properties.NewMap()) require.NoError(t, err) require.Empty(t, items) } func TestBoardIdentifySorting(t *testing.T) { + configuration.Settings = configuration.Init("") + configuration.Settings.Set("locale", "en") + dataDir := paths.TempDir().Join("test", "data_dir") t.Setenv("ARDUINO_DATA_DIR", dataDir.String()) dataDir.MkdirAll() diff --git a/commands/compile/compile.go b/commands/service_compile.go similarity index 99% rename from commands/compile/compile.go rename to commands/service_compile.go index 7a124aceb00..94157244cba 100644 --- a/commands/compile/compile.go +++ b/commands/service_compile.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package compile +package commands import ( "context" @@ -32,15 +32,12 @@ import ( "github.com/arduino/arduino-cli/internal/arduino/utils" "github.com/arduino/arduino-cli/internal/buildcache" "github.com/arduino/arduino-cli/internal/cli/configuration" - "github.com/arduino/arduino-cli/internal/i18n" "github.com/arduino/arduino-cli/internal/inventory" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" ) -var tr = i18n.Tr - // Compile FIXMEDOC func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream io.Writer, progressCB rpc.TaskProgressCB) (r *rpc.BuilderResult, e error) { exportBinaries := configuration.Settings.GetBool("sketch.always_export_binaries") diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index 8cc3df895a4..337266ba1ad 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -19,7 +19,6 @@ import ( "context" "github.com/arduino/arduino-cli/commands" - "github.com/arduino/arduino-cli/commands/board" "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -169,7 +168,7 @@ func GetInstallableLibs() []string { func GetAvailablePorts() []*rpc.Port { inst := instance.CreateAndInit() - list, _, _ := board.List(&rpc.BoardListRequest{ + list, _, _ := commands.BoardList(&rpc.BoardListRequest{ Instance: inst, }) var res []*rpc.Port diff --git a/internal/cli/arguments/port.go b/internal/cli/arguments/port.go index f10c6bf70a0..e696be1e3cb 100644 --- a/internal/cli/arguments/port.go +++ b/internal/cli/arguments/port.go @@ -20,7 +20,7 @@ import ( "fmt" "time" - "github.com/arduino/arduino-cli/commands/board" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/cli/feedback" @@ -91,7 +91,7 @@ func (p *Port) GetPort(instance *rpc.Instance, defaultAddress, defaultProtocol s ctx, cancel := context.WithCancel(context.Background()) defer cancel() - watcher, err := board.Watch(ctx, &rpc.BoardListWatchRequest{Instance: instance}) + watcher, err := commands.BoardListWatch(ctx, &rpc.BoardListWatchRequest{Instance: instance}) if err != nil { return nil, err } @@ -130,7 +130,7 @@ func (p *Port) GetSearchTimeout() time.Duration { // discovered Port object together with the FQBN. If the port does not match // exactly 1 board, func (p *Port) DetectFQBN(inst *rpc.Instance) (string, *rpc.Port) { - detectedPorts, _, err := board.List(&rpc.BoardListRequest{ + detectedPorts, _, err := commands.BoardList(&rpc.BoardListRequest{ Instance: inst, Timeout: p.timeout.Get().Milliseconds(), }) diff --git a/internal/cli/arguments/programmer.go b/internal/cli/arguments/programmer.go index a5267ef804e..b793d8192a4 100644 --- a/internal/cli/arguments/programmer.go +++ b/internal/cli/arguments/programmer.go @@ -18,8 +18,8 @@ package arguments import ( "context" - "github.com/arduino/arduino-cli/commands/board" - "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "github.com/arduino/arduino-cli/commands" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) @@ -40,14 +40,14 @@ func (p *Programmer) AddToCommand(cmd *cobra.Command) { // String returns the programmer specified by the user, or the default programmer // for the given board if defined. -func (p *Programmer) String(inst *commands.Instance, fqbn string) string { +func (p *Programmer) String(inst *rpc.Instance, fqbn string) string { if p.programmer != "" { return p.programmer } if inst == nil || fqbn == "" { return "" } - details, err := board.Details(context.Background(), &commands.BoardDetailsRequest{ + details, err := commands.BoardDetails(context.Background(), &rpc.BoardDetailsRequest{ Instance: inst, Fqbn: fqbn, }) diff --git a/internal/cli/board/details.go b/internal/cli/board/details.go index 14f48414ea9..a91359caea4 100644 --- a/internal/cli/board/details.go +++ b/internal/cli/board/details.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/board" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -65,7 +65,7 @@ func runDetailsCommand(fqbn string, showFullDetails, listProgrammers bool, showP if err != nil { feedback.Fatal(err.Error(), feedback.ErrBadArgument) } - res, err := board.Details(context.Background(), &rpc.BoardDetailsRequest{ + res, err := commands.BoardDetails(context.Background(), &rpc.BoardDetailsRequest{ Instance: inst, Fqbn: fqbn, DoNotExpandBuildProperties: showPropertiesMode == arguments.ShowPropertiesUnexpanded, diff --git a/internal/cli/board/list.go b/internal/cli/board/list.go index f864768fc8d..96fb69c5029 100644 --- a/internal/cli/board/list.go +++ b/internal/cli/board/list.go @@ -22,7 +22,7 @@ import ( "os" "sort" - "github.com/arduino/arduino-cli/commands/board" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/internal/arduino/cores" "github.com/arduino/arduino-cli/internal/cli/arguments" @@ -67,7 +67,7 @@ func runListCommand(watch bool, timeout int64, fqbn string) { return } - ports, discoveryErrors, err := board.List(&rpc.BoardListRequest{ + ports, discoveryErrors, err := commands.BoardList(&rpc.BoardListRequest{ Instance: inst, Timeout: timeout, Fqbn: fqbn, @@ -87,7 +87,7 @@ func runListCommand(watch bool, timeout int64, fqbn string) { } func watchList(inst *rpc.Instance) { - eventsChan, err := board.Watch(context.Background(), &rpc.BoardListWatchRequest{Instance: inst}) + eventsChan, err := commands.BoardListWatch(context.Background(), &rpc.BoardListWatchRequest{Instance: inst}) if err != nil { feedback.Fatal(tr("Error detecting boards: %v", err), feedback.ErrNetwork) } diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 13db316f12b..1d72fe8b8a2 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -26,7 +26,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/compile" "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/arguments" @@ -246,7 +245,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) { DoNotExpandBuildProperties: showProperties == arguments.ShowPropertiesUnexpanded, Jobs: jobs, } - builderRes, compileError := compile.Compile(context.Background(), compileRequest, stdOut, stdErr, nil) + builderRes, compileError := commands.Compile(context.Background(), compileRequest, stdOut, stdErr, nil) var uploadRes *rpc.UploadResult if compileError == nil && uploadAfterCompile { From 3ff8e090e9552379ef622a418b92f3912459bb5b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 11:27:13 +0100 Subject: [PATCH 03/56] Moved a batch of function from commands/* subpackage to commands (part 3) --- commands/service.go | 11 ++-- .../{upload/upload.go => service_upload.go} | 9 +-- ...er.go => service_upload_burnbootloader.go} | 2 +- ....go => service_upload_list_programmers.go} | 2 +- .../upload_test.go => service_upload_test.go} | 64 +++++++++---------- .../upload}/Blonk/Blonk.ino | 0 .../build/arduino.samd.mkr1000/Blonk.ino.bin | 0 .../build/arduino.samd.mkr1000/Blonk.ino.elf | 0 .../build/arduino.samd.mkr1000/Blonk.ino.hex | 0 .../build/arduino.samd.mkr1000/Blonk.ino.map | 0 .../Blonk.ino.with_bootloader.bin | 0 .../Blonk.ino.with_bootloader.hex | 0 .../upload}/build_path_1/sketch.ino.bin | 0 .../upload}/build_path_2/Blink.ino.bin | 0 .../upload}/build_path_2/Blink.ino.elf | 0 .../upload}/build_path_2/Blink.ino.hex | 0 .../upload}/build_path_2/Blink.ino.map | 0 .../Blink.ino.with_bootloader.bin | 0 .../Blink.ino.with_bootloader.hex | 0 .../build_path_3/AnotherSketch.ino.bin | 0 .../upload}/build_path_3/Blink.ino.bin | 0 .../upload}/build_path_3/Blink.ino.elf | 0 .../upload}/build_path_3/Blink.ino.hex | 0 .../upload}/build_path_3/Blink.ino.map | 0 .../Blink.ino.with_bootloader.bin | 0 .../Blink.ino.with_bootloader.hex | 0 .../upload}/build_path_4/some_other_files.txt | 0 .../upload}/firmware/another_firmware.ino.bin | 0 .../upload}/firmware/firmware.ino.bin | 0 .../upload}/hardware/alice/avr/boards.txt | 0 .../upload}/hardware/alice/avr/platform.txt | 0 .../hardware/alice/avr/programmers.txt | 0 internal/cli/arguments/completion.go | 3 +- internal/cli/burnbootloader/burnbootloader.go | 4 +- internal/cli/compile/compile.go | 5 +- internal/cli/upload/upload.go | 5 +- 36 files changed, 49 insertions(+), 56 deletions(-) rename commands/{upload/upload.go => service_upload.go} (99%) rename commands/{upload/burnbootloader.go => service_upload_burnbootloader.go} (99%) rename commands/{upload/programmers_list.go => service_upload_list_programmers.go} (99%) rename commands/{upload/upload_test.go => service_upload_test.go} (83%) rename commands/{upload/testdata => testdata/upload}/Blonk/Blonk.ino (100%) rename commands/{upload/testdata => testdata/upload}/Blonk/build/arduino.samd.mkr1000/Blonk.ino.bin (100%) rename commands/{upload/testdata => testdata/upload}/Blonk/build/arduino.samd.mkr1000/Blonk.ino.elf (100%) rename commands/{upload/testdata => testdata/upload}/Blonk/build/arduino.samd.mkr1000/Blonk.ino.hex (100%) rename commands/{upload/testdata => testdata/upload}/Blonk/build/arduino.samd.mkr1000/Blonk.ino.map (100%) rename commands/{upload/testdata => testdata/upload}/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.bin (100%) rename commands/{upload/testdata => testdata/upload}/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.hex (100%) rename commands/{upload/testdata => testdata/upload}/build_path_1/sketch.ino.bin (100%) rename commands/{upload/testdata => testdata/upload}/build_path_2/Blink.ino.bin (100%) rename commands/{upload/testdata => testdata/upload}/build_path_2/Blink.ino.elf (100%) rename commands/{upload/testdata => testdata/upload}/build_path_2/Blink.ino.hex (100%) rename commands/{upload/testdata => testdata/upload}/build_path_2/Blink.ino.map (100%) rename commands/{upload/testdata => testdata/upload}/build_path_2/Blink.ino.with_bootloader.bin (100%) rename commands/{upload/testdata => testdata/upload}/build_path_2/Blink.ino.with_bootloader.hex (100%) rename commands/{upload/testdata => testdata/upload}/build_path_3/AnotherSketch.ino.bin (100%) rename commands/{upload/testdata => testdata/upload}/build_path_3/Blink.ino.bin (100%) rename commands/{upload/testdata => testdata/upload}/build_path_3/Blink.ino.elf (100%) rename commands/{upload/testdata => testdata/upload}/build_path_3/Blink.ino.hex (100%) rename commands/{upload/testdata => testdata/upload}/build_path_3/Blink.ino.map (100%) rename commands/{upload/testdata => testdata/upload}/build_path_3/Blink.ino.with_bootloader.bin (100%) rename commands/{upload/testdata => testdata/upload}/build_path_3/Blink.ino.with_bootloader.hex (100%) rename commands/{upload/testdata => testdata/upload}/build_path_4/some_other_files.txt (100%) rename commands/{upload/testdata => testdata/upload}/firmware/another_firmware.ino.bin (100%) rename commands/{upload/testdata => testdata/upload}/firmware/firmware.ino.bin (100%) rename commands/{upload/testdata => testdata/upload}/hardware/alice/avr/boards.txt (100%) rename commands/{upload/testdata => testdata/upload}/hardware/alice/avr/platform.txt (100%) rename commands/{upload/testdata => testdata/upload}/hardware/alice/avr/programmers.txt (100%) diff --git a/commands/service.go b/commands/service.go index 7121ab48be2..3b47adc451e 100644 --- a/commands/service.go +++ b/commands/service.go @@ -27,7 +27,6 @@ import ( "github.com/arduino/arduino-cli/commands/monitor" "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/commands/updatecheck" - "github.com/arduino/arduino-cli/commands/upload" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "google.golang.org/grpc/metadata" @@ -299,7 +298,7 @@ func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.Arduin Message: &rpc.UploadResponse_ErrStream{ErrStream: data}, }) }) - res, err := upload.Upload(stream.Context(), req, outStream, errStream) + res, err := Upload(stream.Context(), req, outStream, errStream) outStream.Close() errStream.Close() if res != nil { @@ -329,7 +328,7 @@ func (s *ArduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgra }, }) }) - err := upload.UsingProgrammer(stream.Context(), req, outStream, errStream) + err := UploadUsingProgrammer(stream.Context(), req, outStream, errStream) outStream.Close() errStream.Close() if err != nil { @@ -340,7 +339,7 @@ func (s *ArduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgra // SupportedUserFields FIXMEDOC func (s *ArduinoCoreServerImpl) SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsRequest) (*rpc.SupportedUserFieldsResponse, error) { - res, err := upload.SupportedUserFields(ctx, req) + res, err := SupportedUserFields(ctx, req) return res, convertErrorToRPCStatus(err) } @@ -361,7 +360,7 @@ func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, s }, }) }) - resp, err := upload.BurnBootloader(stream.Context(), req, outStream, errStream) + resp, err := BurnBootloader(stream.Context(), req, outStream, errStream) outStream.Close() errStream.Close() if err != nil { @@ -372,7 +371,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) + resp, err := ListProgrammersAvailableForUpload(ctx, req) return resp, convertErrorToRPCStatus(err) } diff --git a/commands/upload/upload.go b/commands/service_upload.go similarity index 99% rename from commands/upload/upload.go rename to commands/service_upload.go index fcc248ce3b9..15df0cb295c 100644 --- a/commands/upload/upload.go +++ b/commands/service_upload.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package upload +package commands import ( "context" @@ -31,7 +31,6 @@ import ( "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/internal/arduino/globals" "github.com/arduino/arduino-cli/internal/arduino/sketch" - "github.com/arduino/arduino-cli/internal/i18n" 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" @@ -40,8 +39,6 @@ import ( "github.com/sirupsen/logrus" ) -var tr = i18n.Tr - // SupportedUserFields returns a SupportedUserFieldsResponse containing all the UserFields supported // 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) { @@ -179,8 +176,8 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er }, nil } -// UsingProgrammer FIXMEDOC -func UsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest, outStream io.Writer, errStream io.Writer) error { +// UploadUsingProgrammer FIXMEDOC +func UploadUsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest, outStream io.Writer, errStream io.Writer) error { logrus.Tracef("Upload using programmer %s on %s started", req.GetSketchPath(), req.GetFqbn()) if req.GetProgrammer() == "" { diff --git a/commands/upload/burnbootloader.go b/commands/service_upload_burnbootloader.go similarity index 99% rename from commands/upload/burnbootloader.go rename to commands/service_upload_burnbootloader.go index b589e573698..7d9c34cb7cc 100644 --- a/commands/upload/burnbootloader.go +++ b/commands/service_upload_burnbootloader.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package upload +package commands import ( "context" diff --git a/commands/upload/programmers_list.go b/commands/service_upload_list_programmers.go similarity index 99% rename from commands/upload/programmers_list.go rename to commands/service_upload_list_programmers.go index 76188ac5e2e..0e02d36c25a 100644 --- a/commands/upload/programmers_list.go +++ b/commands/service_upload_list_programmers.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package upload +package commands import ( "context" diff --git a/commands/upload/upload_test.go b/commands/service_upload_test.go similarity index 83% rename from commands/upload/upload_test.go rename to commands/service_upload_test.go index 95d26de6634..f50f06c4583 100644 --- a/commands/upload/upload_test.go +++ b/commands/service_upload_test.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package upload +package commands import ( "bytes" @@ -32,23 +32,23 @@ import ( ) func TestDetectSketchNameFromBuildPath(t *testing.T) { - sk1, err1 := detectSketchNameFromBuildPath(paths.New("testdata/build_path_1")) + sk1, err1 := detectSketchNameFromBuildPath(paths.New("testdata/upload/build_path_1")) require.NoError(t, err1) require.Equal(t, "sketch.ino", sk1) - sk2, err2 := detectSketchNameFromBuildPath(paths.New("testdata/build_path_2")) + sk2, err2 := detectSketchNameFromBuildPath(paths.New("testdata/upload/build_path_2")) require.NoError(t, err2) require.Equal(t, "Blink.ino", sk2) - sk3, err3 := detectSketchNameFromBuildPath(paths.New("testdata/build_path_3")) + sk3, err3 := detectSketchNameFromBuildPath(paths.New("testdata/upload/build_path_3")) require.Error(t, err3) require.Equal(t, "", sk3) - sk4, err4 := detectSketchNameFromBuildPath(paths.New("testdata/build_path_4")) + sk4, err4 := detectSketchNameFromBuildPath(paths.New("testdata/upload/build_path_4")) require.Error(t, err4) require.Equal(t, "", sk4) - sk5, err5 := detectSketchNameFromBuildPath(paths.New("testdata/build_path_invalid")) + sk5, err5 := detectSketchNameFromBuildPath(paths.New("testdata/upload/build_path_invalid")) require.Error(t, err5) require.Equal(t, "", sk5) } @@ -63,7 +63,7 @@ func TestDetermineBuildPathAndSketchName(t *testing.T) { resSketchName string } - blonk, err := sketch.New(paths.New("testdata/Blonk")) + blonk, err := sketch.New(paths.New("testdata/upload/Blonk")) require.NoError(t, err) fqbn, err := cores.ParseFQBN("arduino:samd:mkr1000") @@ -73,39 +73,39 @@ func TestDetermineBuildPathAndSketchName(t *testing.T) { // 00: error: no data passed in {"", "", nil, nil, "", ""}, // 01: use importFile to detect build.path and project_name - {"testdata/build_path_2/Blink.ino.hex", "", nil, nil, "testdata/build_path_2", "Blink.ino"}, + {"testdata/upload/build_path_2/Blink.ino.hex", "", nil, nil, "testdata/upload/build_path_2", "Blink.ino"}, // 02: use importPath as build.path and project_name - {"", "testdata/build_path_2", nil, nil, "testdata/build_path_2", "Blink.ino"}, + {"", "testdata/upload/build_path_2", nil, nil, "testdata/upload/build_path_2", "Blink.ino"}, // 03: error: used both importPath and importFile - {"testdata/build_path_2/Blink.ino.hex", "testdata/build_path_2", nil, nil, "", ""}, + {"testdata/upload/build_path_2/Blink.ino.hex", "testdata/upload/build_path_2", nil, nil, "", ""}, // 04: only sketch without FQBN {"", "", blonk, nil, blonk.DefaultBuildPath().String(), "Blonk.ino"}, // 05: use importFile to detect build.path and project_name, sketch is ignored. - {"testdata/build_path_2/Blink.ino.hex", "", blonk, nil, "testdata/build_path_2", "Blink.ino"}, + {"testdata/upload/build_path_2/Blink.ino.hex", "", blonk, nil, "testdata/upload/build_path_2", "Blink.ino"}, // 06: use importPath as build.path and Blink as project name, ignore the sketch Blonk - {"", "testdata/build_path_2", blonk, nil, "testdata/build_path_2", "Blink.ino"}, + {"", "testdata/upload/build_path_2", blonk, nil, "testdata/upload/build_path_2", "Blink.ino"}, // 07: error: used both importPath and importFile - {"testdata/build_path_2/Blink.ino.hex", "testdata/build_path_2", blonk, nil, "", ""}, + {"testdata/upload/build_path_2/Blink.ino.hex", "testdata/upload/build_path_2", blonk, nil, "", ""}, // 08: error: no data passed in {"", "", nil, fqbn, "", ""}, // 09: use importFile to detect build.path and project_name, fqbn ignored - {"testdata/build_path_2/Blink.ino.hex", "", nil, fqbn, "testdata/build_path_2", "Blink.ino"}, + {"testdata/upload/build_path_2/Blink.ino.hex", "", nil, fqbn, "testdata/upload/build_path_2", "Blink.ino"}, // 10: use importPath as build.path and project_name, fqbn ignored - {"", "testdata/build_path_2", nil, fqbn, "testdata/build_path_2", "Blink.ino"}, + {"", "testdata/upload/build_path_2", nil, fqbn, "testdata/upload/build_path_2", "Blink.ino"}, // 11: error: used both importPath and importFile - {"testdata/build_path_2/Blink.ino.hex", "testdata/build_path_2", nil, fqbn, "", ""}, + {"testdata/upload/build_path_2/Blink.ino.hex", "testdata/upload/build_path_2", nil, fqbn, "", ""}, // 12: use sketch to determine project name and sketch+fqbn to determine build path {"", "", blonk, fqbn, blonk.DefaultBuildPath().String(), "Blonk.ino"}, // 13: use importFile to detect build.path and project_name, sketch+fqbn is ignored. - {"testdata/build_path_2/Blink.ino.hex", "", blonk, fqbn, "testdata/build_path_2", "Blink.ino"}, + {"testdata/upload/build_path_2/Blink.ino.hex", "", blonk, fqbn, "testdata/upload/build_path_2", "Blink.ino"}, // 14: use importPath as build.path and Blink as project name, ignore the sketch Blonk, ignore fqbn - {"", "testdata/build_path_2", blonk, fqbn, "testdata/build_path_2", "Blink.ino"}, + {"", "testdata/upload/build_path_2", blonk, fqbn, "testdata/upload/build_path_2", "Blink.ino"}, // 15: error: used both importPath and importFile - {"testdata/build_path_2/Blink.ino.hex", "testdata/build_path_2", blonk, fqbn, "", ""}, + {"testdata/upload/build_path_2/Blink.ino.hex", "testdata/upload/build_path_2", blonk, fqbn, "", ""}, // 16: importPath containing multiple firmwares, but one has the same name as the containing folder - {"", "testdata/firmware", nil, fqbn, "testdata/firmware", "firmware.ino"}, + {"", "testdata/upload/firmware", nil, fqbn, "testdata/upload/firmware", "firmware.ino"}, // 17: importFile among multiple firmwares - {"testdata/firmware/another_firmware.ino.bin", "", nil, fqbn, "testdata/firmware", "another_firmware.ino"}, + {"testdata/upload/firmware/another_firmware.ino.bin", "", nil, fqbn, "testdata/upload/firmware", "another_firmware.ino"}, } for i, test := range tests { t.Run(fmt.Sprintf("SubTest%02d", i), func(t *testing.T) { @@ -128,9 +128,9 @@ func TestDetermineBuildPathAndSketchName(t *testing.T) { func TestUploadPropertiesComposition(t *testing.T) { pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test") - errs := pmb.LoadHardwareFromDirectory(paths.New("testdata", "hardware")) + errs := pmb.LoadHardwareFromDirectory(paths.New("testdata", "upload", "hardware")) require.Len(t, errs, 0) - buildPath1 := paths.New("testdata", "build_path_1") + buildPath1 := paths.New("testdata", "upload", "build_path_1") logrus.SetLevel(logrus.TraceLevel) type test struct { importDir *paths.Path @@ -149,32 +149,32 @@ func TestUploadPropertiesComposition(t *testing.T) { tests := []test{ // 0: classic upload, requires port - {buildPath1, "alice:avr:board1", "port", "serial", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol port -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board1", "port", "serial", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol port -bspeed testdata/upload/build_path_1/sketch.ino.hex\n", ""}, {buildPath1, "alice:avr:board1", "", "", "", false, "FAIL", ""}, // 2: classic upload, no port - {buildPath1, "alice:avr:board2", "port", "serial", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, - {buildPath1, "alice:avr:board2", "", "", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board2", "port", "serial", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/upload/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board2", "", "", "", false, "conf-board1 conf-general conf-upload $$VERBOSE-VERIFY$$ protocol -bspeed testdata/upload/build_path_1/sketch.ino.hex\n", ""}, // 4: upload with programmer, requires port - {buildPath1, "alice:avr:board1", "port", "serial", "progr1", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ progprotocol port -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board1", "port", "serial", "progr1", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ progprotocol port -bspeed testdata/upload/build_path_1/sketch.ino.hex\n", ""}, {buildPath1, "alice:avr:board1", "", "", "progr1", false, "FAIL", ""}, // 6: upload with programmer, no port - {buildPath1, "alice:avr:board1", "port", "serial", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, - {buildPath1, "alice:avr:board1", "", "", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board1", "port", "serial", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/upload/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board1", "", "", "progr2", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog2protocol -bspeed testdata/upload/build_path_1/sketch.ino.hex\n", ""}, // 8: upload with programmer, require port through extra params - {buildPath1, "alice:avr:board1", "port", "serial", "progr3", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog3protocol port -bspeed testdata/build_path_1/sketch.ino.hex\n", ""}, + {buildPath1, "alice:avr:board1", "port", "serial", "progr3", false, "conf-board1 conf-general conf-program $$VERBOSE-VERIFY$$ prog3protocol port -bspeed testdata/upload/build_path_1/sketch.ino.hex\n", ""}, {buildPath1, "alice:avr:board1", "", "", "progr3", false, "FAIL", ""}, // 10: burn bootloader, require port {buildPath1, "alice:avr:board1", "port", "serial", "", true, "FAIL", ""}, // requires programmer {buildPath1, "alice:avr:board1", "port", "serial", "progr1", true, "ERASE conf-board1 conf-general conf-erase $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed\n", - "BURN conf-board1 conf-general conf-bootloader $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex\n"}, + "BURN conf-board1 conf-general conf-bootloader $$VERBOSE-VERIFY$$ genprog1protocol port -bspeed -F0xFF " + cwd + "/testdata/upload/hardware/alice/avr/bootloaders/niceboot/niceboot.hex\n"}, // 12: burn bootloader, preferences override from programmers.txt {buildPath1, "alice:avr:board1", "port", "serial", "progr4", true, "ERASE conf-board1 conf-two-general conf-two-erase $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed\n", - "BURN conf-board1 conf-two-general conf-two-bootloader $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed -F0xFF " + cwd + "/testdata/hardware/alice/avr/bootloaders/niceboot/niceboot.hex\n"}, + "BURN conf-board1 conf-two-general conf-two-bootloader $$VERBOSE-VERIFY$$ prog4protocol-bootloader port -bspeed -F0xFF " + cwd + "/testdata/upload/hardware/alice/avr/bootloaders/niceboot/niceboot.hex\n"}, } pm := pmb.Build() diff --git a/commands/upload/testdata/Blonk/Blonk.ino b/commands/testdata/upload/Blonk/Blonk.ino similarity index 100% rename from commands/upload/testdata/Blonk/Blonk.ino rename to commands/testdata/upload/Blonk/Blonk.ino diff --git a/commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.bin b/commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.bin similarity index 100% rename from commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.bin rename to commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.bin diff --git a/commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.elf b/commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.elf similarity index 100% rename from commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.elf rename to commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.elf diff --git a/commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.hex b/commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.hex similarity index 100% rename from commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.hex rename to commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.hex diff --git a/commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.map b/commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.map similarity index 100% rename from commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.map rename to commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.map diff --git a/commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.bin b/commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.bin similarity index 100% rename from commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.bin rename to commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.bin diff --git a/commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.hex b/commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.hex similarity index 100% rename from commands/upload/testdata/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.hex rename to commands/testdata/upload/Blonk/build/arduino.samd.mkr1000/Blonk.ino.with_bootloader.hex diff --git a/commands/upload/testdata/build_path_1/sketch.ino.bin b/commands/testdata/upload/build_path_1/sketch.ino.bin similarity index 100% rename from commands/upload/testdata/build_path_1/sketch.ino.bin rename to commands/testdata/upload/build_path_1/sketch.ino.bin diff --git a/commands/upload/testdata/build_path_2/Blink.ino.bin b/commands/testdata/upload/build_path_2/Blink.ino.bin similarity index 100% rename from commands/upload/testdata/build_path_2/Blink.ino.bin rename to commands/testdata/upload/build_path_2/Blink.ino.bin diff --git a/commands/upload/testdata/build_path_2/Blink.ino.elf b/commands/testdata/upload/build_path_2/Blink.ino.elf similarity index 100% rename from commands/upload/testdata/build_path_2/Blink.ino.elf rename to commands/testdata/upload/build_path_2/Blink.ino.elf diff --git a/commands/upload/testdata/build_path_2/Blink.ino.hex b/commands/testdata/upload/build_path_2/Blink.ino.hex similarity index 100% rename from commands/upload/testdata/build_path_2/Blink.ino.hex rename to commands/testdata/upload/build_path_2/Blink.ino.hex diff --git a/commands/upload/testdata/build_path_2/Blink.ino.map b/commands/testdata/upload/build_path_2/Blink.ino.map similarity index 100% rename from commands/upload/testdata/build_path_2/Blink.ino.map rename to commands/testdata/upload/build_path_2/Blink.ino.map diff --git a/commands/upload/testdata/build_path_2/Blink.ino.with_bootloader.bin b/commands/testdata/upload/build_path_2/Blink.ino.with_bootloader.bin similarity index 100% rename from commands/upload/testdata/build_path_2/Blink.ino.with_bootloader.bin rename to commands/testdata/upload/build_path_2/Blink.ino.with_bootloader.bin diff --git a/commands/upload/testdata/build_path_2/Blink.ino.with_bootloader.hex b/commands/testdata/upload/build_path_2/Blink.ino.with_bootloader.hex similarity index 100% rename from commands/upload/testdata/build_path_2/Blink.ino.with_bootloader.hex rename to commands/testdata/upload/build_path_2/Blink.ino.with_bootloader.hex diff --git a/commands/upload/testdata/build_path_3/AnotherSketch.ino.bin b/commands/testdata/upload/build_path_3/AnotherSketch.ino.bin similarity index 100% rename from commands/upload/testdata/build_path_3/AnotherSketch.ino.bin rename to commands/testdata/upload/build_path_3/AnotherSketch.ino.bin diff --git a/commands/upload/testdata/build_path_3/Blink.ino.bin b/commands/testdata/upload/build_path_3/Blink.ino.bin similarity index 100% rename from commands/upload/testdata/build_path_3/Blink.ino.bin rename to commands/testdata/upload/build_path_3/Blink.ino.bin diff --git a/commands/upload/testdata/build_path_3/Blink.ino.elf b/commands/testdata/upload/build_path_3/Blink.ino.elf similarity index 100% rename from commands/upload/testdata/build_path_3/Blink.ino.elf rename to commands/testdata/upload/build_path_3/Blink.ino.elf diff --git a/commands/upload/testdata/build_path_3/Blink.ino.hex b/commands/testdata/upload/build_path_3/Blink.ino.hex similarity index 100% rename from commands/upload/testdata/build_path_3/Blink.ino.hex rename to commands/testdata/upload/build_path_3/Blink.ino.hex diff --git a/commands/upload/testdata/build_path_3/Blink.ino.map b/commands/testdata/upload/build_path_3/Blink.ino.map similarity index 100% rename from commands/upload/testdata/build_path_3/Blink.ino.map rename to commands/testdata/upload/build_path_3/Blink.ino.map diff --git a/commands/upload/testdata/build_path_3/Blink.ino.with_bootloader.bin b/commands/testdata/upload/build_path_3/Blink.ino.with_bootloader.bin similarity index 100% rename from commands/upload/testdata/build_path_3/Blink.ino.with_bootloader.bin rename to commands/testdata/upload/build_path_3/Blink.ino.with_bootloader.bin diff --git a/commands/upload/testdata/build_path_3/Blink.ino.with_bootloader.hex b/commands/testdata/upload/build_path_3/Blink.ino.with_bootloader.hex similarity index 100% rename from commands/upload/testdata/build_path_3/Blink.ino.with_bootloader.hex rename to commands/testdata/upload/build_path_3/Blink.ino.with_bootloader.hex diff --git a/commands/upload/testdata/build_path_4/some_other_files.txt b/commands/testdata/upload/build_path_4/some_other_files.txt similarity index 100% rename from commands/upload/testdata/build_path_4/some_other_files.txt rename to commands/testdata/upload/build_path_4/some_other_files.txt diff --git a/commands/upload/testdata/firmware/another_firmware.ino.bin b/commands/testdata/upload/firmware/another_firmware.ino.bin similarity index 100% rename from commands/upload/testdata/firmware/another_firmware.ino.bin rename to commands/testdata/upload/firmware/another_firmware.ino.bin diff --git a/commands/upload/testdata/firmware/firmware.ino.bin b/commands/testdata/upload/firmware/firmware.ino.bin similarity index 100% rename from commands/upload/testdata/firmware/firmware.ino.bin rename to commands/testdata/upload/firmware/firmware.ino.bin diff --git a/commands/upload/testdata/hardware/alice/avr/boards.txt b/commands/testdata/upload/hardware/alice/avr/boards.txt similarity index 100% rename from commands/upload/testdata/hardware/alice/avr/boards.txt rename to commands/testdata/upload/hardware/alice/avr/boards.txt diff --git a/commands/upload/testdata/hardware/alice/avr/platform.txt b/commands/testdata/upload/hardware/alice/avr/platform.txt similarity index 100% rename from commands/upload/testdata/hardware/alice/avr/platform.txt rename to commands/testdata/upload/hardware/alice/avr/platform.txt diff --git a/commands/upload/testdata/hardware/alice/avr/programmers.txt b/commands/testdata/upload/hardware/alice/avr/programmers.txt similarity index 100% rename from commands/upload/testdata/hardware/alice/avr/programmers.txt rename to commands/testdata/upload/hardware/alice/avr/programmers.txt diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index 337266ba1ad..d351c8e4f5a 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -19,7 +19,6 @@ import ( "context" "github.com/arduino/arduino-cli/commands" - "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) @@ -58,7 +57,7 @@ func GetInstalledProgrammers() []string { installedProgrammers := make(map[string]string) for _, board := range list.GetBoards() { - programmers, _ := upload.ListProgrammersAvailableForUpload(context.Background(), &rpc.ListProgrammersAvailableForUploadRequest{ + programmers, _ := commands.ListProgrammersAvailableForUpload(context.Background(), &rpc.ListProgrammersAvailableForUploadRequest{ Instance: inst, Fqbn: board.GetFqbn(), }) diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index c14c63eeb42..2de1a5f132b 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -20,8 +20,8 @@ import ( "errors" "os" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" @@ -75,7 +75,7 @@ func runBootloaderCommand(command *cobra.Command, args []string) { } stdOut, stdErr, res := feedback.OutputStreams() - if _, err := upload.BurnBootloader(context.Background(), &rpc.BurnBootloaderRequest{ + if _, err := commands.BurnBootloader(context.Background(), &rpc.BurnBootloaderRequest{ Instance: instance, Fqbn: fqbn.String(), Port: discoveryPort, diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 1d72fe8b8a2..5a379bb8f73 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -27,7 +27,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/sketch" - "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" @@ -249,7 +248,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) { var uploadRes *rpc.UploadResult if compileError == nil && uploadAfterCompile { - userFieldRes, err := upload.SupportedUserFields(context.Background(), &rpc.SupportedUserFieldsRequest{ + userFieldRes, err := commands.SupportedUserFields(context.Background(), &rpc.SupportedUserFieldsRequest{ Instance: inst, Fqbn: fqbn, Protocol: port.GetProtocol(), @@ -288,7 +287,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) { UserFields: fields, } - if res, err := upload.Upload(context.Background(), uploadRequest, stdOut, stdErr); err != nil { + if res, err := commands.Upload(context.Background(), uploadRequest, stdOut, stdErr); err != nil { errcode := feedback.ErrGeneric if errors.Is(err, &cmderrors.ProgrammerRequiredForUploadError{}) { errcode = feedback.ErrMissingProgrammer diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 7f04e731a83..7ab259c6ae3 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -25,7 +25,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" sk "github.com/arduino/arduino-cli/commands/sketch" - "github.com/arduino/arduino-cli/commands/upload" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -117,7 +116,7 @@ func runUploadCommand(args []string, uploadFieldsArgs map[string]string) { defaultProtocol := sketch.GetDefaultProtocol() fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, inst, defaultFQBN, defaultAddress, defaultProtocol) - userFieldRes, err := upload.SupportedUserFields(context.Background(), &rpc.SupportedUserFieldsRequest{ + userFieldRes, err := commands.SupportedUserFields(context.Background(), &rpc.SupportedUserFieldsRequest{ Instance: inst, Fqbn: fqbn, Protocol: port.GetProtocol(), @@ -198,7 +197,7 @@ func runUploadCommand(args []string, uploadFieldsArgs map[string]string) { DryRun: dryRun, UserFields: fields, } - if res, err := upload.Upload(context.Background(), req, stdOut, stdErr); err != nil { + if res, err := commands.Upload(context.Background(), req, stdOut, stdErr); err != nil { errcode := feedback.ErrGeneric if errors.Is(err, &cmderrors.ProgrammerRequiredForUploadError{}) { errcode = feedback.ErrMissingProgrammer From 86159855ff6409db0e593c08e27542e50f6e0f3e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 11:36:31 +0100 Subject: [PATCH 04/56] Moved a batch of function from commands/* subpackage to commands (part 4) --- commands/service.go | 14 ++++++------- .../monitor.go => service_monitor.go} | 21 ++++++++----------- ...ettings.go => service_monitor_settings.go} | 2 +- ...ults.go => service_set_sketch_defaults.go} | 2 +- .../archive.go => service_sketch_archive.go} | 5 +---- .../load.go => service_sketch_load.go} | 2 +- ...ad_test.go => service_sketch_load_test.go} | 2 +- .../{sketch/new.go => service_sketch_new.go} | 2 +- ...new_test.go => service_sketch_new_test.go} | 2 +- .../testdata/sketch_with_profile/sketch.yml | 0 .../sketch_with_profile.ino | 0 internal/cli/arguments/sketch.go | 4 ++-- internal/cli/board/attach.go | 4 ++-- internal/cli/compile/compile.go | 3 +-- internal/cli/debug/debug.go | 4 ++-- internal/cli/monitor/monitor.go | 9 ++++---- internal/cli/sketch/archive.go | 6 +++--- internal/cli/sketch/new.go | 4 ++-- internal/cli/upload/upload.go | 3 +-- 19 files changed, 39 insertions(+), 50 deletions(-) rename commands/{monitor/monitor.go => service_monitor.go} (92%) rename commands/{monitor/settings.go => service_monitor_settings.go} (99%) rename commands/{sketch/set_defaults.go => service_set_sketch_defaults.go} (99%) rename commands/{sketch/archive.go => service_sketch_archive.go} (98%) rename commands/{sketch/load.go => service_sketch_load.go} (98%) rename commands/{sketch/load_test.go => service_sketch_load_test.go} (98%) rename commands/{sketch/new.go => service_sketch_new.go} (99%) rename commands/{sketch/new_test.go => service_sketch_new_test.go} (99%) rename commands/{sketch => }/testdata/sketch_with_profile/sketch.yml (100%) rename commands/{sketch => }/testdata/sketch_with_profile/sketch_with_profile.ino (100%) diff --git a/commands/service.go b/commands/service.go index 3b47adc451e..0b34c6250c8 100644 --- a/commands/service.go +++ b/commands/service.go @@ -24,8 +24,6 @@ import ( "github.com/arduino/arduino-cli/commands/cache" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/monitor" - "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/commands/updatecheck" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" @@ -174,19 +172,19 @@ func (s *ArduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionReq // NewSketch FIXMEDOC func (s *ArduinoCoreServerImpl) NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { - resp, err := sketch.NewSketch(ctx, req) + resp, err := NewSketch(ctx, req) return resp, convertErrorToRPCStatus(err) } // LoadSketch FIXMEDOC func (s *ArduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { - resp, err := sketch.LoadSketch(ctx, req) + resp, err := LoadSketch(ctx, req) return &rpc.LoadSketchResponse{Sketch: resp}, convertErrorToRPCStatus(err) } // SetSketchDefaults FIXMEDOC func (s *ArduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) { - resp, err := sketch.SetSketchDefaults(ctx, req) + resp, err := SetSketchDefaults(ctx, req) return resp, convertErrorToRPCStatus(err) } @@ -449,7 +447,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) + resp, err := ArchiveSketch(ctx, req) return resp, convertErrorToRPCStatus(err) } @@ -475,7 +473,7 @@ func (s *ArduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequ // EnumerateMonitorPortSettings FIXMEDOC func (s *ArduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { - resp, err := monitor.EnumerateMonitorPortSettings(ctx, req) + resp, err := EnumerateMonitorPortSettings(ctx, req) return resp, convertErrorToRPCStatus(err) } @@ -493,7 +491,7 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer if openReq == nil { return &cmderrors.InvalidInstanceError{} } - portProxy, _, err := monitor.Monitor(stream.Context(), openReq) + portProxy, _, err := Monitor(stream.Context(), openReq) if err != nil { return err } diff --git a/commands/monitor/monitor.go b/commands/service_monitor.go similarity index 92% rename from commands/monitor/monitor.go rename to commands/service_monitor.go index 357a885be31..538e99795bb 100644 --- a/commands/monitor/monitor.go +++ b/commands/service_monitor.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package monitor +package commands import ( "context" @@ -25,42 +25,39 @@ import ( "github.com/arduino/arduino-cli/internal/arduino/cores" "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" pluggableMonitor "github.com/arduino/arduino-cli/internal/arduino/monitor" - "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-properties-orderedmap" "github.com/sirupsen/logrus" ) -var tr = i18n.Tr - -// PortProxy is an io.ReadWriteCloser that maps into the monitor port of the board -type PortProxy struct { +// portProxy is an io.ReadWriteCloser that maps into the monitor port of the board +type portProxy struct { rw io.ReadWriter changeSettingsCB func(setting, value string) error closeCB func() error } -func (p *PortProxy) Read(buff []byte) (int, error) { +func (p *portProxy) Read(buff []byte) (int, error) { return p.rw.Read(buff) } -func (p *PortProxy) Write(buff []byte) (int, error) { +func (p *portProxy) Write(buff []byte) (int, error) { return p.rw.Write(buff) } // Config sets the port configuration setting to the specified value -func (p *PortProxy) Config(setting, value string) error { +func (p *portProxy) Config(setting, value string) error { return p.changeSettingsCB(setting, value) } // Close the port -func (p *PortProxy) Close() error { +func (p *portProxy) Close() error { return p.closeCB() } // Monitor opens a communication port. It returns a PortProxy to communicate with the port and a PortDescriptor // that describes the available configuration settings. -func Monitor(ctx context.Context, req *rpc.MonitorPortOpenRequest) (*PortProxy, *pluggableMonitor.PortDescriptor, error) { +func Monitor(ctx context.Context, req *rpc.MonitorPortOpenRequest) (*portProxy, *pluggableMonitor.PortDescriptor, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, nil, err @@ -103,7 +100,7 @@ func Monitor(ctx context.Context, req *rpc.MonitorPortOpenRequest) (*PortProxy, } logrus.Infof("Port %s successfully opened", req.GetPort().GetAddress()) - return &PortProxy{ + return &portProxy{ rw: monIO, changeSettingsCB: m.Configure, closeCB: func() error { diff --git a/commands/monitor/settings.go b/commands/service_monitor_settings.go similarity index 99% rename from commands/monitor/settings.go rename to commands/service_monitor_settings.go index f6d41c15219..d69164d281d 100644 --- a/commands/monitor/settings.go +++ b/commands/service_monitor_settings.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package monitor +package commands import ( "context" diff --git a/commands/sketch/set_defaults.go b/commands/service_set_sketch_defaults.go similarity index 99% rename from commands/sketch/set_defaults.go rename to commands/service_set_sketch_defaults.go index c53bc1b1ae5..e90b1ef58c4 100644 --- a/commands/sketch/set_defaults.go +++ b/commands/service_set_sketch_defaults.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package sketch +package commands import ( "context" diff --git a/commands/sketch/archive.go b/commands/service_sketch_archive.go similarity index 98% rename from commands/sketch/archive.go rename to commands/service_sketch_archive.go index 8f843dbca6b..b2b28ae4bdd 100644 --- a/commands/sketch/archive.go +++ b/commands/service_sketch_archive.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package sketch +package commands import ( "archive/zip" @@ -24,13 +24,10 @@ import ( "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/internal/arduino/sketch" - "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" ) -var tr = i18n.Tr - // ArchiveSketch FIXMEDOC func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { // sketchName is the name of the sketch without extension, for example "MySketch" diff --git a/commands/sketch/load.go b/commands/service_sketch_load.go similarity index 98% rename from commands/sketch/load.go rename to commands/service_sketch_load.go index 5dadb0113c4..ffca3016715 100644 --- a/commands/sketch/load.go +++ b/commands/service_sketch_load.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package sketch +package commands import ( "context" diff --git a/commands/sketch/load_test.go b/commands/service_sketch_load_test.go similarity index 98% rename from commands/sketch/load_test.go rename to commands/service_sketch_load_test.go index bfae0e6a959..9d058e7035f 100644 --- a/commands/sketch/load_test.go +++ b/commands/service_sketch_load_test.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package sketch +package commands import ( "context" diff --git a/commands/sketch/new.go b/commands/service_sketch_new.go similarity index 99% rename from commands/sketch/new.go rename to commands/service_sketch_new.go index 5a7f6003e29..1a39615c9eb 100644 --- a/commands/sketch/new.go +++ b/commands/service_sketch_new.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package sketch +package commands import ( "context" diff --git a/commands/sketch/new_test.go b/commands/service_sketch_new_test.go similarity index 99% rename from commands/sketch/new_test.go rename to commands/service_sketch_new_test.go index 00ae7856732..0ba8b56767c 100644 --- a/commands/sketch/new_test.go +++ b/commands/service_sketch_new_test.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package sketch +package commands import ( "context" diff --git a/commands/sketch/testdata/sketch_with_profile/sketch.yml b/commands/testdata/sketch_with_profile/sketch.yml similarity index 100% rename from commands/sketch/testdata/sketch_with_profile/sketch.yml rename to commands/testdata/sketch_with_profile/sketch.yml diff --git a/commands/sketch/testdata/sketch_with_profile/sketch_with_profile.ino b/commands/testdata/sketch_with_profile/sketch_with_profile.ino similarity index 100% rename from commands/sketch/testdata/sketch_with_profile/sketch_with_profile.ino rename to commands/testdata/sketch_with_profile/sketch_with_profile.ino diff --git a/internal/cli/arguments/sketch.go b/internal/cli/arguments/sketch.go index 3b6d9d2c26d..57a3463bcc3 100644 --- a/internal/cli/arguments/sketch.go +++ b/internal/cli/arguments/sketch.go @@ -18,7 +18,7 @@ package arguments import ( "context" - "github.com/arduino/arduino-cli/commands/sketch" + "github.com/arduino/arduino-cli/commands" f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -52,7 +52,7 @@ func GetSketchProfiles(sketchPath string) []string { return nil } } - sk, err := sketch.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath}) + sk, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath}) if err != nil { return nil } diff --git a/internal/cli/board/attach.go b/internal/cli/board/attach.go index b340193e609..b7a943f8cfa 100644 --- a/internal/cli/board/attach.go +++ b/internal/cli/board/attach.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/sketch" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -59,7 +59,7 @@ func runAttachCommand(path string, port *arguments.Port, fqbn string, programmer sketchPath := arguments.InitSketchPath(path) portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(nil, "", "") - newDefaults, err := sketch.SetSketchDefaults(context.Background(), &rpc.SetSketchDefaultsRequest{ + newDefaults, err := commands.SetSketchDefaults(context.Background(), &rpc.SetSketchDefaultsRequest{ SketchPath: sketchPath.String(), DefaultFqbn: fqbn, DefaultProgrammer: programmer.GetProgrammer(), diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 5a379bb8f73..f2b36b41e75 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -26,7 +26,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" @@ -157,7 +156,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) { } sketchPath := arguments.InitSketchPath(path) - sk, err := sketch.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + sk, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index 8ead18d8c1b..99a4e4ca8b9 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -22,9 +22,9 @@ import ( "os" "os/signal" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/debug" - "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -83,7 +83,7 @@ func runDebugCommand(args []string, portArgs *arguments.Port, fqbnArg *arguments } sketchPath := arguments.InitSketchPath(path) - sk, err := sketch.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + sk, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index aacf38bd9b3..1309210cad6 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -26,8 +26,7 @@ import ( "strings" "time" - "github.com/arduino/arduino-cli/commands/monitor" - sk "github.com/arduino/arduino-cli/commands/sketch" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -104,7 +103,7 @@ func runMonitorCmd( // If only --port is set we read the fqbn in the following order: default_fqbn -> discovery // If only --fqbn is set we read the port in the following order: default_port sketchPath := arguments.InitSketchPath(sketchPathArg) - sketch, err := sk.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + sketch, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if err != nil && !portArgs.IsPortFlagSet() { feedback.Fatal( tr("Error getting default port from `sketch.yaml`. Check if you're in the correct sketch folder or provide the --port flag: %s", err), @@ -145,7 +144,7 @@ func runMonitorCmd( feedback.FatalError(err, feedback.ErrGeneric) } - enumerateResp, err := monitor.EnumerateMonitorPortSettings(context.Background(), &rpc.EnumerateMonitorPortSettingsRequest{ + enumerateResp, err := commands.EnumerateMonitorPortSettings(context.Background(), &rpc.EnumerateMonitorPortSettingsRequest{ Instance: inst, PortProtocol: portProtocol, Fqbn: fqbn, @@ -203,7 +202,7 @@ func runMonitorCmd( } } } - portProxy, _, err := monitor.Monitor(context.Background(), &rpc.MonitorPortOpenRequest{ + portProxy, _, err := commands.Monitor(context.Background(), &rpc.MonitorPortOpenRequest{ Instance: inst, Port: &rpc.Port{Address: portAddress, Protocol: portProtocol}, Fqbn: fqbn, diff --git a/internal/cli/sketch/archive.go b/internal/cli/sketch/archive.go index fc0875be9fb..9b8836daba3 100644 --- a/internal/cli/sketch/archive.go +++ b/internal/cli/sketch/archive.go @@ -20,7 +20,7 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands/sketch" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -66,13 +66,13 @@ func runArchiveCommand(args []string, includeBuildDir bool, overwrite bool) { } sketchPath := arguments.InitSketchPath(sketchPathArg) - sk, err := sketch.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + sk, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } feedback.WarnAboutDeprecatedFiles(sk) - if _, err := sketch.ArchiveSketch(context.Background(), + if _, err := commands.ArchiveSketch(context.Background(), &rpc.ArchiveSketchRequest{ SketchPath: sketchPath.String(), ArchivePath: archivePathArg, diff --git a/internal/cli/sketch/new.go b/internal/cli/sketch/new.go index 3514a05556b..1bfdf36c764 100644 --- a/internal/cli/sketch/new.go +++ b/internal/cli/sketch/new.go @@ -20,7 +20,7 @@ import ( "os" "strings" - sk "github.com/arduino/arduino-cli/commands/sketch" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/arduino/globals" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -72,7 +72,7 @@ func runNewCommand(args []string, overwrite bool) { sketchName = sketchDirPath.Base() } - _, err = sk.NewSketch(context.Background(), &rpc.NewSketchRequest{ + _, err = commands.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: sketchName, SketchDir: sketchDir, Overwrite: overwrite, diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 7ab259c6ae3..8641d746c49 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -24,7 +24,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" - sk "github.com/arduino/arduino-cli/commands/sketch" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -90,7 +89,7 @@ func runUploadCommand(args []string, uploadFieldsArgs map[string]string) { path = args[0] } sketchPath := arguments.InitSketchPath(path) - sketch, err := sk.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + sketch, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if importDir == "" && importFile == "" { if err != nil { feedback.Fatal(tr("Error during Upload: %v", err), feedback.ErrGeneric) From 61e5c461641f611298b4a7995c729c88a420c13b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 13:26:38 +0100 Subject: [PATCH 05/56] Moved a batch of function from commands/* subpackage to commands (part 5) --- commands/service_debug.go | 7 +++---- commands/{debug/debug_info.go => service_debug_config.go} | 2 +- commands/{debug/debug.go => service_debug_run.go} | 5 +---- commands/{debug/debug_test.go => service_debug_test.go} | 8 ++++---- .../debug}/custom_hardware/arduino-test/samd/boards.txt | 0 .../debug}/custom_hardware/arduino-test/samd/platform.txt | 0 .../custom_hardware/arduino-test/samd/programmers.txt | 0 .../arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-gdb | 0 .../tools/openocd/0.10.0-arduino7/bin/openocd | 0 .../arduino-test.samd.arduino_zero_edbg/hello.ino.bin | 0 .../hello/build/arduino-test.samd.mkr1000/hello.ino.bin | 0 .../{debug/testdata => testdata/debug}/hello/hello.ino | 0 internal/cli/debug/debug.go | 5 ++--- internal/cli/debug/debug_check.go | 4 ++-- 14 files changed, 13 insertions(+), 18 deletions(-) rename commands/{debug/debug_info.go => service_debug_config.go} (99%) rename commands/{debug/debug.go => service_debug_run.go} (98%) rename commands/{debug/debug_test.go => service_debug_test.go} (97%) rename commands/{debug/testdata => testdata/debug}/custom_hardware/arduino-test/samd/boards.txt (100%) rename commands/{debug/testdata => testdata/debug}/custom_hardware/arduino-test/samd/platform.txt (100%) rename commands/{debug/testdata => testdata/debug}/custom_hardware/arduino-test/samd/programmers.txt (100%) rename commands/{debug/testdata => testdata/debug}/data_dir/packages/arduino-test/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-gdb (100%) rename commands/{debug/testdata => testdata/debug}/data_dir/packages/arduino-test/tools/openocd/0.10.0-arduino7/bin/openocd (100%) rename commands/{debug/testdata => testdata/debug}/hello/build/arduino-test.samd.arduino_zero_edbg/hello.ino.bin (100%) rename commands/{debug/testdata => testdata/debug}/hello/build/arduino-test.samd.mkr1000/hello.ino.bin (100%) rename commands/{debug/testdata => testdata/debug}/hello/hello.ino (100%) diff --git a/commands/service_debug.go b/commands/service_debug.go index 363f77da862..78af8c12371 100644 --- a/commands/service_debug.go +++ b/commands/service_debug.go @@ -20,7 +20,6 @@ import ( "errors" "os" - cmd "github.com/arduino/arduino-cli/commands/debug" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) @@ -44,7 +43,7 @@ func (s *ArduinoCoreServerImpl) Debug(stream rpc.ArduinoCoreService_DebugServer) signalChan := make(chan os.Signal) defer close(signalChan) outStream := feedStreamTo(func(data []byte) { stream.Send(&rpc.DebugResponse{Data: data}) }) - resp, debugErr := cmd.Debug(stream.Context(), req, + resp, debugErr := Debug(stream.Context(), req, consumeStreamFrom(func() ([]byte, error) { command, err := stream.Recv() if command.GetSendInterrupt() { @@ -63,12 +62,12 @@ func (s *ArduinoCoreServerImpl) Debug(stream rpc.ArduinoCoreService_DebugServer) // GetDebugConfig return metadata about a debug session func (s *ArduinoCoreServerImpl) GetDebugConfig(ctx context.Context, req *rpc.GetDebugConfigRequest) (*rpc.GetDebugConfigResponse, error) { - res, err := cmd.GetDebugConfig(ctx, req) + res, err := GetDebugConfig(ctx, req) return res, convertErrorToRPCStatus(err) } // IsDebugSupported checks if debugging is supported for a given configuration func (s *ArduinoCoreServerImpl) IsDebugSupported(ctx context.Context, req *rpc.IsDebugSupportedRequest) (*rpc.IsDebugSupportedResponse, error) { - res, err := cmd.IsDebugSupported(ctx, req) + res, err := IsDebugSupported(ctx, req) return res, convertErrorToRPCStatus(err) } diff --git a/commands/debug/debug_info.go b/commands/service_debug_config.go similarity index 99% rename from commands/debug/debug_info.go rename to commands/service_debug_config.go index 5528dd53b8f..0f4040011f8 100644 --- a/commands/debug/debug_info.go +++ b/commands/service_debug_config.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package debug +package commands import ( "context" diff --git a/commands/debug/debug.go b/commands/service_debug_run.go similarity index 98% rename from commands/debug/debug.go rename to commands/service_debug_run.go index 431c8fcb830..47ecbf4fe04 100644 --- a/commands/debug/debug.go +++ b/commands/service_debug_run.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package debug +package commands import ( "context" @@ -27,14 +27,11 @@ import ( "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" - "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" ) -var tr = i18n.Tr - // Debug command launches a debug tool for a sketch. // It also implements streams routing: // gRPC In -> tool stdIn diff --git a/commands/debug/debug_test.go b/commands/service_debug_test.go similarity index 97% rename from commands/debug/debug_test.go rename to commands/service_debug_test.go index 9ca9d7cf056..e3bb45b0fd8 100644 --- a/commands/debug/debug_test.go +++ b/commands/service_debug_test.go @@ -12,7 +12,7 @@ // 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 debug +package commands import ( "fmt" @@ -30,10 +30,10 @@ import ( ) func TestGetCommandLine(t *testing.T) { - customHardware := paths.New("testdata", "custom_hardware") - dataDir := paths.New("testdata", "data_dir", "packages") + customHardware := paths.New("testdata", "debug", "custom_hardware") + dataDir := paths.New("testdata", "debug", "data_dir", "packages") sketch := "hello" - sketchPath := paths.New("testdata", sketch) + sketchPath := paths.New("testdata", "debug", sketch) require.NoError(t, sketchPath.ToAbs()) pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test") diff --git a/commands/debug/testdata/custom_hardware/arduino-test/samd/boards.txt b/commands/testdata/debug/custom_hardware/arduino-test/samd/boards.txt similarity index 100% rename from commands/debug/testdata/custom_hardware/arduino-test/samd/boards.txt rename to commands/testdata/debug/custom_hardware/arduino-test/samd/boards.txt diff --git a/commands/debug/testdata/custom_hardware/arduino-test/samd/platform.txt b/commands/testdata/debug/custom_hardware/arduino-test/samd/platform.txt similarity index 100% rename from commands/debug/testdata/custom_hardware/arduino-test/samd/platform.txt rename to commands/testdata/debug/custom_hardware/arduino-test/samd/platform.txt diff --git a/commands/debug/testdata/custom_hardware/arduino-test/samd/programmers.txt b/commands/testdata/debug/custom_hardware/arduino-test/samd/programmers.txt similarity index 100% rename from commands/debug/testdata/custom_hardware/arduino-test/samd/programmers.txt rename to commands/testdata/debug/custom_hardware/arduino-test/samd/programmers.txt diff --git a/commands/debug/testdata/data_dir/packages/arduino-test/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-gdb b/commands/testdata/debug/data_dir/packages/arduino-test/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-gdb similarity index 100% rename from commands/debug/testdata/data_dir/packages/arduino-test/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-gdb rename to commands/testdata/debug/data_dir/packages/arduino-test/tools/arm-none-eabi-gcc/7-2017q4/bin/arm-none-eabi-gdb diff --git a/commands/debug/testdata/data_dir/packages/arduino-test/tools/openocd/0.10.0-arduino7/bin/openocd b/commands/testdata/debug/data_dir/packages/arduino-test/tools/openocd/0.10.0-arduino7/bin/openocd similarity index 100% rename from commands/debug/testdata/data_dir/packages/arduino-test/tools/openocd/0.10.0-arduino7/bin/openocd rename to commands/testdata/debug/data_dir/packages/arduino-test/tools/openocd/0.10.0-arduino7/bin/openocd diff --git a/commands/debug/testdata/hello/build/arduino-test.samd.arduino_zero_edbg/hello.ino.bin b/commands/testdata/debug/hello/build/arduino-test.samd.arduino_zero_edbg/hello.ino.bin similarity index 100% rename from commands/debug/testdata/hello/build/arduino-test.samd.arduino_zero_edbg/hello.ino.bin rename to commands/testdata/debug/hello/build/arduino-test.samd.arduino_zero_edbg/hello.ino.bin diff --git a/commands/debug/testdata/hello/build/arduino-test.samd.mkr1000/hello.ino.bin b/commands/testdata/debug/hello/build/arduino-test.samd.mkr1000/hello.ino.bin similarity index 100% rename from commands/debug/testdata/hello/build/arduino-test.samd.mkr1000/hello.ino.bin rename to commands/testdata/debug/hello/build/arduino-test.samd.mkr1000/hello.ino.bin diff --git a/commands/debug/testdata/hello/hello.ino b/commands/testdata/debug/hello/hello.ino similarity index 100% rename from commands/debug/testdata/hello/hello.ino rename to commands/testdata/debug/hello/hello.ino diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index 99a4e4ca8b9..631b9046595 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -24,7 +24,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/commands/debug" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -124,7 +123,7 @@ func runDebugCommand(args []string, portArgs *arguments.Port, fqbnArg *arguments if printInfo { - if res, err := debug.GetDebugConfig(context.Background(), debugConfigRequested); err != nil { + if res, err := commands.GetDebugConfig(context.Background(), debugConfigRequested); err != nil { errcode := feedback.ErrBadArgument if errors.Is(err, &cmderrors.MissingProgrammerError{}) { errcode = feedback.ErrMissingProgrammer @@ -144,7 +143,7 @@ func runDebugCommand(args []string, portArgs *arguments.Port, fqbnArg *arguments if err != nil { feedback.FatalError(err, feedback.ErrBadArgument) } - if _, err := debug.Debug(context.Background(), debugConfigRequested, in, out, ctrlc); err != nil { + if _, err := commands.Debug(context.Background(), debugConfigRequested, in, out, ctrlc); err != nil { errcode := feedback.ErrGeneric if errors.Is(err, &cmderrors.MissingProgrammerError{}) { errcode = feedback.ErrMissingProgrammer diff --git a/internal/cli/debug/debug_check.go b/internal/cli/debug/debug_check.go index 52e25d40577..a4bfafac879 100644 --- a/internal/cli/debug/debug_check.go +++ b/internal/cli/debug/debug_check.go @@ -19,7 +19,7 @@ import ( "context" "os" - "github.com/arduino/arduino-cli/commands/debug" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -60,7 +60,7 @@ func runDebugCheckCommand(portArgs *arguments.Port, fqbnArg *arguments.Fqbn, int feedback.FatalError(err, feedback.ErrBadArgument) } fqbn := fqbnArg.String() - resp, err := debug.IsDebugSupported(context.Background(), &rpc.IsDebugSupportedRequest{ + resp, err := commands.IsDebugSupported(context.Background(), &rpc.IsDebugSupportedRequest{ Instance: instance, Fqbn: fqbn, Port: port, From 9e75b4d6b3358410c9095e25fc7cb8cd846e6916 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 13:27:52 +0100 Subject: [PATCH 06/56] Removed unused parameters --- commands/service_library_install.go | 2 +- commands/service_library_resolve_deps.go | 4 ++-- commands/service_platform_uninstall.go | 4 ++-- commands/service_upload.go | 4 ++-- commands/service_upload_test.go | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/commands/service_library_install.go b/commands/service_library_install.go index b9fa369ebe0..021eada534f 100644 --- a/commands/service_library_install.go +++ b/commands/service_library_install.go @@ -51,7 +51,7 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, downloa return err } - res, err := libraryResolveDependencies(ctx, lme, li, req.GetName(), req.GetVersion(), req.GetNoOverwrite()) + res, err := libraryResolveDependencies(lme, li, req.GetName(), req.GetVersion(), req.GetNoOverwrite()) releaseLme() if err != nil { return err diff --git a/commands/service_library_resolve_deps.go b/commands/service_library_resolve_deps.go index 5699cbf4052..ccfef15b742 100644 --- a/commands/service_library_resolve_deps.go +++ b/commands/service_library_resolve_deps.go @@ -42,10 +42,10 @@ func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDepe return nil, err } - return libraryResolveDependencies(ctx, lme, li, req.GetName(), req.GetVersion(), req.GetDoNotUpdateInstalledLibraries()) + return libraryResolveDependencies(lme, li, req.GetName(), req.GetVersion(), req.GetDoNotUpdateInstalledLibraries()) } -func libraryResolveDependencies(ctx context.Context, lme *librariesmanager.Explorer, li *librariesindex.Index, +func libraryResolveDependencies(lme *librariesmanager.Explorer, li *librariesindex.Index, reqName, reqVersion string, noOverwrite bool) (*rpc.LibraryResolveDependenciesResponse, error) { version, err := ParseVersion(reqVersion) if err != nil { diff --git a/commands/service_platform_uninstall.go b/commands/service_platform_uninstall.go index 26a2e404d58..9459a92ba86 100644 --- a/commands/service_platform_uninstall.go +++ b/commands/service_platform_uninstall.go @@ -26,7 +26,7 @@ import ( // PlatformUninstall FIXMEDOC func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgressCB) (*rpc.PlatformUninstallResponse, error) { - if err := platformUninstall(ctx, req, taskCB); err != nil { + if err := platformUninstall(req, taskCB); err != nil { return nil, err } if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { @@ -36,7 +36,7 @@ func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, t } // platformUninstall is the implementation of platform unistaller -func platformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgressCB) error { +func platformUninstall(req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgressCB) error { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return &cmderrors.InvalidInstanceError{} diff --git a/commands/service_upload.go b/commands/service_upload.go index 15df0cb295c..a364f3f88f2 100644 --- a/commands/service_upload.go +++ b/commands/service_upload.go @@ -371,7 +371,7 @@ func runProgramAction(pme *packagemanager.Explorer, } if !burnBootloader { - importPath, sketchName, err := determineBuildPathAndSketchName(importFile, importDir, sk, fqbn) + importPath, sketchName, err := determineBuildPathAndSketchName(importFile, importDir, sk) if err != nil { return nil, &cmderrors.NotFoundError{Message: tr("Error finding build artifacts"), Cause: err} } @@ -674,7 +674,7 @@ func runTool(recipeID string, props *properties.Map, outStream, errStream io.Wri return nil } -func determineBuildPathAndSketchName(importFile, importDir string, sk *sketch.Sketch, fqbn *cores.FQBN) (*paths.Path, string, error) { +func determineBuildPathAndSketchName(importFile, importDir string, sk *sketch.Sketch) (*paths.Path, string, error) { // In general, compiling a sketch will produce a set of files that are // named as the sketch but have different extensions, for example Sketch.ino // may produce: Sketch.ino.bin; Sketch.ino.hex; Sketch.ino.zip; etc... diff --git a/commands/service_upload_test.go b/commands/service_upload_test.go index f50f06c4583..cf2f4ff3306 100644 --- a/commands/service_upload_test.go +++ b/commands/service_upload_test.go @@ -109,7 +109,7 @@ func TestDetermineBuildPathAndSketchName(t *testing.T) { } for i, test := range tests { t.Run(fmt.Sprintf("SubTest%02d", i), func(t *testing.T) { - buildPath, sketchName, err := determineBuildPathAndSketchName(test.importFile, test.importDir, test.sketch, test.fqbn) + buildPath, sketchName, err := determineBuildPathAndSketchName(test.importFile, test.importDir, test.sketch) if test.resBuildPath == "" { require.Error(t, err) require.Nil(t, buildPath) From f1a015c7a0305faf80cf2f755cc236ca7295047a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 13:28:41 +0100 Subject: [PATCH 07/56] Removed unused file --- commands/lib.go | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 commands/lib.go diff --git a/commands/lib.go b/commands/lib.go deleted file mode 100644 index 8794f4ea94a..00000000000 --- a/commands/lib.go +++ /dev/null @@ -1,46 +0,0 @@ -// 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" - "context" -) - -func (s *Service) ListLibraries(ctx context.Context, in *ListLibrariesReq) (*ListLibrariesResp, error) { - if in.Instance == nil { - return nil, fmt.Errorf("invalid request") - } - instance, ok := instances[in.Instance.Id] - if !ok { - return nil, fmt.Errorf("instance not found") - } - libs := lib.ListLibraries(instance.lm, in.Updatable) - - result := []*pb.Library{} - for _, lib := range libs.Libraries { - result = append(result, &pb.Library{ - Name: lib.Library.Name, - Paragraph: lib.Library.Paragraph, - Precompiled: lib.Library.Precompiled, - }) - } - return &pb.ListLibrariesResp{ - Libraries: result, - }, nil -} -*/ From c4ca8522c5afe069166bbbb5307c0f77ceb30e7a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 14:09:23 +0100 Subject: [PATCH 08/56] Removed ToRPCStatus in favor of standardized GRPCStatus() interface This change avoids the ugly 'convertErrorToRPCStatus' helper method since the gRPC server automatically recognize if the error implements the `GRPCStatus() *Status` interface method. --- commands/cmderrors/cmderrors.go | 192 +++++++++--------- commands/instances.go | 26 +-- commands/service.go | 104 ++++------ commands/service_debug.go | 6 +- .../integrationtest/daemon/daemon_test.go | 4 +- 5 files changed, 149 insertions(+), 183 deletions(-) diff --git a/commands/cmderrors/cmderrors.go b/commands/cmderrors/cmderrors.go index e6794ffdee9..a5024a37a26 100644 --- a/commands/cmderrors/cmderrors.go +++ b/commands/cmderrors/cmderrors.go @@ -37,8 +37,8 @@ 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 + // GRPCStatus convertes the error into a *status.Status + GRPCStatus() *status.Status } // InvalidInstanceError is returned if the instance used in the command is not valid. @@ -48,8 +48,8 @@ func (e *InvalidInstanceError) Error() string { return tr("Invalid instance") } -// ToRPCStatus converts the error into a *status.Status -func (e *InvalidInstanceError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InvalidInstanceError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -62,8 +62,8 @@ func (e *InvalidFQBNError) Error() string { return composeErrorMsg(tr("Invalid FQBN"), e.Cause) } -// ToRPCStatus converts the error into a *status.Status -func (e *InvalidFQBNError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InvalidFQBNError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -80,8 +80,8 @@ func (e *InvalidURLError) Error() string { return composeErrorMsg(tr("Invalid URL"), e.Cause) } -// ToRPCStatus converts the error into a *status.Status -func (e *InvalidURLError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InvalidURLError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -98,8 +98,8 @@ func (e *InvalidLibraryError) Error() string { return composeErrorMsg(tr("Invalid library"), e.Cause) } -// ToRPCStatus converts the error into a *status.Status -func (e *InvalidLibraryError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InvalidLibraryError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -116,8 +116,8 @@ func (e *InvalidVersionError) Error() string { return composeErrorMsg(tr("Invalid version"), e.Cause) } -// ToRPCStatus converts the error into a *status.Status -func (e *InvalidVersionError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InvalidVersionError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -139,8 +139,8 @@ func (e *NoBoardsDetectedError) Error() string { ) } -// ToRPCStatus converts the error into a *status.Status -func (e *NoBoardsDetectedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *NoBoardsDetectedError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -159,8 +159,8 @@ func (e *MultipleBoardsDetectedError) Error() string { ) } -// ToRPCStatus converts the error into a *status.Status -func (e *MultipleBoardsDetectedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MultipleBoardsDetectedError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -171,8 +171,8 @@ func (e *MissingFQBNError) Error() string { return tr("Missing FQBN (Fully Qualified Board Name)") } -// ToRPCStatus converts the error into a *status.Status -func (e *MissingFQBNError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MissingFQBNError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -189,8 +189,8 @@ func (e *UnknownFQBNError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *UnknownFQBNError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *UnknownFQBNError) GRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -208,8 +208,8 @@ func (e *UnknownProfileError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *UnknownProfileError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *UnknownProfileError) GRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -226,8 +226,8 @@ func (e *InvalidProfileError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *InvalidProfileError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InvalidProfileError) GRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -238,8 +238,8 @@ func (e *MissingPortAddressError) Error() string { return tr("Missing port address") } -// ToRPCStatus converts the error into a *status.Status -func (e *MissingPortAddressError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MissingPortAddressError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -250,8 +250,8 @@ func (e *MissingPortProtocolError) Error() string { return tr("Missing port protocol") } -// ToRPCStatus converts the error into a *status.Status -func (e *MissingPortProtocolError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MissingPortProtocolError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -262,8 +262,8 @@ func (e *MissingPortError) Error() string { return tr("Missing port") } -// ToRPCStatus converts the error into a *status.Status -func (e *MissingPortError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MissingPortError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -276,8 +276,8 @@ func (e *NoMonitorAvailableForProtocolError) Error() string { return tr("No monitor available for the port protocol %s", e.Protocol) } -// ToRPCStatus converts the error into a *status.Status -func (e *NoMonitorAvailableForProtocolError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *NoMonitorAvailableForProtocolError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -288,8 +288,8 @@ func (e *MissingProgrammerError) Error() string { return tr("Missing programmer") } -// ToRPCStatus converts the error into a *status.Status -func (e *MissingProgrammerError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MissingProgrammerError) GRPCStatus() *status.Status { s, _ := status.New(codes.InvalidArgument, e.Error()).WithDetails(&rpc.MissingProgrammerError{}) return s } @@ -301,8 +301,8 @@ func (e *ProgrammerRequiredForUploadError) Error() string { return tr("A programmer is required to upload") } -// ToRPCStatus converts the error into a *status.Status -func (e *ProgrammerRequiredForUploadError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *ProgrammerRequiredForUploadError) GRPCStatus() *status.Status { st, _ := status. New(codes.InvalidArgument, e.Error()). WithDetails(&rpc.ProgrammerIsRequiredForUploadError{}) @@ -320,8 +320,8 @@ func (ife *InitFailedError) Error() string { return ife.Cause.Error() } -// ToRPCStatus converts the error into a *status.Status -func (ife *InitFailedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (ife *InitFailedError) GRPCStatus() *status.Status { st, _ := status. New(ife.Code, ife.Cause.Error()). WithDetails(&rpc.FailedInstanceInitError{ @@ -345,8 +345,8 @@ func (e *ProgrammerNotFoundError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *ProgrammerNotFoundError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *ProgrammerNotFoundError) GRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -364,8 +364,8 @@ func (e *MonitorNotFoundError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *MonitorNotFoundError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MonitorNotFoundError) GRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -379,8 +379,8 @@ func (e *InvalidPlatformPropertyError) Error() string { return tr("Invalid '%[1]s' property: %[2]s", e.Property, e.Value) } -// ToRPCStatus converts the error into a *status.Status -func (e *InvalidPlatformPropertyError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InvalidPlatformPropertyError) GRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -393,8 +393,8 @@ func (e *MissingPlatformPropertyError) Error() string { return tr("Property '%s' is undefined", e.Property) } -// ToRPCStatus converts the error into a *status.Status -func (e *MissingPlatformPropertyError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MissingPlatformPropertyError) GRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -408,8 +408,8 @@ func (e *PlatformNotFoundError) Error() string { return composeErrorMsg(tr("Platform '%s' not found", e.Platform), e.Cause) } -// ToRPCStatus converts the error into a *status.Status -func (e *PlatformNotFoundError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *PlatformNotFoundError) GRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -426,8 +426,8 @@ func (e *PlatformLoadingError) Error() string { return composeErrorMsg(tr("Error loading hardware platform"), e.Cause) } -// ToRPCStatus converts the error into a *status.Status -func (e *PlatformLoadingError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *PlatformLoadingError) GRPCStatus() *status.Status { s, _ := status.New(codes.FailedPrecondition, e.Error()). WithDetails(&rpc.PlatformLoadingError{}) return s @@ -447,8 +447,8 @@ func (e *LibraryNotFoundError) Error() string { return composeErrorMsg(tr("Library '%s' not found", e.Library), e.Cause) } -// ToRPCStatus converts the error into a *status.Status -func (e *LibraryNotFoundError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *LibraryNotFoundError) GRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -466,8 +466,8 @@ func (e *LibraryDependenciesResolutionFailedError) Error() string { return composeErrorMsg(tr("No valid dependencies solution found"), e.Cause) } -// ToRPCStatus converts the error into a *status.Status -func (e *LibraryDependenciesResolutionFailedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *LibraryDependenciesResolutionFailedError) GRPCStatus() *status.Status { return status.New(codes.FailedPrecondition, e.Error()) } @@ -484,8 +484,8 @@ func (e *PlatformAlreadyAtTheLatestVersionError) Error() string { return tr("Platform '%s' is already at the latest version", e.Platform) } -// ToRPCStatus converts the error into a *status.Status -func (e *PlatformAlreadyAtTheLatestVersionError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *PlatformAlreadyAtTheLatestVersionError) GRPCStatus() *status.Status { st, _ := status. New(codes.AlreadyExists, e.Error()). WithDetails(&rpc.AlreadyAtLatestVersionError{}) @@ -499,8 +499,8 @@ func (e *MissingSketchPathError) Error() string { return tr("Missing sketch path") } -// ToRPCStatus converts the error into a *status.Status -func (e *MissingSketchPathError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MissingSketchPathError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -543,8 +543,8 @@ func (e *CantOpenSketchError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *CantOpenSketchError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *CantOpenSketchError) GRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -562,8 +562,8 @@ func (e *FailedInstallError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *FailedInstallError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *FailedInstallError) GRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -580,8 +580,8 @@ func (e *FailedLibraryInstallError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *FailedLibraryInstallError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *FailedLibraryInstallError) GRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -599,8 +599,8 @@ func (e *FailedUninstallError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *FailedUninstallError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *FailedUninstallError) GRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -618,8 +618,8 @@ func (e *FailedDownloadError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *FailedDownloadError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *FailedDownloadError) GRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -637,8 +637,8 @@ func (e *FailedUploadError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *FailedUploadError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *FailedUploadError) GRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -656,8 +656,8 @@ func (e *FailedDebugError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *FailedDebugError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *FailedDebugError) GRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -674,8 +674,8 @@ func (e *FailedMonitorError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *FailedMonitorError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *FailedMonitorError) GRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -693,8 +693,8 @@ func (e *CompileFailedError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *CompileFailedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *CompileFailedError) GRPCStatus() *status.Status { return status.New(codes.Internal, e.Error()) } @@ -712,8 +712,8 @@ func (e *InvalidArgumentError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *InvalidArgumentError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InvalidArgumentError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -731,8 +731,8 @@ func (e *NotFoundError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *NotFoundError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *NotFoundError) GRPCStatus() *status.Status { return status.New(codes.NotFound, e.Error()) } @@ -750,8 +750,8 @@ func (e *PermissionDeniedError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *PermissionDeniedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *PermissionDeniedError) GRPCStatus() *status.Status { return status.New(codes.PermissionDenied, e.Error()) } @@ -769,8 +769,8 @@ func (e *UnavailableError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *UnavailableError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *UnavailableError) GRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -787,8 +787,8 @@ func (e *TempDirCreationFailedError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *TempDirCreationFailedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *TempDirCreationFailedError) GRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -805,8 +805,8 @@ func (e *TempFileCreationFailedError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *TempFileCreationFailedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *TempFileCreationFailedError) GRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -824,8 +824,8 @@ func (e *SignatureVerificationFailedError) Unwrap() error { return e.Cause } -// ToRPCStatus converts the error into a *status.Status -func (e *SignatureVerificationFailedError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *SignatureVerificationFailedError) GRPCStatus() *status.Status { return status.New(codes.Unavailable, e.Error()) } @@ -842,8 +842,8 @@ func (e *MultiplePlatformsError) Error() string { len(e.Platforms), e.UserPlatform, strings.Join(e.Platforms, ", ")) } -// ToRPCStatus converts the error into a *status.Status -func (e *MultiplePlatformsError) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MultiplePlatformsError) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -865,8 +865,8 @@ func (e *MultipleLibraryInstallDetected) Error() string { return res } -// ToRPCStatus converts the error into a *status.Status -func (e *MultipleLibraryInstallDetected) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *MultipleLibraryInstallDetected) GRPCStatus() *status.Status { return status.New(codes.InvalidArgument, e.Error()) } @@ -878,8 +878,8 @@ func (e *InstanceNeedsReinitialization) Error() string { return tr("The instance is no longer valid and needs to be reinitialized") } -// ToRPCStatus converts the error into a *status.Status -func (e *InstanceNeedsReinitialization) ToRPCStatus() *status.Status { +// GRPCStatus converts the error into a *status.Status +func (e *InstanceNeedsReinitialization) GRPCStatus() *status.Status { st, _ := status. New(codes.InvalidArgument, e.Error()). WithDetails(&rpc.InstanceNeedsReinitializationError{}) diff --git a/commands/instances.go b/commands/instances.go index 45f6a109f86..ba067358cca 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -162,7 +162,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro Cause: fmt.Errorf(tr("Invalid additional URL: %v", err)), Reason: rpc.FailedInstanceInitReason_FAILED_INSTANCE_INIT_REASON_INVALID_INDEX_URL, } - responseError(e.ToRPCStatus()) + responseError(e.GRPCStatus()) continue } allPackageIndexUrls = append(allPackageIndexUrls, URL) @@ -174,7 +174,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro Cause: err, Reason: rpc.FailedInstanceInitReason_FAILED_INSTANCE_INIT_REASON_INDEX_DOWNLOAD_ERROR, } - responseError(e.ToRPCStatus()) + responseError(e.GRPCStatus()) } { @@ -199,7 +199,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro Cause: fmt.Errorf(tr("Loading index file: %v", err)), Reason: rpc.FailedInstanceInitReason_FAILED_INSTANCE_INIT_REASON_INDEX_LOAD_ERROR, } - responseError(e.ToRPCStatus()) + responseError(e.GRPCStatus()) } continue } @@ -210,7 +210,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro Cause: fmt.Errorf(tr("Loading index file: %v", err)), Reason: rpc.FailedInstanceInitReason_FAILED_INSTANCE_INIT_REASON_INDEX_LOAD_ERROR, } - responseError(e.ToRPCStatus()) + responseError(e.GRPCStatus()) } } @@ -223,7 +223,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro if profile == nil { for _, err := range pmb.LoadHardware() { s := &cmderrors.PlatformLoadingError{Cause: err} - responseError(s.ToRPCStatus()) + responseError(s.GRPCStatus()) } } else { // Load platforms from profile @@ -232,7 +232,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro ) for _, err := range errs { s := &cmderrors.PlatformLoadingError{Cause: err} - responseError(s.ToRPCStatus()) + responseError(s.GRPCStatus()) } // Load "builtin" tools @@ -252,7 +252,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro Cause: fmt.Errorf(tr("can't find latest release of tool %s", name)), Reason: rpc.FailedInstanceInitReason_FAILED_INSTANCE_INIT_REASON_TOOL_LOAD_ERROR, } - responseError(e.ToRPCStatus()) + responseError(e.GRPCStatus()) } else if !latest.IsInstalled() { builtinToolsToInstall = append(builtinToolsToInstall, latest) } @@ -267,7 +267,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro Cause: err, Reason: rpc.FailedInstanceInitReason_FAILED_INSTANCE_INIT_REASON_TOOL_LOAD_ERROR, } - responseError(e.ToRPCStatus()) + responseError(e.GRPCStatus()) } } @@ -275,7 +275,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro // so we must reload again otherwise we would never found them. for _, err := range loadBuiltinTools() { s := &cmderrors.PlatformLoadingError{Cause: err} - responseError(s.ToRPCStatus()) + responseError(s.GRPCStatus()) } } @@ -290,7 +290,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro for _, err := range pme.LoadDiscoveries() { s := &cmderrors.PlatformLoadingError{Cause: err} - responseError(s.ToRPCStatus()) + responseError(s.GRPCStatus()) } // Create library manager and add libraries directories @@ -353,13 +353,13 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro if err != nil { taskCallback(&rpc.TaskProgress{Name: tr("Library %s not found", libraryRef)}) err := &cmderrors.LibraryNotFoundError{Library: libraryRef.Library} - responseError(err.ToRPCStatus()) + responseError(err.GRPCStatus()) continue } if err := libRelease.Resource.Download(pme.DownloadDir, nil, libRelease.String(), downloadCallback, ""); err != nil { taskCallback(&rpc.TaskProgress{Name: tr("Error downloading library %s", libraryRef)}) e := &cmderrors.FailedLibraryInstallError{Cause: err} - responseError(e.ToRPCStatus()) + responseError(e.GRPCStatus()) continue } taskCallback(&rpc.TaskProgress{Completed: true}) @@ -369,7 +369,7 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro if err := libRelease.Resource.Install(pme.DownloadDir, libRoot, libDir); err != nil { taskCallback(&rpc.TaskProgress{Name: tr("Error installing library %s", libraryRef)}) e := &cmderrors.FailedLibraryInstallError{Cause: err} - responseError(e.ToRPCStatus()) + responseError(e.GRPCStatus()) continue } taskCallback(&rpc.TaskProgress{Completed: true}) diff --git a/commands/service.go b/commands/service.go index 0b34c6250c8..88f03e5fed8 100644 --- a/commands/service.go +++ b/commands/service.go @@ -38,27 +38,16 @@ type ArduinoCoreServerImpl struct { VersionString string } -func convertErrorToRPCStatus(err error) error { - if err == nil { - return nil - } - if cmdErr, ok := err.(cmderrors.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 := BoardDetails(ctx, req) - return resp, convertErrorToRPCStatus(err) + return BoardDetails(ctx, req) } // BoardList FIXMEDOC func (s *ArduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { ports, _, err := BoardList(req) if err != nil { - return nil, convertErrorToRPCStatus(err) + return nil, err } return &rpc.BoardListResponse{ Ports: ports, @@ -67,14 +56,12 @@ 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 := BoardListAll(ctx, req) - return resp, convertErrorToRPCStatus(err) + return BoardListAll(ctx, req) } // 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 := BoardSearch(ctx, req) - return resp, convertErrorToRPCStatus(err) + return BoardSearch(ctx, req) } // BoardListWatch FIXMEDOC @@ -91,7 +78,7 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, s eventsChan, err := BoardListWatch(stream.Context(), req) if err != nil { - return convertErrorToRPCStatus(err) + return err } for event := range eventsChan { @@ -105,8 +92,7 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, s // Destroy FIXMEDOC func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { - resp, err := Destroy(ctx, req) - return resp, convertErrorToRPCStatus(err) + return Destroy(ctx, req) } // UpdateIndex FIXMEDOC @@ -124,7 +110,7 @@ func (s *ArduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream Message: &rpc.UpdateIndexResponse_Result_{Result: res}, }) } - return convertErrorToRPCStatus(err) + return err } // UpdateLibrariesIndex FIXMEDOC @@ -142,7 +128,7 @@ func (s *ArduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd Message: &rpc.UpdateLibrariesIndexResponse_Result_{Result: res}, }) } - return convertErrorToRPCStatus(err) + return err } // Create FIXMEDOC @@ -154,15 +140,13 @@ func (s *ArduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque if len(userAgent) == 0 { userAgent = []string{"gRPCClientUnknown/0.0.0"} } - res, err := Create(req, userAgent...) - return res, convertErrorToRPCStatus(err) + return Create(req, userAgent...) } // Init FIXMEDOC func (s *ArduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := Init(req, func(message *rpc.InitResponse) { syncSend.Send(message) }) - return convertErrorToRPCStatus(err) + return Init(req, func(message *rpc.InitResponse) { syncSend.Send(message) }) } // Version FIXMEDOC @@ -172,20 +156,18 @@ func (s *ArduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionReq // NewSketch FIXMEDOC func (s *ArduinoCoreServerImpl) NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { - resp, err := NewSketch(ctx, req) - return resp, convertErrorToRPCStatus(err) + return NewSketch(ctx, req) } // LoadSketch FIXMEDOC func (s *ArduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { resp, err := LoadSketch(ctx, req) - return &rpc.LoadSketchResponse{Sketch: resp}, convertErrorToRPCStatus(err) + return &rpc.LoadSketchResponse{Sketch: resp}, err } // SetSketchDefaults FIXMEDOC func (s *ArduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) { - resp, err := SetSketchDefaults(ctx, req) - return resp, convertErrorToRPCStatus(err) + return SetSketchDefaults(ctx, req) } // Compile FIXMEDOC @@ -218,7 +200,7 @@ func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu }) } if compileErr != nil { - return convertErrorToRPCStatus(compileErr) + return compileErr } return compileRespSendErr } @@ -232,7 +214,7 @@ func (s *ArduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) }, ) if err != nil { - return convertErrorToRPCStatus(err) + return err } return syncSend.Send(resp) } @@ -245,7 +227,7 @@ func (s *ArduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadReques func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformDownloadResponse{Progress: p}) }, ) if err != nil { - return convertErrorToRPCStatus(err) + return err } return syncSend.Send(resp) } @@ -258,7 +240,7 @@ func (s *ArduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequ func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) }, ) if err != nil { - return convertErrorToRPCStatus(err) + return err } return syncSend.Send(resp) } @@ -274,13 +256,12 @@ func (s *ArduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, if err2 := syncSend.Send(resp); err2 != nil { return err2 } - return convertErrorToRPCStatus(err) + return err } // PlatformSearch FIXMEDOC func (s *ArduinoCoreServerImpl) PlatformSearch(ctx context.Context, req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { - resp, err := PlatformSearch(req) - return resp, convertErrorToRPCStatus(err) + return PlatformSearch(req) } // Upload FIXMEDOC @@ -306,7 +287,7 @@ func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.Arduin }, }) } - return convertErrorToRPCStatus(err) + return err } // UploadUsingProgrammer FIXMEDOC @@ -330,15 +311,14 @@ func (s *ArduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgra outStream.Close() errStream.Close() if err != nil { - return convertErrorToRPCStatus(err) + return err } return nil } // SupportedUserFields FIXMEDOC func (s *ArduinoCoreServerImpl) SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsRequest) (*rpc.SupportedUserFieldsResponse, error) { - res, err := SupportedUserFields(ctx, req) - return res, convertErrorToRPCStatus(err) + return SupportedUserFields(ctx, req) } // BurnBootloader FIXMEDOC @@ -362,15 +342,14 @@ func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, s outStream.Close() errStream.Close() if err != nil { - return convertErrorToRPCStatus(err) + return err } return syncSend.Send(resp) } // ListProgrammersAvailableForUpload FIXMEDOC func (s *ArduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { - resp, err := ListProgrammersAvailableForUpload(ctx, req) - return resp, convertErrorToRPCStatus(err) + return ListProgrammersAvailableForUpload(ctx, req) } // LibraryDownload FIXMEDOC @@ -381,7 +360,7 @@ func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryDownloadResponse{Progress: p}) }, ) if err != nil { - return convertErrorToRPCStatus(err) + return err } return syncSend.Send(resp) } @@ -389,92 +368,81 @@ func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, // LibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, stream rpc.ArduinoCoreService_LibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := LibraryInstall( + return LibraryInstall( stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryInstallResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) }, ) - return convertErrorToRPCStatus(err) } // LibraryUpgrade FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, stream rpc.ArduinoCoreService_LibraryUpgradeServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := LibraryUpgrade( + return LibraryUpgrade( stream.Context(), req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{TaskProgress: p}) }, ) - return convertErrorToRPCStatus(err) } // LibraryUninstall FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallRequest, stream rpc.ArduinoCoreService_LibraryUninstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := LibraryUninstall(stream.Context(), req, + return LibraryUninstall(stream.Context(), req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) }, ) - return convertErrorToRPCStatus(err) } // LibraryUpgradeAll FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, stream rpc.ArduinoCoreService_LibraryUpgradeAllServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := LibraryUpgradeAll(req, + return LibraryUpgradeAll(req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) }, ) - return convertErrorToRPCStatus(err) } // LibraryResolveDependencies FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { - resp, err := LibraryResolveDependencies(ctx, req) - return resp, convertErrorToRPCStatus(err) + return LibraryResolveDependencies(ctx, req) } // LibrarySearch FIXMEDOC func (s *ArduinoCoreServerImpl) LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { - resp, err := LibrarySearch(ctx, req) - return resp, convertErrorToRPCStatus(err) + return LibrarySearch(ctx, req) } // LibraryList FIXMEDOC func (s *ArduinoCoreServerImpl) LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { - resp, err := LibraryList(ctx, req) - return resp, convertErrorToRPCStatus(err) + return LibraryList(ctx, req) } // ArchiveSketch FIXMEDOC func (s *ArduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { - resp, err := ArchiveSketch(ctx, req) - return resp, convertErrorToRPCStatus(err) + return ArchiveSketch(ctx, req) } // ZipLibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequest, stream rpc.ArduinoCoreService_ZipLibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := ZipLibraryInstall( + return ZipLibraryInstall( stream.Context(), req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.ZipLibraryInstallResponse{TaskProgress: p}) }, ) - return convertErrorToRPCStatus(err) } // GitLibraryInstall FIXMEDOC func (s *ArduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequest, stream rpc.ArduinoCoreService_GitLibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) - err := GitLibraryInstall( + return GitLibraryInstall( stream.Context(), req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.GitLibraryInstallResponse{TaskProgress: p}) }, ) - return convertErrorToRPCStatus(err) } // EnumerateMonitorPortSettings FIXMEDOC func (s *ArduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { - resp, err := EnumerateMonitorPortSettings(ctx, req) - return resp, convertErrorToRPCStatus(err) + return EnumerateMonitorPortSettings(ctx, req) } // Monitor FIXMEDOC diff --git a/commands/service_debug.go b/commands/service_debug.go index 78af8c12371..cb3f682219c 100644 --- a/commands/service_debug.go +++ b/commands/service_debug.go @@ -62,12 +62,10 @@ func (s *ArduinoCoreServerImpl) Debug(stream rpc.ArduinoCoreService_DebugServer) // GetDebugConfig return metadata about a debug session func (s *ArduinoCoreServerImpl) GetDebugConfig(ctx context.Context, req *rpc.GetDebugConfigRequest) (*rpc.GetDebugConfigResponse, error) { - res, err := GetDebugConfig(ctx, req) - return res, convertErrorToRPCStatus(err) + return GetDebugConfig(ctx, req) } // IsDebugSupported checks if debugging is supported for a given configuration func (s *ArduinoCoreServerImpl) IsDebugSupported(ctx context.Context, req *rpc.IsDebugSupportedRequest) (*rpc.IsDebugSupportedResponse, error) { - res, err := IsDebugSupported(ctx, req) - return res, convertErrorToRPCStatus(err) + return IsDebugSupported(ctx, req) } diff --git a/internal/integrationtest/daemon/daemon_test.go b/internal/integrationtest/daemon/daemon_test.go index 3bae601a01d..297ba4b59af 100644 --- a/internal/integrationtest/daemon/daemon_test.go +++ b/internal/integrationtest/daemon/daemon_test.go @@ -503,7 +503,7 @@ func TestDaemonCoreUpgradePlatform(t *testing.T) { require.NoError(t, err) platform, upgradeError := analyzePlatformUpgradeClient(plUpgrade) - require.ErrorIs(t, upgradeError, (&cmderrors.PlatformAlreadyAtTheLatestVersionError{Platform: "esp8266:esp8266"}).ToRPCStatus().Err()) + require.ErrorIs(t, upgradeError, (&cmderrors.PlatformAlreadyAtTheLatestVersionError{Platform: "esp8266:esp8266"}).GRPCStatus().Err()) require.NotNil(t, platform) require.False(t, platform.GetMetadata().GetIndexed()) // the esp866 is not present in the additional-urls require.False(t, platform.GetRelease().GetMissingMetadata()) // install.json is present @@ -528,7 +528,7 @@ func TestDaemonCoreUpgradePlatform(t *testing.T) { require.NoError(t, err) platform, upgradeError := analyzePlatformUpgradeClient(plUpgrade) - require.ErrorIs(t, upgradeError, (&cmderrors.PlatformAlreadyAtTheLatestVersionError{Platform: "esp8266:esp8266"}).ToRPCStatus().Err()) + require.ErrorIs(t, upgradeError, (&cmderrors.PlatformAlreadyAtTheLatestVersionError{Platform: "esp8266:esp8266"}).GRPCStatus().Err()) require.NotNil(t, platform) require.False(t, platform.GetMetadata().GetIndexed()) // the esp866 is not present in the additional-urls require.True(t, platform.GetRelease().GetMissingMetadata()) // install.json is present From 23ccd4332dcbe8b8153824381ae79b96de419a20 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 16:47:44 +0100 Subject: [PATCH 09/56] Inlining methods in ArduinoCoreServiceImpl (part 1: BoardListAll) This commit is composed of many parts: * ArduinoCoreServiceImpl has been made private * A new function NewArduinoCoreService() has been added to instatiate a new service. * The service is created at CLI startup and sent down the initialization chain where needed. In this commit only the BoardListAll command has been ported to prove the feasability of the change. --- commands/service.go | 107 +++++++++--------- commands/service_board_listall.go | 4 +- commands/service_debug.go | 6 +- commands/service_settings.go | 12 +- commands/service_settings_test.go | 2 +- internal/cli/arguments/completion.go | 8 +- internal/cli/arguments/fqbn.go | 4 +- internal/cli/arguments/programmer.go | 4 +- internal/cli/board/attach.go | 6 +- internal/cli/board/board.go | 11 +- internal/cli/board/details.go | 4 +- internal/cli/board/list.go | 4 +- internal/cli/board/listall.go | 11 +- internal/cli/burnbootloader/burnbootloader.go | 6 +- internal/cli/cli.go | 30 ++--- internal/cli/compile/compile.go | 6 +- internal/cli/config/delete.go | 2 +- internal/cli/config/get.go | 2 +- internal/cli/daemon/daemon.go | 5 +- internal/cli/debug/debug.go | 8 +- internal/cli/debug/debug_check.go | 6 +- internal/cli/lib/examples.go | 4 +- internal/cli/lib/lib.go | 7 +- internal/cli/lib/list.go | 4 +- internal/cli/monitor/monitor.go | 4 +- internal/cli/upload/upload.go | 6 +- internal/docsgen/main.go | 2 +- main.go | 7 +- 28 files changed, 141 insertions(+), 141 deletions(-) diff --git a/commands/service.go b/commands/service.go index 88f03e5fed8..256cba0d027 100644 --- a/commands/service.go +++ b/commands/service.go @@ -30,21 +30,27 @@ import ( "google.golang.org/grpc/metadata" ) -// ArduinoCoreServerImpl FIXMEDOC -type ArduinoCoreServerImpl struct { - // Force compile error for unimplemented methods - rpc.UnsafeArduinoCoreServiceServer +// NewArduinoCoreServer returns an implementation of the ArduinoCoreService gRPC service +// that uses the provided version string. +func NewArduinoCoreServer(version string) rpc.ArduinoCoreServiceServer { + return &arduinoCoreServerImpl{ + versionString: version, + } +} + +type arduinoCoreServerImpl struct { + rpc.UnsafeArduinoCoreServiceServer // Force compile error for unimplemented methods - VersionString string + versionString string } // BoardDetails FIXMEDOC -func (s *ArduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { +func (s *arduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { return BoardDetails(ctx, req) } // BoardList FIXMEDOC -func (s *ArduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { +func (s *arduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { ports, _, err := BoardList(req) if err != nil { return nil, err @@ -54,18 +60,13 @@ func (s *ArduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardLis }, nil } -// BoardListAll FIXMEDOC -func (s *ArduinoCoreServerImpl) BoardListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { - return BoardListAll(ctx, req) -} - // BoardSearch exposes to the gRPC interface the board search command -func (s *ArduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { +func (s *arduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { return BoardSearch(ctx, req) } // BoardListWatch FIXMEDOC -func (s *ArduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, stream rpc.ArduinoCoreService_BoardListWatchServer) error { +func (s *arduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, stream rpc.ArduinoCoreService_BoardListWatchServer) error { syncSend := NewSynchronizedSend(stream.Send) if req.GetInstance() == nil { err := fmt.Errorf(tr("no instance specified")) @@ -91,12 +92,12 @@ func (s *ArduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, s } // Destroy FIXMEDOC -func (s *ArduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { +func (s *arduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { return Destroy(ctx, req) } // UpdateIndex FIXMEDOC -func (s *ArduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream rpc.ArduinoCoreService_UpdateIndexServer) error { +func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream rpc.ArduinoCoreService_UpdateIndexServer) error { syncSend := NewSynchronizedSend(stream.Send) res, err := UpdateIndex(stream.Context(), req, func(p *rpc.DownloadProgress) { @@ -114,7 +115,7 @@ func (s *ArduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream } // UpdateLibrariesIndex FIXMEDOC -func (s *ArduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesIndexRequest, stream rpc.ArduinoCoreService_UpdateLibrariesIndexServer) error { +func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesIndexRequest, stream rpc.ArduinoCoreService_UpdateLibrariesIndexServer) error { syncSend := NewSynchronizedSend(stream.Send) res, err := UpdateLibrariesIndex(stream.Context(), req, func(p *rpc.DownloadProgress) { @@ -132,7 +133,7 @@ func (s *ArduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd } // Create FIXMEDOC -func (s *ArduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateRequest) (*rpc.CreateResponse, error) { +func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateRequest) (*rpc.CreateResponse, error) { var userAgent []string if md, ok := metadata.FromIncomingContext(ctx); ok { userAgent = md.Get("user-agent") @@ -144,34 +145,34 @@ func (s *ArduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque } // Init FIXMEDOC -func (s *ArduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { +func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { syncSend := NewSynchronizedSend(stream.Send) return Init(req, func(message *rpc.InitResponse) { syncSend.Send(message) }) } // Version FIXMEDOC -func (s *ArduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionRequest) (*rpc.VersionResponse, error) { - return &rpc.VersionResponse{Version: s.VersionString}, nil +func (s *arduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionRequest) (*rpc.VersionResponse, error) { + return &rpc.VersionResponse{Version: s.versionString}, nil } // NewSketch FIXMEDOC -func (s *ArduinoCoreServerImpl) NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { +func (s *arduinoCoreServerImpl) NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { return NewSketch(ctx, req) } // LoadSketch FIXMEDOC -func (s *ArduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { +func (s *arduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { resp, err := LoadSketch(ctx, req) return &rpc.LoadSketchResponse{Sketch: resp}, err } // SetSketchDefaults FIXMEDOC -func (s *ArduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) { +func (s *arduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) { return SetSketchDefaults(ctx, req) } // Compile FIXMEDOC -func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.ArduinoCoreService_CompileServer) error { +func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.ArduinoCoreService_CompileServer) error { syncSend := NewSynchronizedSend(stream.Send) outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.CompileResponse{ @@ -206,7 +207,7 @@ func (s *ArduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu } // PlatformInstall FIXMEDOC -func (s *ArduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error { +func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) resp, err := PlatformInstall( stream.Context(), req, @@ -220,7 +221,7 @@ func (s *ArduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, } // PlatformDownload FIXMEDOC -func (s *ArduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadRequest, stream rpc.ArduinoCoreService_PlatformDownloadServer) error { +func (s *arduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadRequest, stream rpc.ArduinoCoreService_PlatformDownloadServer) error { syncSend := NewSynchronizedSend(stream.Send) resp, err := PlatformDownload( stream.Context(), req, @@ -233,7 +234,7 @@ func (s *ArduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadReques } // PlatformUninstall FIXMEDOC -func (s *ArduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequest, stream rpc.ArduinoCoreService_PlatformUninstallServer) error { +func (s *arduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequest, stream rpc.ArduinoCoreService_PlatformUninstallServer) error { syncSend := NewSynchronizedSend(stream.Send) resp, err := PlatformUninstall( stream.Context(), req, @@ -246,7 +247,7 @@ func (s *ArduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequ } // PlatformUpgrade FIXMEDOC -func (s *ArduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, stream rpc.ArduinoCoreService_PlatformUpgradeServer) error { +func (s *arduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, stream rpc.ArduinoCoreService_PlatformUpgradeServer) error { syncSend := NewSynchronizedSend(stream.Send) resp, err := PlatformUpgrade( stream.Context(), req, @@ -260,12 +261,12 @@ func (s *ArduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, } // PlatformSearch FIXMEDOC -func (s *ArduinoCoreServerImpl) PlatformSearch(ctx context.Context, req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { +func (s *arduinoCoreServerImpl) PlatformSearch(ctx context.Context, req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { return PlatformSearch(req) } // Upload FIXMEDOC -func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.ArduinoCoreService_UploadServer) error { +func (s *arduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.ArduinoCoreService_UploadServer) error { syncSend := NewSynchronizedSend(stream.Send) outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.UploadResponse{ @@ -291,7 +292,7 @@ func (s *ArduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.Arduin } // UploadUsingProgrammer FIXMEDOC -func (s *ArduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgrammerRequest, stream rpc.ArduinoCoreService_UploadUsingProgrammerServer) error { +func (s *arduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgrammerRequest, stream rpc.ArduinoCoreService_UploadUsingProgrammerServer) error { syncSend := NewSynchronizedSend(stream.Send) outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.UploadUsingProgrammerResponse{ @@ -317,12 +318,12 @@ func (s *ArduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgra } // SupportedUserFields FIXMEDOC -func (s *ArduinoCoreServerImpl) SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsRequest) (*rpc.SupportedUserFieldsResponse, error) { +func (s *arduinoCoreServerImpl) SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsRequest) (*rpc.SupportedUserFieldsResponse, error) { return SupportedUserFields(ctx, req) } // BurnBootloader FIXMEDOC -func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, stream rpc.ArduinoCoreService_BurnBootloaderServer) error { +func (s *arduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, stream rpc.ArduinoCoreService_BurnBootloaderServer) error { syncSend := NewSynchronizedSend(stream.Send) outStream := feedStreamTo(func(data []byte) { syncSend.Send(&rpc.BurnBootloaderResponse{ @@ -348,12 +349,12 @@ func (s *ArduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, s } // ListProgrammersAvailableForUpload FIXMEDOC -func (s *ArduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { +func (s *arduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { return ListProgrammersAvailableForUpload(ctx, req) } // LibraryDownload FIXMEDOC -func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, stream rpc.ArduinoCoreService_LibraryDownloadServer) error { +func (s *arduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, stream rpc.ArduinoCoreService_LibraryDownloadServer) error { syncSend := NewSynchronizedSend(stream.Send) resp, err := LibraryDownload( stream.Context(), req, @@ -366,7 +367,7 @@ func (s *ArduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, } // LibraryInstall FIXMEDOC -func (s *ArduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, stream rpc.ArduinoCoreService_LibraryInstallServer) error { +func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, stream rpc.ArduinoCoreService_LibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) return LibraryInstall( stream.Context(), req, @@ -376,7 +377,7 @@ func (s *ArduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s } // LibraryUpgrade FIXMEDOC -func (s *ArduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, stream rpc.ArduinoCoreService_LibraryUpgradeServer) error { +func (s *arduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, stream rpc.ArduinoCoreService_LibraryUpgradeServer) error { syncSend := NewSynchronizedSend(stream.Send) return LibraryUpgrade( stream.Context(), req, @@ -386,7 +387,7 @@ func (s *ArduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, s } // LibraryUninstall FIXMEDOC -func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallRequest, stream rpc.ArduinoCoreService_LibraryUninstallServer) error { +func (s *arduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallRequest, stream rpc.ArduinoCoreService_LibraryUninstallServer) error { syncSend := NewSynchronizedSend(stream.Send) return LibraryUninstall(stream.Context(), req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) }, @@ -394,7 +395,7 @@ func (s *ArduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallReques } // LibraryUpgradeAll FIXMEDOC -func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, stream rpc.ArduinoCoreService_LibraryUpgradeAllServer) error { +func (s *arduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, stream rpc.ArduinoCoreService_LibraryUpgradeAllServer) error { syncSend := NewSynchronizedSend(stream.Send) return LibraryUpgradeAll(req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{Progress: p}) }, @@ -403,27 +404,27 @@ func (s *ArduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequ } // LibraryResolveDependencies FIXMEDOC -func (s *ArduinoCoreServerImpl) LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { +func (s *arduinoCoreServerImpl) LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { return LibraryResolveDependencies(ctx, req) } // LibrarySearch FIXMEDOC -func (s *ArduinoCoreServerImpl) LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { +func (s *arduinoCoreServerImpl) LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { return LibrarySearch(ctx, req) } // LibraryList FIXMEDOC -func (s *ArduinoCoreServerImpl) LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { +func (s *arduinoCoreServerImpl) LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { return LibraryList(ctx, req) } // ArchiveSketch FIXMEDOC -func (s *ArduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { +func (s *arduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { return ArchiveSketch(ctx, req) } // ZipLibraryInstall FIXMEDOC -func (s *ArduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequest, stream rpc.ArduinoCoreService_ZipLibraryInstallServer) error { +func (s *arduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequest, stream rpc.ArduinoCoreService_ZipLibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) return ZipLibraryInstall( stream.Context(), req, @@ -432,7 +433,7 @@ func (s *ArduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequ } // GitLibraryInstall FIXMEDOC -func (s *ArduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequest, stream rpc.ArduinoCoreService_GitLibraryInstallServer) error { +func (s *arduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequest, stream rpc.ArduinoCoreService_GitLibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) return GitLibraryInstall( stream.Context(), req, @@ -441,12 +442,12 @@ func (s *ArduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequ } // EnumerateMonitorPortSettings FIXMEDOC -func (s *ArduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { +func (s *arduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { return EnumerateMonitorPortSettings(ctx, req) } // Monitor FIXMEDOC -func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorServer) error { +func (s *arduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorServer) error { syncSend := NewSynchronizedSend(stream.Send) // The configuration must be sent on the first message @@ -542,13 +543,11 @@ func (s *ArduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorSer } // CheckForArduinoCLIUpdates FIXMEDOC -func (s *ArduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, req *rpc.CheckForArduinoCLIUpdatesRequest) (*rpc.CheckForArduinoCLIUpdatesResponse, error) { - resp, err := updatecheck.CheckForArduinoCLIUpdates(ctx, req) - return resp, convertErrorToRPCStatus(err) +func (s *arduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, req *rpc.CheckForArduinoCLIUpdatesRequest) (*rpc.CheckForArduinoCLIUpdatesResponse, error) { + return updatecheck.CheckForArduinoCLIUpdates(ctx, req) } // CleanDownloadCacheDirectory FIXMEDOC -func (s *ArduinoCoreServerImpl) CleanDownloadCacheDirectory(ctx context.Context, req *rpc.CleanDownloadCacheDirectoryRequest) (*rpc.CleanDownloadCacheDirectoryResponse, error) { - resp, err := cache.CleanDownloadCacheDirectory(ctx, req) - return resp, convertErrorToRPCStatus(err) +func (s *arduinoCoreServerImpl) CleanDownloadCacheDirectory(ctx context.Context, req *rpc.CleanDownloadCacheDirectoryRequest) (*rpc.CleanDownloadCacheDirectoryResponse, error) { + return cache.CleanDownloadCacheDirectory(ctx, req) } diff --git a/commands/service_board_listall.go b/commands/service_board_listall.go index de20a7ce174..5c9a8664ab3 100644 --- a/commands/service_board_listall.go +++ b/commands/service_board_listall.go @@ -26,8 +26,8 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) -// BoardListAll FIXMEDOC -func BoardListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { +// BoardListAll list all the boards provided by installed platforms. +func (s *arduinoCoreServerImpl) BoardListAll(ctx context.Context, req *rpc.BoardListAllRequest) (*rpc.BoardListAllResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/commands/service_debug.go b/commands/service_debug.go index cb3f682219c..0f618ce7598 100644 --- a/commands/service_debug.go +++ b/commands/service_debug.go @@ -26,7 +26,7 @@ import ( // Debug returns a stream response that can be used to fetch data from the // target. The first message passed through the `Debug` request must // contain DebugRequest configuration params, not data. -func (s *ArduinoCoreServerImpl) Debug(stream rpc.ArduinoCoreService_DebugServer) error { +func (s *arduinoCoreServerImpl) Debug(stream rpc.ArduinoCoreService_DebugServer) error { // Grab the first message msg, err := stream.Recv() if err != nil { @@ -61,11 +61,11 @@ func (s *ArduinoCoreServerImpl) Debug(stream rpc.ArduinoCoreService_DebugServer) } // GetDebugConfig return metadata about a debug session -func (s *ArduinoCoreServerImpl) GetDebugConfig(ctx context.Context, req *rpc.GetDebugConfigRequest) (*rpc.GetDebugConfigResponse, error) { +func (s *arduinoCoreServerImpl) GetDebugConfig(ctx context.Context, req *rpc.GetDebugConfigRequest) (*rpc.GetDebugConfigResponse, error) { return GetDebugConfig(ctx, req) } // IsDebugSupported checks if debugging is supported for a given configuration -func (s *ArduinoCoreServerImpl) IsDebugSupported(ctx context.Context, req *rpc.IsDebugSupportedRequest) (*rpc.IsDebugSupportedResponse, error) { +func (s *arduinoCoreServerImpl) IsDebugSupported(ctx context.Context, req *rpc.IsDebugSupportedRequest) (*rpc.IsDebugSupportedResponse, error) { return IsDebugSupported(ctx, req) } diff --git a/commands/service_settings.go b/commands/service_settings.go index 806937fbb0c..f4675e0467e 100644 --- a/commands/service_settings.go +++ b/commands/service_settings.go @@ -28,7 +28,7 @@ import ( // SettingsGetAll returns a message with a string field containing all the settings // currently in use, marshalled in JSON format. -func (s *ArduinoCoreServerImpl) SettingsGetAll(ctx context.Context, req *rpc.SettingsGetAllRequest) (*rpc.SettingsGetAllResponse, error) { +func (s *arduinoCoreServerImpl) SettingsGetAll(ctx context.Context, req *rpc.SettingsGetAllRequest) (*rpc.SettingsGetAllResponse, error) { b, err := json.Marshal(configuration.Settings.AllSettings()) if err == nil { return &rpc.SettingsGetAllResponse{ @@ -68,7 +68,7 @@ func mapper(toMap map[string]interface{}) map[string]interface{} { } // SettingsMerge applies multiple settings values at once. -func (s *ArduinoCoreServerImpl) SettingsMerge(ctx context.Context, req *rpc.SettingsMergeRequest) (*rpc.SettingsMergeResponse, error) { +func (s *arduinoCoreServerImpl) SettingsMerge(ctx context.Context, req *rpc.SettingsMergeRequest) (*rpc.SettingsMergeResponse, error) { var toMerge map[string]interface{} if err := json.Unmarshal([]byte(req.GetJsonData()), &toMerge); err != nil { return nil, err @@ -93,7 +93,7 @@ func (s *ArduinoCoreServerImpl) SettingsMerge(ctx context.Context, req *rpc.Sett // SettingsGetValue returns a settings value given its key. If the key is not present // an error will be returned, so that we distinguish empty settings from missing // ones. -func (s *ArduinoCoreServerImpl) SettingsGetValue(ctx context.Context, req *rpc.SettingsGetValueRequest) (*rpc.SettingsGetValueResponse, error) { +func (s *arduinoCoreServerImpl) SettingsGetValue(ctx context.Context, req *rpc.SettingsGetValueRequest) (*rpc.SettingsGetValueResponse, error) { key := req.GetKey() // Check if settings key actually existing, we don't use Viper.InConfig() @@ -121,7 +121,7 @@ func (s *ArduinoCoreServerImpl) SettingsGetValue(ctx context.Context, req *rpc.S } // SettingsSetValue updates or set a value for a certain key. -func (s *ArduinoCoreServerImpl) SettingsSetValue(ctx context.Context, val *rpc.SettingsSetValueRequest) (*rpc.SettingsSetValueResponse, error) { +func (s *arduinoCoreServerImpl) SettingsSetValue(ctx context.Context, val *rpc.SettingsSetValueRequest) (*rpc.SettingsSetValueResponse, error) { key := val.GetKey() var value interface{} @@ -137,7 +137,7 @@ func (s *ArduinoCoreServerImpl) SettingsSetValue(ctx context.Context, val *rpc.S // We don't have a Read() function, that's not necessary since we only want one config file to be used // and that's picked up when the CLI is run as daemon, either using the default path or a custom one // set with the --config-file flag. -func (s *ArduinoCoreServerImpl) SettingsWrite(ctx context.Context, req *rpc.SettingsWriteRequest) (*rpc.SettingsWriteResponse, error) { +func (s *arduinoCoreServerImpl) SettingsWrite(ctx context.Context, req *rpc.SettingsWriteRequest) (*rpc.SettingsWriteResponse, error) { if err := configuration.Settings.WriteConfigAs(req.GetFilePath()); err != nil { return nil, err } @@ -145,7 +145,7 @@ func (s *ArduinoCoreServerImpl) SettingsWrite(ctx context.Context, req *rpc.Sett } // SettingsDelete removes a key from the config file -func (s *ArduinoCoreServerImpl) SettingsDelete(ctx context.Context, req *rpc.SettingsDeleteRequest) (*rpc.SettingsDeleteResponse, error) { +func (s *arduinoCoreServerImpl) SettingsDelete(ctx context.Context, req *rpc.SettingsDeleteRequest) (*rpc.SettingsDeleteResponse, error) { toDelete := req.GetKey() // Check if settings key actually existing, we don't use Viper.InConfig() diff --git a/commands/service_settings_test.go b/commands/service_settings_test.go index ff2da8dac07..226a2663990 100644 --- a/commands/service_settings_test.go +++ b/commands/service_settings_test.go @@ -27,7 +27,7 @@ import ( "github.com/stretchr/testify/require" ) -var svc = ArduinoCoreServerImpl{} +var svc = NewArduinoCoreServer("") func init() { configuration.Settings = configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index d351c8e4f5a..d21377a17c2 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -26,10 +26,10 @@ import ( // GetInstalledBoards is an helper function useful to autocomplete. // It returns a list of fqbn // it's taken from cli/board/listall.go -func GetInstalledBoards() []string { +func GetInstalledBoards(srv rpc.ArduinoCoreServiceServer) []string { inst := instance.CreateAndInit() - list, _ := commands.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ + list, _ := srv.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ Instance: inst, SearchArgs: nil, IncludeHiddenBoards: false, @@ -44,7 +44,7 @@ func GetInstalledBoards() []string { // GetInstalledProgrammers is an helper function useful to autocomplete. // It returns a list of programmers available based on the installed boards -func GetInstalledProgrammers() []string { +func GetInstalledProgrammers(srv rpc.ArduinoCoreServiceServer) []string { inst := instance.CreateAndInit() // we need the list of the available fqbn in order to get the list of the programmers @@ -53,7 +53,7 @@ func GetInstalledProgrammers() []string { SearchArgs: nil, IncludeHiddenBoards: false, } - list, _ := commands.BoardListAll(context.Background(), listAllReq) + list, _ := srv.BoardListAll(context.Background(), listAllReq) installedProgrammers := make(map[string]string) for _, board := range list.GetBoards() { diff --git a/internal/cli/arguments/fqbn.go b/internal/cli/arguments/fqbn.go index 01e1079d8ab..8760141b9d3 100644 --- a/internal/cli/arguments/fqbn.go +++ b/internal/cli/arguments/fqbn.go @@ -33,10 +33,10 @@ type Fqbn struct { } // AddToCommand adds the flags used to set fqbn to the specified Command -func (f *Fqbn) AddToCommand(cmd *cobra.Command) { +func (f *Fqbn) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&f.fqbn, "fqbn", "b", "", tr("Fully Qualified Board Name, e.g.: arduino:avr:uno")) cmd.RegisterFlagCompletionFunc("fqbn", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetInstalledBoards(), cobra.ShellCompDirectiveDefault + return GetInstalledBoards(srv), cobra.ShellCompDirectiveDefault }) cmd.Flags().StringSliceVar(&f.boardOptions, "board-options", []string{}, tr("List of board options separated by commas. Or can be used multiple times for multiple options.")) diff --git a/internal/cli/arguments/programmer.go b/internal/cli/arguments/programmer.go index b793d8192a4..0affcfece0d 100644 --- a/internal/cli/arguments/programmer.go +++ b/internal/cli/arguments/programmer.go @@ -31,10 +31,10 @@ type Programmer struct { } // AddToCommand adds the flags used to set the programmer to the specified Command -func (p *Programmer) AddToCommand(cmd *cobra.Command) { +func (p *Programmer) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&p.programmer, "programmer", "P", "", tr("Programmer to use, e.g: atmel_ice")) cmd.RegisterFlagCompletionFunc("programmer", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetInstalledProgrammers(), cobra.ShellCompDirectiveDefault + return GetInstalledProgrammers(srv), cobra.ShellCompDirectiveDefault }) } diff --git a/internal/cli/board/attach.go b/internal/cli/board/attach.go index b7a943f8cfa..86b3c257061 100644 --- a/internal/cli/board/attach.go +++ b/internal/cli/board/attach.go @@ -27,7 +27,7 @@ import ( "github.com/spf13/cobra" ) -func initAttachCommand() *cobra.Command { +func initAttachCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var port arguments.Port var fqbn arguments.Fqbn var programmer arguments.Programmer @@ -48,9 +48,9 @@ func initAttachCommand() *cobra.Command { runAttachCommand(sketchPath, &port, fqbn.String(), &programmer) }, } - fqbn.AddToCommand(attachCommand) + fqbn.AddToCommand(attachCommand, srv) port.AddToCommand(attachCommand) - programmer.AddToCommand(attachCommand) + programmer.AddToCommand(attachCommand, srv) return attachCommand } diff --git a/internal/cli/board/board.go b/internal/cli/board/board.go index 8cdba86743c..3c3b99a51b5 100644 --- a/internal/cli/board/board.go +++ b/internal/cli/board/board.go @@ -19,13 +19,14 @@ import ( "os" "github.com/arduino/arduino-cli/internal/i18n" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) var tr = i18n.Tr // NewCommand created a new `board` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { boardCommand := &cobra.Command{ Use: "board", Short: tr("Arduino board commands."), @@ -34,10 +35,10 @@ func NewCommand() *cobra.Command { " " + os.Args[0] + " board list", } - boardCommand.AddCommand(initAttachCommand()) - boardCommand.AddCommand(initDetailsCommand()) - boardCommand.AddCommand(initListCommand()) - boardCommand.AddCommand(initListAllCommand()) + boardCommand.AddCommand(initAttachCommand(srv)) + boardCommand.AddCommand(initDetailsCommand(srv)) + boardCommand.AddCommand(initListCommand(srv)) + boardCommand.AddCommand(initListAllCommand(srv)) boardCommand.AddCommand(initSearchCommand()) return boardCommand diff --git a/internal/cli/board/details.go b/internal/cli/board/details.go index a91359caea4..9f7ef87626f 100644 --- a/internal/cli/board/details.go +++ b/internal/cli/board/details.go @@ -32,7 +32,7 @@ import ( "github.com/spf13/cobra" ) -func initDetailsCommand() *cobra.Command { +func initDetailsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var showFullDetails bool var listProgrammers bool var fqbn arguments.Fqbn @@ -48,7 +48,7 @@ func initDetailsCommand() *cobra.Command { }, } - fqbn.AddToCommand(detailsCommand) + fqbn.AddToCommand(detailsCommand, srv) detailsCommand.Flags().BoolVarP(&showFullDetails, "full", "f", false, tr("Show full board details")) detailsCommand.Flags().BoolVarP(&listProgrammers, "list-programmers", "", false, tr("Show list of available programmers")) detailsCommand.MarkFlagRequired("fqbn") diff --git a/internal/cli/board/list.go b/internal/cli/board/list.go index 96fb69c5029..0e4e9a4cc11 100644 --- a/internal/cli/board/list.go +++ b/internal/cli/board/list.go @@ -35,7 +35,7 @@ import ( "github.com/spf13/cobra" ) -func initListCommand() *cobra.Command { +func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var timeoutArg arguments.DiscoveryTimeout var watch bool var fqbn arguments.Fqbn @@ -51,7 +51,7 @@ func initListCommand() *cobra.Command { } timeoutArg.AddToCommand(listCommand) - fqbn.AddToCommand(listCommand) + fqbn.AddToCommand(listCommand, srv) listCommand.Flags().BoolVarP(&watch, "watch", "w", false, tr("Command keeps running and prints list of connected boards whenever there is a change.")) return listCommand } diff --git a/internal/cli/board/listall.go b/internal/cli/board/listall.go index 82c5c7a0d2e..fdf39fe0a98 100644 --- a/internal/cli/board/listall.go +++ b/internal/cli/board/listall.go @@ -21,7 +21,6 @@ import ( "os" "sort" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -33,7 +32,7 @@ import ( var showHiddenBoard bool -func initListAllCommand() *cobra.Command { +func initListAllCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var listAllCommand = &cobra.Command{ Use: fmt.Sprintf("listall [%s]", tr("boardname")), Short: tr("List all known boards and their corresponding FQBN."), @@ -43,19 +42,21 @@ for a specific board if you specify the board name`), " " + os.Args[0] + " board listall\n" + " " + os.Args[0] + " board listall zero", Args: cobra.ArbitraryArgs, - Run: runListAllCommand, + Run: func(cmd *cobra.Command, args []string) { + runListAllCommand(args, srv) + }, } listAllCommand.Flags().BoolVarP(&showHiddenBoard, "show-hidden", "a", false, tr("Show also boards marked as 'hidden' in the platform")) return listAllCommand } // runListAllCommand list all installed boards -func runListAllCommand(cmd *cobra.Command, args []string) { +func runListAllCommand(args []string, srv rpc.ArduinoCoreServiceServer) { inst := instance.CreateAndInit() logrus.Info("Executing `arduino-cli board listall`") - list, err := commands.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ + list, err := srv.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ Instance: inst, SearchArgs: args, IncludeHiddenBoards: showHiddenBoard, diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index 2de1a5f132b..1a09a1154c0 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -42,7 +42,7 @@ var ( ) // NewCommand created a new `burn-bootloader` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { burnBootloaderCommand := &cobra.Command{ Use: "burn-bootloader", Short: tr("Upload the bootloader."), @@ -52,9 +52,9 @@ func NewCommand() *cobra.Command { Run: runBootloaderCommand, } - fqbn.AddToCommand(burnBootloaderCommand) + fqbn.AddToCommand(burnBootloaderCommand, srv) port.AddToCommand(burnBootloaderCommand) - programmer.AddToCommand(burnBootloaderCommand) + programmer.AddToCommand(burnBootloaderCommand, srv) burnBootloaderCommand.Flags().BoolVarP(&verify, "verify", "t", false, tr("Verify uploaded binary after the upload.")) burnBootloaderCommand.Flags().BoolVarP(&verbose, "verbose", "v", false, tr("Turns on verbose mode.")) burnBootloaderCommand.Flags().BoolVar(&dryRun, "dry-run", false, tr("Do not perform the actual upload, just log out actions")) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index da265d46f59..2e633d236fd 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -64,13 +64,13 @@ var ( ) // NewCommand creates a new ArduinoCli command root -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cobra.AddTemplateFunc("tr", i18n.Tr) var updaterMessageChan chan *semver.Version // ArduinoCli is the root command - arduinoCli := &cobra.Command{ + cmd := &cobra.Command{ Use: "arduino-cli", Short: tr("Arduino CLI."), Long: tr("Arduino Command Line Interface (arduino-cli)."), @@ -112,35 +112,27 @@ func NewCommand() *cobra.Command { }, } - arduinoCli.SetUsageTemplate(getUsageTemplate()) + cmd.SetUsageTemplate(getUsageTemplate()) - createCliCommandTree(arduinoCli) - - return arduinoCli -} - -// this is here only for testing -func createCliCommandTree(cmd *cobra.Command) { - cmd.AddCommand(board.NewCommand()) + cmd.AddCommand(board.NewCommand(srv)) cmd.AddCommand(cache.NewCommand()) - cmd.AddCommand(compile.NewCommand()) + cmd.AddCommand(compile.NewCommand(srv)) cmd.AddCommand(completion.NewCommand()) cmd.AddCommand(config.NewCommand()) cmd.AddCommand(core.NewCommand()) cmd.AddCommand(daemon.NewCommand()) cmd.AddCommand(generatedocs.NewCommand()) - cmd.AddCommand(lib.NewCommand()) - cmd.AddCommand(monitor.NewCommand()) + cmd.AddCommand(lib.NewCommand(srv)) + cmd.AddCommand(monitor.NewCommand(srv)) cmd.AddCommand(outdated.NewCommand()) cmd.AddCommand(sketch.NewCommand()) cmd.AddCommand(update.NewCommand()) cmd.AddCommand(upgrade.NewCommand()) - cmd.AddCommand(upload.NewCommand()) - cmd.AddCommand(debug.NewCommand()) - cmd.AddCommand(burnbootloader.NewCommand()) + cmd.AddCommand(upload.NewCommand(srv)) + cmd.AddCommand(debug.NewCommand(srv)) + cmd.AddCommand(burnbootloader.NewCommand(srv)) cmd.AddCommand(version.NewCommand()) cmd.AddCommand(feedback.NewCommand()) - cmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, tr("Print the logs on the standard output.")) cmd.Flag("verbose").Hidden = true cmd.PersistentFlags().BoolVar(&verbose, "log", false, tr("Print the logs on the standard output.")) @@ -166,6 +158,8 @@ func createCliCommandTree(cmd *cobra.Command) { cmd.PersistentFlags().StringSlice("additional-urls", []string{}, tr("Comma-separated list of additional URLs for the Boards Manager.")) cmd.PersistentFlags().Bool("no-color", false, "Disable colored output.") configuration.BindFlags(cmd, configuration.Settings) + + return cmd } // convert the string passed to the `--log-level` option to the corresponding diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index f2b36b41e75..82b6d49faf6 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -77,7 +77,7 @@ var ( ) // NewCommand created a new `compile` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { compileCommand := &cobra.Command{ Use: "compile", Short: tr("Compiles Arduino sketches."), @@ -91,7 +91,7 @@ func NewCommand() *cobra.Command { Run: runCompileCommand, } - fqbnArg.AddToCommand(compileCommand) + fqbnArg.AddToCommand(compileCommand, srv) profileArg.AddToCommand(compileCommand) compileCommand.Flags().BoolVar(&dumpProfile, "dump-profile", false, tr("Create and print a profile configuration from the build.")) showPropertiesArg.AddToCommand(compileCommand) @@ -122,7 +122,7 @@ func NewCommand() *cobra.Command { compileCommand.Flags().StringSliceVar(&libraries, "libraries", []string{}, tr("Path to a collection of libraries. Can be used multiple times or entries can be comma separated.")) compileCommand.Flags().BoolVar(&optimizeForDebug, "optimize-for-debug", false, tr("Optional, optimize compile output for debugging, rather than for release.")) - programmer.AddToCommand(compileCommand) + programmer.AddToCommand(compileCommand, srv) compileCommand.Flags().BoolVar(&compilationDatabaseOnly, "only-compilation-database", false, tr("Just produce the compilation database, without actually compiling. All build commands are skipped except pre* hooks.")) compileCommand.Flags().BoolVar(&clean, "clean", false, tr("Optional, cleanup the build folder and do not use any cached build.")) compileCommand.Flags().BoolVarP(&exportBinaries, "export-binaries", "e", false, tr("If set built binaries will be exported to the sketch folder.")) diff --git a/internal/cli/config/delete.go b/internal/cli/config/delete.go index 2102a2581d7..e5889a12952 100644 --- a/internal/cli/config/delete.go +++ b/internal/cli/config/delete.go @@ -47,7 +47,7 @@ func runDeleteCommand(cmd *cobra.Command, args []string) { logrus.Info("Executing `arduino-cli config delete`") toDelete := args[0] - svc := commands.ArduinoCoreServerImpl{} + svc := commands.NewArduinoCoreServer("") _, err := svc.SettingsDelete(cmd.Context(), &rpc.SettingsDeleteRequest{Key: toDelete}) if err != nil { feedback.Fatal(tr("Cannot delete the key %[1]s: %[2]v", toDelete, err), feedback.ErrGeneric) diff --git a/internal/cli/config/get.go b/internal/cli/config/get.go index 74fcd93fa72..68b8afd0d4a 100644 --- a/internal/cli/config/get.go +++ b/internal/cli/config/get.go @@ -50,7 +50,7 @@ func initGetCommand() *cobra.Command { func runGetCommand(cmd *cobra.Command, args []string) { logrus.Info("Executing `arduino-cli config get`") - svc := commands.ArduinoCoreServerImpl{} + svc := commands.NewArduinoCoreServer("") for _, toGet := range args { resp, err := svc.SettingsGetValue(cmd.Context(), &rpc.SettingsGetValueRequest{Key: toGet}) if err != nil { diff --git a/internal/cli/daemon/daemon.go b/internal/cli/daemon/daemon.go index a96f5a3ffff..2422a03c2c2 100644 --- a/internal/cli/daemon/daemon.go +++ b/internal/cli/daemon/daemon.go @@ -102,9 +102,8 @@ func runDaemonCommand(cmd *cobra.Command, args []string) { configuration.Settings.Set("network.user_agent_ext", "daemon") // register the commands service - srv_commands.RegisterArduinoCoreServiceServer(s, &commands.ArduinoCoreServerImpl{ - VersionString: version.VersionInfo.VersionString, - }) + srv_commands.RegisterArduinoCoreServiceServer(s, + commands.NewArduinoCoreServer(version.VersionInfo.VersionString)) if !daemonize { // When parent process ends terminate also the daemon diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index 631b9046595..a4dbe0aba34 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -38,7 +38,7 @@ import ( var tr = i18n.Tr // NewCommand created a new `upload` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var ( fqbnArg arguments.Fqbn portArgs arguments.Port @@ -60,10 +60,10 @@ func NewCommand() *cobra.Command { }, } - debugCommand.AddCommand(newDebugCheckCommand()) - fqbnArg.AddToCommand(debugCommand) + debugCommand.AddCommand(newDebugCheckCommand(srv)) + fqbnArg.AddToCommand(debugCommand, srv) portArgs.AddToCommand(debugCommand) - programmer.AddToCommand(debugCommand) + programmer.AddToCommand(debugCommand, srv) profileArg.AddToCommand(debugCommand) debugCommand.Flags().StringVar(&interpreter, "interpreter", "console", tr("Debug interpreter e.g.: %s", "console, mi, mi1, mi2, mi3")) debugCommand.Flags().StringVarP(&importDir, "input-dir", "", "", tr("Directory containing binaries for debug.")) diff --git a/internal/cli/debug/debug_check.go b/internal/cli/debug/debug_check.go index a4bfafac879..085c47c2b55 100644 --- a/internal/cli/debug/debug_check.go +++ b/internal/cli/debug/debug_check.go @@ -29,7 +29,7 @@ import ( "github.com/spf13/cobra" ) -func newDebugCheckCommand() *cobra.Command { +func newDebugCheckCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var ( fqbnArg arguments.Fqbn portArgs arguments.Port @@ -44,9 +44,9 @@ func newDebugCheckCommand() *cobra.Command { runDebugCheckCommand(&portArgs, &fqbnArg, interpreter, &programmer) }, } - fqbnArg.AddToCommand(debugCheckCommand) + fqbnArg.AddToCommand(debugCheckCommand, srv) portArgs.AddToCommand(debugCheckCommand) - programmer.AddToCommand(debugCheckCommand) + programmer.AddToCommand(debugCheckCommand, srv) debugCheckCommand.Flags().StringVar(&interpreter, "interpreter", "console", tr("Debug interpreter e.g.: %s", "console, mi, mi1, mi2, mi3")) return debugCheckCommand } diff --git a/internal/cli/lib/examples.go b/internal/cli/lib/examples.go index beca10871a5..4a411d26ff6 100644 --- a/internal/cli/lib/examples.go +++ b/internal/cli/lib/examples.go @@ -38,7 +38,7 @@ var ( fqbn arguments.Fqbn ) -func initExamplesCommand() *cobra.Command { +func initExamplesCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { examplesCommand := &cobra.Command{ Use: fmt.Sprintf("examples [%s]", tr("LIBRARY_NAME")), Short: tr("Shows the list of the examples for libraries."), @@ -50,7 +50,7 @@ func initExamplesCommand() *cobra.Command { return arguments.GetInstalledLibraries(), cobra.ShellCompDirectiveDefault }, } - fqbn.AddToCommand(examplesCommand) + fqbn.AddToCommand(examplesCommand, srv) return examplesCommand } diff --git a/internal/cli/lib/lib.go b/internal/cli/lib/lib.go index edba456bde9..59cd2020650 100644 --- a/internal/cli/lib/lib.go +++ b/internal/cli/lib/lib.go @@ -19,13 +19,14 @@ import ( "os" "github.com/arduino/arduino-cli/internal/i18n" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) var tr = i18n.Tr // NewCommand created a new `lib` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { libCommand := &cobra.Command{ Use: "lib", Short: tr("Arduino commands about libraries."), @@ -37,8 +38,8 @@ func NewCommand() *cobra.Command { libCommand.AddCommand(initDownloadCommand()) libCommand.AddCommand(initInstallCommand()) - libCommand.AddCommand(initListCommand()) - libCommand.AddCommand(initExamplesCommand()) + libCommand.AddCommand(initListCommand(srv)) + libCommand.AddCommand(initExamplesCommand(srv)) libCommand.AddCommand(initSearchCommand()) libCommand.AddCommand(initUninstallCommand()) libCommand.AddCommand(initUpgradeCommand()) diff --git a/internal/cli/lib/list.go b/internal/cli/lib/list.go index 1c0ba7dd6c1..a034267db46 100644 --- a/internal/cli/lib/list.go +++ b/internal/cli/lib/list.go @@ -32,7 +32,7 @@ import ( "github.com/spf13/cobra" ) -func initListCommand() *cobra.Command { +func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var all bool var updatable bool listCommand := &cobra.Command{ @@ -52,7 +52,7 @@ not listed, they can be listed by adding the --all flag.`), }, } listCommand.Flags().BoolVar(&all, "all", false, tr("Include built-in libraries (from platforms and IDE) in listing.")) - fqbn.AddToCommand(listCommand) + fqbn.AddToCommand(listCommand, srv) listCommand.Flags().BoolVar(&updatable, "updatable", false, tr("List updatable libraries.")) return listCommand } diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 1309210cad6..9442a1b8736 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -43,7 +43,7 @@ import ( var tr = i18n.Tr // NewCommand created a new `monitor` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var ( portArgs arguments.Port fqbnArg arguments.Fqbn @@ -76,7 +76,7 @@ func NewCommand() *cobra.Command { monitorCommand.Flags().StringSliceVarP(&configs, "config", "c", []string{}, tr("Configure communication port settings. The format is =[,=]...")) monitorCommand.Flags().BoolVarP(&quiet, "quiet", "q", false, tr("Run in silent mode, show only monitor input and output.")) monitorCommand.Flags().BoolVar(×tamp, "timestamp", false, tr("Timestamp each incoming line.")) - fqbnArg.AddToCommand(monitorCommand) + fqbnArg.AddToCommand(monitorCommand, srv) return monitorCommand } diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 8641d746c49..28f8d77ea83 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -49,7 +49,7 @@ var ( ) // NewCommand created a new `upload` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { uploadFields := map[string]string{} uploadCommand := &cobra.Command{ Use: "upload", @@ -67,14 +67,14 @@ func NewCommand() *cobra.Command { }, } - fqbnArg.AddToCommand(uploadCommand) + fqbnArg.AddToCommand(uploadCommand, srv) portArgs.AddToCommand(uploadCommand) profileArg.AddToCommand(uploadCommand) uploadCommand.Flags().StringVarP(&importDir, "input-dir", "", "", tr("Directory containing binaries to upload.")) uploadCommand.Flags().StringVarP(&importFile, "input-file", "i", "", tr("Binary file to upload.")) uploadCommand.Flags().BoolVarP(&verify, "verify", "t", false, tr("Verify uploaded binary after the upload.")) uploadCommand.Flags().BoolVarP(&verbose, "verbose", "v", false, tr("Optional, turns on verbose mode.")) - programmer.AddToCommand(uploadCommand) + programmer.AddToCommand(uploadCommand, srv) uploadCommand.Flags().BoolVar(&dryRun, "dry-run", false, tr("Do not perform the actual upload, just log out actions")) uploadCommand.Flags().MarkHidden("dry-run") arguments.AddKeyValuePFlag(uploadCommand, &uploadFields, "upload-field", "F", nil, tr("Set a value for a field required to upload.")) diff --git a/internal/docsgen/main.go b/internal/docsgen/main.go index 3448c9f5f62..eb8903507e1 100644 --- a/internal/docsgen/main.go +++ b/internal/docsgen/main.go @@ -32,7 +32,7 @@ func main() { os.MkdirAll(os.Args[1], 0755) // Create the output folder if it doesn't already exist configuration.Settings = configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args)) - cli := cli.NewCommand() + cli := cli.NewCommand(nil) cli.DisableAutoGenTag = true // Disable addition of auto-generated date stamp err := doc.GenMarkdownTree(cli, os.Args[1]) if err != nil { diff --git a/main.go b/main.go index db1baad2bee..8587037fbf1 100644 --- a/main.go +++ b/main.go @@ -18,16 +18,21 @@ package main import ( "os" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/i18n" + "github.com/arduino/arduino-cli/version" ) func main() { configuration.Settings = configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args)) i18n.Init(configuration.Settings.GetString("locale")) - arduinoCmd := cli.NewCommand() + + srv := commands.NewArduinoCoreServer(version.VersionInfo.VersionString) + + arduinoCmd := cli.NewCommand(srv) if err := arduinoCmd.Execute(); err != nil { feedback.FatalError(err, feedback.ErrGeneric) } From 53f03e5754ce7d438e525da55fa7b9cacc2912ae Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 16:58:19 +0100 Subject: [PATCH 10/56] Inlining methods in ArduinoCoreServiceImpl (part 2: BoardDetails) --- commands/service.go | 5 ----- commands/service_board_details.go | 2 +- internal/cli/arguments/programmer.go | 5 ++--- internal/cli/board/details.go | 7 +++---- internal/cli/burnbootloader/burnbootloader.go | 10 ++++++---- internal/cli/compile/compile.go | 8 +++++--- internal/cli/debug/debug.go | 6 +++--- internal/cli/debug/debug_check.go | 6 +++--- internal/cli/upload/upload.go | 6 +++--- 9 files changed, 26 insertions(+), 29 deletions(-) diff --git a/commands/service.go b/commands/service.go index 256cba0d027..b96bbf35635 100644 --- a/commands/service.go +++ b/commands/service.go @@ -44,11 +44,6 @@ type arduinoCoreServerImpl struct { versionString string } -// BoardDetails FIXMEDOC -func (s *arduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { - return BoardDetails(ctx, req) -} - // BoardList FIXMEDOC func (s *arduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { ports, _, err := BoardList(req) diff --git a/commands/service_board_details.go b/commands/service_board_details.go index d6637416688..5f042452582 100644 --- a/commands/service_board_details.go +++ b/commands/service_board_details.go @@ -27,7 +27,7 @@ import ( // BoardDetails 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 BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { +func (s *arduinoCoreServerImpl) BoardDetails(ctx context.Context, req *rpc.BoardDetailsRequest) (*rpc.BoardDetailsResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/internal/cli/arguments/programmer.go b/internal/cli/arguments/programmer.go index 0affcfece0d..c76271b0ede 100644 --- a/internal/cli/arguments/programmer.go +++ b/internal/cli/arguments/programmer.go @@ -18,7 +18,6 @@ package arguments import ( "context" - "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) @@ -40,14 +39,14 @@ func (p *Programmer) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreService // String returns the programmer specified by the user, or the default programmer // for the given board if defined. -func (p *Programmer) String(inst *rpc.Instance, fqbn string) string { +func (p *Programmer) String(inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer, fqbn string) string { if p.programmer != "" { return p.programmer } if inst == nil || fqbn == "" { return "" } - details, err := commands.BoardDetails(context.Background(), &rpc.BoardDetailsRequest{ + details, err := srv.BoardDetails(context.Background(), &rpc.BoardDetailsRequest{ Instance: inst, Fqbn: fqbn, }) diff --git a/internal/cli/board/details.go b/internal/cli/board/details.go index 9f7ef87626f..296078a9393 100644 --- a/internal/cli/board/details.go +++ b/internal/cli/board/details.go @@ -20,7 +20,6 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -44,7 +43,7 @@ func initDetailsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " board details -b arduino:avr:nano", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runDetailsCommand(fqbn.String(), showFullDetails, listProgrammers, showProperties) + runDetailsCommand(srv, fqbn.String(), showFullDetails, listProgrammers, showProperties) }, } @@ -56,7 +55,7 @@ func initDetailsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return detailsCommand } -func runDetailsCommand(fqbn string, showFullDetails, listProgrammers bool, showProperties arguments.ShowProperties) { +func runDetailsCommand(srv rpc.ArduinoCoreServiceServer, fqbn string, showFullDetails, listProgrammers bool, showProperties arguments.ShowProperties) { inst := instance.CreateAndInit() logrus.Info("Executing `arduino-cli board details`") @@ -65,7 +64,7 @@ func runDetailsCommand(fqbn string, showFullDetails, listProgrammers bool, showP if err != nil { feedback.Fatal(err.Error(), feedback.ErrBadArgument) } - res, err := commands.BoardDetails(context.Background(), &rpc.BoardDetailsRequest{ + res, err := srv.BoardDetails(context.Background(), &rpc.BoardDetailsRequest{ Instance: inst, Fqbn: fqbn, DoNotExpandBuildProperties: showPropertiesMode == arguments.ShowPropertiesUnexpanded, diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index 1a09a1154c0..999c2c137b8 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -48,8 +48,10 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Short: tr("Upload the bootloader."), Long: tr("Upload the bootloader on the board using an external programmer."), Example: " " + os.Args[0] + " burn-bootloader -b arduino:avr:uno -P atmel_ice", - Args: cobra.MaximumNArgs(1), - Run: runBootloaderCommand, + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + runBootloaderCommand(srv) + }, } fqbn.AddToCommand(burnBootloaderCommand, srv) @@ -63,7 +65,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return burnBootloaderCommand } -func runBootloaderCommand(command *cobra.Command, args []string) { +func runBootloaderCommand(srv rpc.ArduinoCoreServiceServer) { instance := instance.CreateAndInit() logrus.Info("Executing `arduino-cli burn-bootloader`") @@ -81,7 +83,7 @@ func runBootloaderCommand(command *cobra.Command, args []string) { Port: discoveryPort, Verbose: verbose, Verify: verify, - Programmer: programmer.String(instance, fqbn.String()), + Programmer: programmer.String(instance, srv, fqbn.String()), DryRun: dryRun, }, stdOut, stdErr); err != nil { errcode := feedback.ErrGeneric diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 82b6d49faf6..b03ecda1e02 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -88,7 +88,9 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + ` compile -b arduino:avr:uno --build-property "build.extra_flags=-DPIN=2 \"-DMY_DEFINE=\"hello world\"\"" /home/user/Arduino/MySketch` + "\n" + " " + os.Args[0] + ` compile -b arduino:avr:uno --build-property build.extra_flags=-DPIN=2 --build-property "compiler.cpp.extra_flags=\"-DSSID=\"hello world\"\"" /home/user/Arduino/MySketch` + "\n", Args: cobra.MaximumNArgs(1), - Run: runCompileCommand, + Run: func(cmd *cobra.Command, args []string) { + runCompileCommand(cmd, args, srv) + }, } fqbnArg.AddToCommand(compileCommand, srv) @@ -138,7 +140,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return compileCommand } -func runCompileCommand(cmd *cobra.Command, args []string) { +func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli compile`") if profileArg.Get() != "" { @@ -268,7 +270,7 @@ func runCompileCommand(cmd *cobra.Command, args []string) { prog := profile.GetProgrammer() if prog == "" || programmer.GetProgrammer() != "" { - prog = programmer.String(inst, fqbn) + prog = programmer.String(inst, srv, fqbn) } if prog == "" { prog = sk.GetDefaultProgrammer() diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index a4dbe0aba34..b4a04bd0c72 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -56,7 +56,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " debug -b arduino:samd:mkr1000 -P atmel_ice /home/user/Arduino/MySketch", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runDebugCommand(args, &portArgs, &fqbnArg, interpreter, importDir, &programmer, printInfo, &profileArg) + runDebugCommand(srv, args, &portArgs, &fqbnArg, interpreter, importDir, &programmer, printInfo, &profileArg) }, } @@ -72,7 +72,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return debugCommand } -func runDebugCommand(args []string, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, +func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, importDir string, programmer *arguments.Programmer, printInfo bool, profileArg *arguments.Profile) { logrus.Info("Executing `arduino-cli debug`") @@ -105,7 +105,7 @@ func runDebugCommand(args []string, portArgs *arguments.Port, fqbnArg *arguments prog := profile.GetProgrammer() if prog == "" || programmer.GetProgrammer() != "" { - prog = programmer.String(inst, fqbn) + prog = programmer.String(inst, srv, fqbn) } if prog == "" { prog = sk.GetDefaultProgrammer() diff --git a/internal/cli/debug/debug_check.go b/internal/cli/debug/debug_check.go index 085c47c2b55..1cff21c02a3 100644 --- a/internal/cli/debug/debug_check.go +++ b/internal/cli/debug/debug_check.go @@ -41,7 +41,7 @@ func newDebugCheckCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Short: tr("Check if the given board/programmer combination supports debugging."), Example: " " + os.Args[0] + " debug check -b arduino:samd:mkr1000 -P atmel_ice", Run: func(cmd *cobra.Command, args []string) { - runDebugCheckCommand(&portArgs, &fqbnArg, interpreter, &programmer) + runDebugCheckCommand(srv, &portArgs, &fqbnArg, interpreter, &programmer) }, } fqbnArg.AddToCommand(debugCheckCommand, srv) @@ -51,7 +51,7 @@ func newDebugCheckCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return debugCheckCommand } -func runDebugCheckCommand(portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, programmerArg *arguments.Programmer) { +func runDebugCheckCommand(srv rpc.ArduinoCoreServiceServer, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, programmerArg *arguments.Programmer) { instance := instance.CreateAndInit() logrus.Info("Executing `arduino-cli debug`") @@ -65,7 +65,7 @@ func runDebugCheckCommand(portArgs *arguments.Port, fqbnArg *arguments.Fqbn, int Fqbn: fqbn, Port: port, Interpreter: interpreter, - Programmer: programmerArg.String(instance, fqbn), + Programmer: programmerArg.String(instance, srv, fqbn), }) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 28f8d77ea83..d3609937875 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -63,7 +63,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { arguments.CheckFlagsConflicts(cmd, "input-file", "input-dir") }, Run: func(cmd *cobra.Command, args []string) { - runUploadCommand(args, uploadFields) + runUploadCommand(srv, args, uploadFields) }, } @@ -81,7 +81,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return uploadCommand } -func runUploadCommand(args []string, uploadFieldsArgs map[string]string) { +func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFieldsArgs map[string]string) { logrus.Info("Executing `arduino-cli upload`") path := "" @@ -176,7 +176,7 @@ func runUploadCommand(args []string, uploadFieldsArgs map[string]string) { prog := profile.GetProgrammer() if prog == "" || programmer.GetProgrammer() != "" { - prog = programmer.String(inst, fqbn) + prog = programmer.String(inst, srv, fqbn) } if prog == "" { prog = sketch.GetDefaultProgrammer() From 0df21493643bac764ba98a1919b88d06d8a331db Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Mar 2024 17:17:51 +0100 Subject: [PATCH 11/56] Inlining methods in ArduinoCoreServiceImpl (part 3: BoardList) This patch inlines BoardList and expands the gRPC API to provide the same output given to the cli. --- commands/service.go | 11 -- commands/service_board_list.go | 20 ++- internal/cli/arguments/completion.go | 16 +- internal/cli/arguments/fqbn.go | 4 +- internal/cli/arguments/port.go | 12 +- internal/cli/board/attach.go | 2 +- internal/cli/board/list.go | 8 +- internal/cli/burnbootloader/burnbootloader.go | 2 +- internal/cli/compile/compile.go | 4 +- internal/cli/debug/debug.go | 4 +- internal/cli/debug/debug_check.go | 2 +- internal/cli/monitor/monitor.go | 7 +- internal/cli/upload/upload.go | 4 +- rpc/cc/arduino/cli/commands/v1/board.pb.go | 155 ++++++++++-------- rpc/cc/arduino/cli/commands/v1/board.proto | 2 + 15 files changed, 129 insertions(+), 124 deletions(-) diff --git a/commands/service.go b/commands/service.go index b96bbf35635..387beb891f1 100644 --- a/commands/service.go +++ b/commands/service.go @@ -44,17 +44,6 @@ type arduinoCoreServerImpl struct { versionString string } -// BoardList FIXMEDOC -func (s *arduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { - ports, _, err := BoardList(req) - if err != nil { - return nil, err - } - return &rpc.BoardListResponse{ - Ports: ports, - }, 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 BoardSearch(ctx, req) diff --git a/commands/service_board_list.go b/commands/service_board_list.go index 5607d932bb9..7fe91c58472 100644 --- a/commands/service_board_list.go +++ b/commands/service_board_list.go @@ -29,6 +29,7 @@ import ( "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" + f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/arduino/cores" "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" "github.com/arduino/arduino-cli/internal/arduino/httpclient" @@ -204,10 +205,10 @@ func identify(pme *packagemanager.Explorer, port *discovery.Port) ([]*rpc.BoardL // BoardList returns a list of boards found by the loaded discoveries. // In case of errors partial results from discoveries that didn't fail // are returned. -func BoardList(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, discoveryStartErrors []error, e error) { +func (s *arduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardListRequest) (*rpc.BoardListResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { - return nil, nil, err + return nil, err } defer release() @@ -216,19 +217,19 @@ func BoardList(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, discoveryStart var err error fqbnFilter, err = cores.ParseFQBN(f) if err != nil { - return nil, nil, &cmderrors.InvalidFQBNError{Cause: err} + return nil, &cmderrors.InvalidFQBNError{Cause: err} } } dm := pme.DiscoveryManager() - discoveryStartErrors = dm.Start() + warnings := f.Map(dm.Start(), (error).Error) time.Sleep(time.Duration(req.GetTimeout()) * time.Millisecond) - retVal := []*rpc.DetectedPort{} + ports := []*rpc.DetectedPort{} for _, port := range dm.List() { boards, err := identify(pme, port) if err != nil { - return nil, discoveryStartErrors, err + warnings = append(warnings, err.Error()) } // boards slice can be empty at this point if neither the cores nor the @@ -239,10 +240,13 @@ func BoardList(req *rpc.BoardListRequest) (r []*rpc.DetectedPort, discoveryStart } if fqbnFilter == nil || hasMatchingBoard(b, fqbnFilter) { - retVal = append(retVal, b) + ports = append(ports, b) } } - return retVal, discoveryStartErrors, nil + return &rpc.BoardListResponse{ + Ports: ports, + Warnings: warnings, + }, nil } func hasMatchingBoard(b *rpc.DetectedPort, fqbnFilter *cores.FQBN) bool { diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index d21377a17c2..7291526e4d5 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -19,6 +19,7 @@ import ( "context" "github.com/arduino/arduino-cli/commands" + f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) @@ -164,16 +165,11 @@ func GetInstallableLibs() []string { // GetAvailablePorts is an helper function useful to autocomplete. // It returns a list of upload port of the boards which are currently connected. // It will not suggests network ports because the timeout is not set. -func GetAvailablePorts() []*rpc.Port { +func GetAvailablePorts(srv rpc.ArduinoCoreServiceServer) []*rpc.Port { + // Get the port list inst := instance.CreateAndInit() + list, _ := srv.BoardList(context.Background(), &rpc.BoardListRequest{Instance: inst}) - list, _, _ := commands.BoardList(&rpc.BoardListRequest{ - Instance: inst, - }) - var res []*rpc.Port - // transform the data structure for the completion - for _, i := range list { - res = append(res, i.GetPort()) - } - return res + // Transform the data structure for the completion (DetectedPort -> Port) + return f.Map(list.GetPorts(), (*rpc.DetectedPort).GetPort) } diff --git a/internal/cli/arguments/fqbn.go b/internal/cli/arguments/fqbn.go index 8760141b9d3..b3fd21d0c25 100644 --- a/internal/cli/arguments/fqbn.go +++ b/internal/cli/arguments/fqbn.go @@ -69,7 +69,7 @@ func (f *Fqbn) Set(fqbn string) { // - the port is not found, in this case nil is returned // - the FQBN autodetection fail, in this case the function prints an error and // terminates the execution -func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, defaultFQBN, defaultAddress, defaultProtocol string) (string, *rpc.Port) { +func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultFQBN, defaultAddress, defaultProtocol string) (string, *rpc.Port) { fqbn := fqbnArg.String() if fqbn == "" { fqbn = defaultFQBN @@ -78,7 +78,7 @@ func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, if portArgs == nil || portArgs.address == "" { feedback.FatalError(&cmderrors.MissingFQBNError{}, feedback.ErrGeneric) } - fqbn, port := portArgs.DetectFQBN(instance) + fqbn, port := portArgs.DetectFQBN(instance, srv) if fqbn == "" { feedback.FatalError(&cmderrors.MissingFQBNError{}, feedback.ErrGeneric) } diff --git a/internal/cli/arguments/port.go b/internal/cli/arguments/port.go index e696be1e3cb..86f461da93e 100644 --- a/internal/cli/arguments/port.go +++ b/internal/cli/arguments/port.go @@ -39,14 +39,14 @@ type Port struct { } // AddToCommand adds the flags used to set port and protocol to the specified Command -func (p *Port) AddToCommand(cmd *cobra.Command) { +func (p *Port) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&p.address, "port", "p", "", tr("Upload port address, e.g.: COM3 or /dev/ttyACM2")) cmd.RegisterFlagCompletionFunc("port", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return f.Map(GetAvailablePorts(), (*rpc.Port).GetAddress), cobra.ShellCompDirectiveDefault + return f.Map(GetAvailablePorts(srv), (*rpc.Port).GetAddress), cobra.ShellCompDirectiveDefault }) cmd.Flags().StringVarP(&p.protocol, "protocol", "l", "", tr("Upload port protocol, e.g: serial")) cmd.RegisterFlagCompletionFunc("protocol", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return f.Map(GetAvailablePorts(), (*rpc.Port).GetProtocol), cobra.ShellCompDirectiveDefault + return f.Map(GetAvailablePorts(srv), (*rpc.Port).GetProtocol), cobra.ShellCompDirectiveDefault }) p.timeout.AddToCommand(cmd) } @@ -129,15 +129,15 @@ func (p *Port) GetSearchTimeout() time.Duration { // DetectFQBN tries to identify the board connected to the port and returns the // discovered Port object together with the FQBN. If the port does not match // exactly 1 board, -func (p *Port) DetectFQBN(inst *rpc.Instance) (string, *rpc.Port) { - detectedPorts, _, err := commands.BoardList(&rpc.BoardListRequest{ +func (p *Port) DetectFQBN(inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer) (string, *rpc.Port) { + detectedPorts, err := srv.BoardList(context.Background(), &rpc.BoardListRequest{ Instance: inst, Timeout: p.timeout.Get().Milliseconds(), }) if err != nil { feedback.Fatal(tr("Error during FQBN detection: %v", err), feedback.ErrGeneric) } - for _, detectedPort := range detectedPorts { + for _, detectedPort := range detectedPorts.GetPorts() { port := detectedPort.GetPort() if p.address != port.GetAddress() { continue diff --git a/internal/cli/board/attach.go b/internal/cli/board/attach.go index 86b3c257061..d64326f18e2 100644 --- a/internal/cli/board/attach.go +++ b/internal/cli/board/attach.go @@ -49,7 +49,7 @@ func initAttachCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { }, } fqbn.AddToCommand(attachCommand, srv) - port.AddToCommand(attachCommand) + port.AddToCommand(attachCommand, srv) programmer.AddToCommand(attachCommand, srv) return attachCommand diff --git a/internal/cli/board/list.go b/internal/cli/board/list.go index 0e4e9a4cc11..3236813b0ba 100644 --- a/internal/cli/board/list.go +++ b/internal/cli/board/list.go @@ -46,7 +46,7 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " board list --discovery-timeout 10s", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runListCommand(watch, timeoutArg.Get().Milliseconds(), fqbn.String()) + runListCommand(srv, watch, timeoutArg.Get().Milliseconds(), fqbn.String()) }, } @@ -57,7 +57,7 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } // runListCommand detects and lists the connected arduino boards -func runListCommand(watch bool, timeout int64, fqbn string) { +func runListCommand(srv rpc.ArduinoCoreServiceServer, watch bool, timeout int64, fqbn string) { inst := instance.CreateAndInit() logrus.Info("Executing `arduino-cli board list`") @@ -67,11 +67,13 @@ func runListCommand(watch bool, timeout int64, fqbn string) { return } - ports, discoveryErrors, err := commands.BoardList(&rpc.BoardListRequest{ + list, err := srv.BoardList(context.Background(), &rpc.BoardListRequest{ Instance: inst, Timeout: timeout, Fqbn: fqbn, }) + ports := list.GetPorts() + discoveryErrors := list.GetWarnings() var invalidFQBNErr *cmderrors.InvalidFQBNError if errors.As(err, &invalidFQBNErr) { feedback.Fatal(tr(err.Error()), feedback.ErrBadArgument) diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index 999c2c137b8..6060b19f131 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -55,7 +55,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } fqbn.AddToCommand(burnBootloaderCommand, srv) - port.AddToCommand(burnBootloaderCommand) + port.AddToCommand(burnBootloaderCommand, srv) programmer.AddToCommand(burnBootloaderCommand, srv) burnBootloaderCommand.Flags().BoolVarP(&verify, "verify", "t", false, tr("Verify uploaded binary after the upload.")) burnBootloaderCommand.Flags().BoolVarP(&verbose, "verbose", "v", false, tr("Turns on verbose mode.")) diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index b03ecda1e02..52fb6d1b60b 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -117,7 +117,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { compileCommand.Flags().BoolVarP(&verbose, "verbose", "v", false, tr("Optional, turns on verbose mode.")) compileCommand.Flags().BoolVar(&quiet, "quiet", false, tr("Optional, suppresses almost every output.")) compileCommand.Flags().BoolVarP(&uploadAfterCompile, "upload", "u", false, tr("Upload the binary after the compilation.")) - portArgs.AddToCommand(compileCommand) + portArgs.AddToCommand(compileCommand, srv) compileCommand.Flags().BoolVarP(&verify, "verify", "t", false, tr("Verify uploaded binary after the upload.")) compileCommand.Flags().StringSliceVar(&library, "library", []string{}, tr("Path to a single library’s root folder. Can be used multiple times or entries can be comma separated.")) @@ -177,7 +177,7 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer fqbnArg.Set(profile.GetFqbn()) } - fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, inst, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) + fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) if keysKeychain != "" || signKey != "" || encryptKey != "" { arguments.CheckFlagsMandatory(cmd, "keys-keychain", "sign-key", "encrypt-key") diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index b4a04bd0c72..576f8cc6a20 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -62,7 +62,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { debugCommand.AddCommand(newDebugCheckCommand(srv)) fqbnArg.AddToCommand(debugCommand, srv) - portArgs.AddToCommand(debugCommand) + portArgs.AddToCommand(debugCommand, srv) programmer.AddToCommand(debugCommand, srv) profileArg.AddToCommand(debugCommand) debugCommand.Flags().StringVar(&interpreter, "interpreter", "console", tr("Debug interpreter e.g.: %s", "console, mi, mi1, mi2, mi3")) @@ -101,7 +101,7 @@ func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs * fqbnArg.Set(profile.GetFqbn()) } - fqbn, port := arguments.CalculateFQBNAndPort(portArgs, fqbnArg, inst, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) + fqbn, port := arguments.CalculateFQBNAndPort(portArgs, fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) prog := profile.GetProgrammer() if prog == "" || programmer.GetProgrammer() != "" { diff --git a/internal/cli/debug/debug_check.go b/internal/cli/debug/debug_check.go index 1cff21c02a3..111bc40215e 100644 --- a/internal/cli/debug/debug_check.go +++ b/internal/cli/debug/debug_check.go @@ -45,7 +45,7 @@ func newDebugCheckCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { }, } fqbnArg.AddToCommand(debugCheckCommand, srv) - portArgs.AddToCommand(debugCheckCommand) + portArgs.AddToCommand(debugCheckCommand, srv) programmer.AddToCommand(debugCheckCommand, srv) debugCheckCommand.Flags().StringVar(&interpreter, "interpreter", "console", tr("Debug interpreter e.g.: %s", "console, mi, mi1, mi2, mi3")) return debugCheckCommand diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 9442a1b8736..342df226ef5 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -66,10 +66,10 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { if len(args) > 0 { sketchPath = args[0] } - runMonitorCmd(&portArgs, &fqbnArg, &profileArg, sketchPath, configs, describe, timestamp, quiet, raw) + runMonitorCmd(srv, &portArgs, &fqbnArg, &profileArg, sketchPath, configs, describe, timestamp, quiet, raw) }, } - portArgs.AddToCommand(monitorCommand) + portArgs.AddToCommand(monitorCommand, srv) profileArg.AddToCommand(monitorCommand) monitorCommand.Flags().BoolVar(&raw, "raw", false, tr("Set terminal in raw mode (unbuffered).")) monitorCommand.Flags().BoolVar(&describe, "describe", false, tr("Show all the settings of the communication port.")) @@ -81,6 +81,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } func runMonitorCmd( + srv rpc.ArduinoCoreServiceServer, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, profileArg *arguments.Profile, sketchPathArg string, configs []string, describe, timestamp, quiet, raw bool, ) { @@ -136,7 +137,7 @@ func runMonitorCmd( case sketch.GetDefaultFqbn() != "": fqbn = sketch.GetDefaultFqbn() default: - fqbn, _ = portArgs.DetectFQBN(inst) + fqbn, _ = portArgs.DetectFQBN(inst, srv) } portAddress, portProtocol, err := portArgs.GetPortAddressAndProtocol(inst, defaultPort, defaultProtocol) diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index d3609937875..125b25d317d 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -68,7 +68,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } fqbnArg.AddToCommand(uploadCommand, srv) - portArgs.AddToCommand(uploadCommand) + portArgs.AddToCommand(uploadCommand, srv) profileArg.AddToCommand(uploadCommand) uploadCommand.Flags().StringVarP(&importDir, "input-dir", "", "", tr("Directory containing binaries to upload.")) uploadCommand.Flags().StringVarP(&importFile, "input-file", "i", "", tr("Binary file to upload.")) @@ -113,7 +113,7 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie defaultFQBN := sketch.GetDefaultFqbn() defaultAddress := sketch.GetDefaultPort() defaultProtocol := sketch.GetDefaultProtocol() - fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, inst, defaultFQBN, defaultAddress, defaultProtocol) + fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, inst, srv, defaultFQBN, defaultAddress, defaultProtocol) userFieldRes, err := commands.SupportedUserFields(context.Background(), &rpc.SupportedUserFieldsRequest{ Instance: inst, diff --git a/rpc/cc/arduino/cli/commands/v1/board.pb.go b/rpc/cc/arduino/cli/commands/v1/board.pb.go index 479446d50e6..65e778c1ba6 100644 --- a/rpc/cc/arduino/cli/commands/v1/board.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/board.pb.go @@ -935,6 +935,8 @@ type BoardListResponse struct { // List of ports and the boards detected on those ports. Ports []*DetectedPort `protobuf:"bytes,1,rep,name=ports,proto3" json:"ports,omitempty"` + // Warning messages or errors coming from the discoveries. + Warnings []string `protobuf:"bytes,2,rep,name=warnings,proto3" json:"warnings,omitempty"` } func (x *BoardListResponse) Reset() { @@ -976,6 +978,13 @@ func (x *BoardListResponse) GetPorts() []*DetectedPort { return nil } +func (x *BoardListResponse) GetWarnings() []string { + if x != nil { + return x.Warnings + } + return nil +} + type DetectedPort struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1606,84 +1615,86 @@ var file_cc_arduino_cli_commands_v1_board_proto_rawDesc = []byte{ 0x63, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x22, 0x53, 0x0a, 0x11, 0x42, 0x6f, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x22, 0x6f, 0x0a, 0x11, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 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, 0x44, 0x65, 0x74, 0x65, - 0x63, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x22, - 0x98, 0x01, 0x0a, 0x0c, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, - 0x12, 0x52, 0x0a, 0x0f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 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, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, - 0x49, 0x74, 0x65, 0x6d, 0x52, 0x0e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x42, 0x6f, - 0x61, 0x72, 0x64, 0x73, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, + 0x63, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x05, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x12, + 0x1a, 0x0a, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x08, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x0c, + 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x52, 0x0a, 0x0f, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 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, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, + 0x52, 0x0e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x73, + 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 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, 0x22, 0xac, 0x01, 0x0a, 0x13, 0x42, 0x6f, 0x61, 0x72, 0x64, + 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 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, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x72, 0x67, + 0x73, 0x12, 0x32, 0x0a, 0x15, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x68, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x13, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x42, + 0x6f, 0x61, 0x72, 0x64, 0x73, 0x22, 0x59, 0x0a, 0x14, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, + 0x06, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 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, 0x6f, 0x61, 0x72, 0x64, + 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x73, + 0x22, 0x59, 0x0a, 0x15, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x74, + 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, 0x22, 0x8b, 0x01, 0x0a, 0x16, + 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 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, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x70, + 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x96, 0x01, 0x0a, 0x0d, 0x42, 0x6f, + 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, + 0x71, 0x62, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, + 0x12, 0x40, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x06, 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, 0x6f, 0x72, 0x74, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x22, 0xac, 0x01, 0x0a, 0x13, 0x42, - 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 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, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x41, 0x72, 0x67, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x5f, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x48, 0x69, 0x64, - 0x64, 0x65, 0x6e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x22, 0x59, 0x0a, 0x14, 0x42, 0x6f, 0x61, - 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x41, 0x0a, 0x06, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x29, 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, - 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x62, 0x6f, - 0x61, 0x72, 0x64, 0x73, 0x22, 0x59, 0x0a, 0x15, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, - 0x74, 0x57, 0x61, 0x74, 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, 0x22, - 0x8b, 0x01, 0x0a, 0x16, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x57, 0x61, 0x74, - 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x04, 0x70, 0x6f, 0x72, - 0x74, 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, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x72, - 0x74, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x96, 0x01, - 0x0a, 0x0d, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x66, 0x71, 0x62, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x68, 0x69, - 0x64, 0x64, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x48, 0x69, - 0x64, 0x64, 0x65, 0x6e, 0x12, 0x40, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x18, 0x06, 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, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, - 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0xab, 0x01, 0x0a, 0x12, 0x42, 0x6f, 0x61, 0x72, 0x64, - 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, 0x32, 0x0a, 0x15, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x68, 0x69, 0x64, 0x64, - 0x65, 0x6e, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x13, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x42, 0x6f, - 0x61, 0x72, 0x64, 0x73, 0x22, 0x58, 0x0a, 0x13, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x62, - 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x63, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, + 0x72, 0x6d, 0x22, 0xab, 0x01, 0x0a, 0x12, 0x42, 0x6f, 0x61, 0x72, 0x64, 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, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, - 0x73, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x06, 0x62, 0x6f, 0x61, 0x72, 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, + 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, 0x32, 0x0a, 0x15, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x5f, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x48, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x73, + 0x22, 0x58, 0x0a, 0x13, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x06, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 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, 0x6f, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x74, + 0x65, 0x6d, 0x52, 0x06, 0x62, 0x6f, 0x61, 0x72, 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 ( diff --git a/rpc/cc/arduino/cli/commands/v1/board.proto b/rpc/cc/arduino/cli/commands/v1/board.proto index 8918473ec86..46a48c945f7 100644 --- a/rpc/cc/arduino/cli/commands/v1/board.proto +++ b/rpc/cc/arduino/cli/commands/v1/board.proto @@ -166,6 +166,8 @@ message BoardListRequest { message BoardListResponse { // List of ports and the boards detected on those ports. repeated DetectedPort ports = 1; + // Warning messages or errors coming from the discoveries. + repeated string warnings = 2; } message DetectedPort { From f65eff25067241587adc0ebda1983d6d1b0df354 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 14 Mar 2024 10:55:50 +0100 Subject: [PATCH 12/56] Inlining methods in ArduinoCoreServiceImpl (part 4: BoardListWatch) The BoardListWatch RPC call has been converted into a method of the gRPC server implementation. This commit boasts an helper method to convert a gRPC streaming response into a channel. --- commands/grpc_streaming_helpers.go | 78 +++++++++++++++++++ commands/service.go | 32 -------- commands/service_board_list.go | 34 +++++--- commands/service_board_search.go | 2 +- internal/cli/arguments/fqbn.go | 2 +- internal/cli/arguments/port.go | 12 +-- internal/cli/board/attach.go | 6 +- internal/cli/board/board.go | 2 +- internal/cli/board/list.go | 7 +- internal/cli/board/search.go | 11 +-- internal/cli/burnbootloader/burnbootloader.go | 2 +- internal/cli/debug/debug_check.go | 2 +- internal/cli/monitor/monitor.go | 2 +- .../integrationtest/daemon/daemon_test.go | 6 +- 14 files changed, 131 insertions(+), 67 deletions(-) create mode 100644 commands/grpc_streaming_helpers.go diff --git a/commands/grpc_streaming_helpers.go b/commands/grpc_streaming_helpers.go new file mode 100644 index 00000000000..d86dfd61795 --- /dev/null +++ b/commands/grpc_streaming_helpers.go @@ -0,0 +1,78 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 ( + "context" + "errors" + "sync" + + "google.golang.org/grpc/metadata" +) + +type streamingResponseProxyToChan[T any] struct { + ctx context.Context + respChan chan<- *T + respLock sync.Mutex +} + +func streamResponseToChan[T any](ctx context.Context) (*streamingResponseProxyToChan[T], <-chan *T) { + respChan := make(chan *T, 1) + w := &streamingResponseProxyToChan[T]{ + ctx: ctx, + respChan: respChan, + } + go func() { + <-ctx.Done() + w.respLock.Lock() + close(w.respChan) + w.respChan = nil + w.respLock.Unlock() + }() + return w, respChan +} + +func (w *streamingResponseProxyToChan[T]) Send(resp *T) error { + w.respLock.Lock() + if w.respChan != nil { + w.respChan <- resp + } + w.respLock.Unlock() + return nil +} + +func (w *streamingResponseProxyToChan[T]) Context() context.Context { + return w.ctx +} + +func (w *streamingResponseProxyToChan[T]) RecvMsg(m any) error { + return errors.New("RecvMsg not implemented") +} + +func (w *streamingResponseProxyToChan[T]) SendHeader(metadata.MD) error { + return errors.New("SendHeader not implemented") +} + +func (w *streamingResponseProxyToChan[T]) SendMsg(m any) error { + return errors.New("SendMsg not implemented") +} + +func (w *streamingResponseProxyToChan[T]) SetHeader(metadata.MD) error { + return errors.New("SetHeader not implemented") +} + +func (w *streamingResponseProxyToChan[T]) SetTrailer(tr metadata.MD) { +} diff --git a/commands/service.go b/commands/service.go index 387beb891f1..7faa8043f47 100644 --- a/commands/service.go +++ b/commands/service.go @@ -18,7 +18,6 @@ package commands import ( "context" "errors" - "fmt" "io" "sync/atomic" @@ -44,37 +43,6 @@ type arduinoCoreServerImpl struct { versionString string } -// BoardSearch exposes to the gRPC interface the board search command -func (s *arduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { - return BoardSearch(ctx, req) -} - -// BoardListWatch FIXMEDOC -func (s *arduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, stream rpc.ArduinoCoreService_BoardListWatchServer) error { - syncSend := NewSynchronizedSend(stream.Send) - if req.GetInstance() == nil { - err := fmt.Errorf(tr("no instance specified")) - syncSend.Send(&rpc.BoardListWatchResponse{ - EventType: "error", - Error: err.Error(), - }) - return err - } - - eventsChan, err := BoardListWatch(stream.Context(), req) - if err != nil { - return err - } - - for event := range eventsChan { - if err := syncSend.Send(event); err != nil { - logrus.Infof("sending board watch message: %v", err) - } - } - - return nil -} - // Destroy FIXMEDOC func (s *arduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { return Destroy(ctx, req) diff --git a/commands/service_board_list.go b/commands/service_board_list.go index 7fe91c58472..ba6cd3c727f 100644 --- a/commands/service_board_list.go +++ b/commands/service_board_list.go @@ -262,29 +262,43 @@ func hasMatchingBoard(b *rpc.DetectedPort, fqbnFilter *cores.FQBN) bool { return false } -// BoardListWatch returns a channel that receives boards connection and disconnection events. -func BoardListWatch(ctx context.Context, req *rpc.BoardListWatchRequest) (<-chan *rpc.BoardListWatchResponse, error) { +// BoardListWatchProxyToChan return a stream, to be used in BoardListWatch method, +// that proxies all the responses to a channel. +func BoardListWatchProxyToChan(ctx context.Context) (rpc.ArduinoCoreService_BoardListWatchServer, <-chan *rpc.BoardListWatchResponse) { + return streamResponseToChan[rpc.BoardListWatchResponse](ctx) +} + +// BoardListWatch FIXMEDOC +func (s *arduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, stream rpc.ArduinoCoreService_BoardListWatchServer) error { + syncSend := NewSynchronizedSend(stream.Send) + if req.GetInstance() == nil { + err := fmt.Errorf(tr("no instance specified")) + syncSend.Send(&rpc.BoardListWatchResponse{ + EventType: "error", + Error: err.Error(), + }) + return err + } + pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { - return nil, err + return err } defer release() dm := pme.DiscoveryManager() watcher, err := dm.Watch() if err != nil { - return nil, err + return err } go func() { - <-ctx.Done() + <-stream.Context().Done() logrus.Trace("closed watch") watcher.Close() }() - outChan := make(chan *rpc.BoardListWatchResponse) go func() { - defer close(outChan) for event := range watcher.Feed() { port := &rpc.DetectedPort{ Port: rpc.DiscoveryPortToRPC(event.Port), @@ -298,13 +312,13 @@ func BoardListWatch(ctx context.Context, req *rpc.BoardListWatchRequest) (<-chan } port.MatchingBoards = boards } - outChan <- &rpc.BoardListWatchResponse{ + stream.Send(&rpc.BoardListWatchResponse{ EventType: event.Type, Port: port, Error: boardsError, - } + }) } }() - return outChan, nil + return nil } diff --git a/commands/service_board_search.go b/commands/service_board_search.go index 4bfd0906a20..a3714b669c2 100644 --- a/commands/service_board_search.go +++ b/commands/service_board_search.go @@ -29,7 +29,7 @@ import ( // 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 BoardSearch(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { +func (s *arduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardSearchRequest) (*rpc.BoardSearchResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/internal/cli/arguments/fqbn.go b/internal/cli/arguments/fqbn.go index b3fd21d0c25..a6c3505767a 100644 --- a/internal/cli/arguments/fqbn.go +++ b/internal/cli/arguments/fqbn.go @@ -85,7 +85,7 @@ func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, return fqbn, port } - port, err := portArgs.GetPort(instance, defaultAddress, defaultProtocol) + port, err := portArgs.GetPort(instance, srv, defaultAddress, defaultProtocol) if err != nil { feedback.Fatal(tr("Error getting port metadata: %v", err), feedback.ErrGeneric) } diff --git a/internal/cli/arguments/port.go b/internal/cli/arguments/port.go index 86f461da93e..9bd7ce99b80 100644 --- a/internal/cli/arguments/port.go +++ b/internal/cli/arguments/port.go @@ -56,12 +56,12 @@ func (p *Port) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer // This method allows will bypass the discoveries if: // - a nil instance is passed: in this case the plain port and protocol arguments are returned (even if empty) // - a protocol is specified: in this case the discoveries are not needed to autodetect the protocol. -func (p *Port) GetPortAddressAndProtocol(instance *rpc.Instance, defaultAddress, defaultProtocol string) (string, string, error) { +func (p *Port) GetPortAddressAndProtocol(instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string) (string, string, error) { if p.protocol != "" || instance == nil { return p.address, p.protocol, nil } - port, err := p.GetPort(instance, defaultAddress, defaultProtocol) + port, err := p.GetPort(instance, srv, defaultAddress, defaultProtocol) if err != nil { return "", "", err } @@ -70,8 +70,7 @@ func (p *Port) GetPortAddressAndProtocol(instance *rpc.Instance, defaultAddress, // GetPort returns the Port obtained by parsing command line arguments. // The extra metadata for the ports is obtained using the pluggable discoveries. -func (p *Port) GetPort(instance *rpc.Instance, defaultAddress, defaultProtocol string) (*rpc.Port, error) { - +func (p *Port) GetPort(instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string) (*rpc.Port, error) { address := p.address protocol := p.protocol if address == "" && (defaultAddress != "" || defaultProtocol != "") { @@ -91,7 +90,10 @@ func (p *Port) GetPort(instance *rpc.Instance, defaultAddress, defaultProtocol s ctx, cancel := context.WithCancel(context.Background()) defer cancel() - watcher, err := commands.BoardListWatch(ctx, &rpc.BoardListWatchRequest{Instance: instance}) + + stream, watcher := commands.BoardListWatchProxyToChan(ctx) + err := srv.BoardListWatch(&rpc.BoardListWatchRequest{Instance: instance}, stream) + if err != nil { return nil, err } diff --git a/internal/cli/board/attach.go b/internal/cli/board/attach.go index d64326f18e2..627f014760c 100644 --- a/internal/cli/board/attach.go +++ b/internal/cli/board/attach.go @@ -45,7 +45,7 @@ func initAttachCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { if len(args) > 0 { sketchPath = args[0] } - runAttachCommand(sketchPath, &port, fqbn.String(), &programmer) + runAttachCommand(srv, sketchPath, &port, fqbn.String(), &programmer) }, } fqbn.AddToCommand(attachCommand, srv) @@ -55,10 +55,10 @@ func initAttachCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return attachCommand } -func runAttachCommand(path string, port *arguments.Port, fqbn string, programmer *arguments.Programmer) { +func runAttachCommand(srv rpc.ArduinoCoreServiceServer, path string, port *arguments.Port, fqbn string, programmer *arguments.Programmer) { sketchPath := arguments.InitSketchPath(path) - portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(nil, "", "") + portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(nil, srv, "", "") newDefaults, err := commands.SetSketchDefaults(context.Background(), &rpc.SetSketchDefaultsRequest{ SketchPath: sketchPath.String(), DefaultFqbn: fqbn, diff --git a/internal/cli/board/board.go b/internal/cli/board/board.go index 3c3b99a51b5..f07ff8c0ac3 100644 --- a/internal/cli/board/board.go +++ b/internal/cli/board/board.go @@ -39,7 +39,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { boardCommand.AddCommand(initDetailsCommand(srv)) boardCommand.AddCommand(initListCommand(srv)) boardCommand.AddCommand(initListAllCommand(srv)) - boardCommand.AddCommand(initSearchCommand()) + boardCommand.AddCommand(initSearchCommand(srv)) return boardCommand } diff --git a/internal/cli/board/list.go b/internal/cli/board/list.go index 3236813b0ba..b27869a459c 100644 --- a/internal/cli/board/list.go +++ b/internal/cli/board/list.go @@ -63,7 +63,7 @@ func runListCommand(srv rpc.ArduinoCoreServiceServer, watch bool, timeout int64, logrus.Info("Executing `arduino-cli board list`") if watch { - watchList(inst) + watchList(inst, srv) return } @@ -88,8 +88,9 @@ func runListCommand(srv rpc.ArduinoCoreServiceServer, watch bool, timeout int64, feedback.PrintResult(listResult{result.NewDetectedPorts(ports)}) } -func watchList(inst *rpc.Instance) { - eventsChan, err := commands.BoardListWatch(context.Background(), &rpc.BoardListWatchRequest{Instance: inst}) +func watchList(inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer) { + stream, eventsChan := commands.BoardListWatchProxyToChan(context.Background()) + err := srv.BoardListWatch(&rpc.BoardListWatchRequest{Instance: inst}, stream) if err != nil { feedback.Fatal(tr("Error detecting boards: %v", err), feedback.ErrNetwork) } diff --git a/internal/cli/board/search.go b/internal/cli/board/search.go index b52a704c1dc..ee3cb40e1bb 100644 --- a/internal/cli/board/search.go +++ b/internal/cli/board/search.go @@ -22,7 +22,6 @@ import ( "sort" "strings" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -32,7 +31,7 @@ import ( "github.com/spf13/cobra" ) -func initSearchCommand() *cobra.Command { +func initSearchCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var searchCommand = &cobra.Command{ Use: fmt.Sprintf("search [%s]", tr("boardname")), Short: tr("Search for a board in the Boards Manager."), @@ -41,18 +40,20 @@ func initSearchCommand() *cobra.Command { " " + os.Args[0] + " board search\n" + " " + os.Args[0] + " board search zero", Args: cobra.ArbitraryArgs, - Run: runSearchCommand, + Run: func(cmd *cobra.Command, args []string) { + runSearchCommand(srv, args) + }, } searchCommand.Flags().BoolVarP(&showHiddenBoard, "show-hidden", "a", false, tr("Show also boards marked as 'hidden' in the platform")) return searchCommand } -func runSearchCommand(cmd *cobra.Command, args []string) { +func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string) { inst := instance.CreateAndInit() logrus.Info("Executing `arduino-cli board search`") - res, err := commands.BoardSearch(context.Background(), &rpc.BoardSearchRequest{ + res, err := srv.BoardSearch(context.Background(), &rpc.BoardSearchRequest{ Instance: inst, SearchArgs: strings.Join(args, " "), IncludeHiddenBoards: showHiddenBoard, diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index 6060b19f131..23dc605a710 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -71,7 +71,7 @@ func runBootloaderCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli burn-bootloader`") // We don't need a Sketch to upload a board's bootloader - discoveryPort, err := port.GetPort(instance, "", "") + discoveryPort, err := port.GetPort(instance, srv, "", "") if err != nil { feedback.Fatal(tr("Error during Upload: %v", err), feedback.ErrGeneric) } diff --git a/internal/cli/debug/debug_check.go b/internal/cli/debug/debug_check.go index 111bc40215e..7be9393b5c0 100644 --- a/internal/cli/debug/debug_check.go +++ b/internal/cli/debug/debug_check.go @@ -55,7 +55,7 @@ func runDebugCheckCommand(srv rpc.ArduinoCoreServiceServer, portArgs *arguments. instance := instance.CreateAndInit() logrus.Info("Executing `arduino-cli debug`") - port, err := portArgs.GetPort(instance, "", "") + port, err := portArgs.GetPort(instance, srv, "", "") if err != nil { feedback.FatalError(err, feedback.ErrBadArgument) } diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 342df226ef5..597933939a3 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -140,7 +140,7 @@ func runMonitorCmd( fqbn, _ = portArgs.DetectFQBN(inst, srv) } - portAddress, portProtocol, err := portArgs.GetPortAddressAndProtocol(inst, defaultPort, defaultProtocol) + portAddress, portProtocol, err := portArgs.GetPortAddressAndProtocol(inst, srv, defaultPort, defaultProtocol) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } diff --git a/internal/integrationtest/daemon/daemon_test.go b/internal/integrationtest/daemon/daemon_test.go index 297ba4b59af..f994813b69e 100644 --- a/internal/integrationtest/daemon/daemon_test.go +++ b/internal/integrationtest/daemon/daemon_test.go @@ -63,15 +63,15 @@ func TestArduinoCliDaemon(t *testing.T) { require.NoError(t, err) watcherCanceldCh := make(chan struct{}) go func() { + defer close(watcherCanceldCh) for { msg, err := watcher.Recv() if errors.Is(err, io.EOF) { - fmt.Println("Watcher EOF") + fmt.Println("Got EOF from watcher") return } if s, ok := status.FromError(err); ok && s.Code() == codes.Canceled { - fmt.Println("Watcher canceled") - watcherCanceldCh <- struct{}{} + fmt.Println("Got Canceled error from watcher") return } require.NoError(t, err, "BoardListWatch grpc call returned an error") From 06d6842ab2a5f6e03b2b783b4e4c308448a2decf Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 14 Mar 2024 12:20:15 +0100 Subject: [PATCH 13/56] Inlining methods in ArduinoCoreServiceImpl (part 5: Create and Destroy) --- commands/instances.go | 19 +++++++--- commands/service.go | 18 --------- commands/service_platform_search_test.go | 10 ++++- internal/cli/arguments/completion.go | 38 +++++++++---------- internal/cli/arguments/fqbn.go | 3 +- internal/cli/arguments/port.go | 4 +- internal/cli/arguments/programmer.go | 2 +- internal/cli/arguments/reference.go | 10 +++-- internal/cli/arguments/reference_test.go | 11 ++++-- internal/cli/board/details.go | 3 +- internal/cli/board/list.go | 3 +- internal/cli/board/listall.go | 3 +- internal/cli/board/search.go | 3 +- internal/cli/burnbootloader/burnbootloader.go | 3 +- internal/cli/cli.go | 8 ++-- internal/cli/compile/compile.go | 5 ++- internal/cli/core/core.go | 17 +++++---- internal/cli/core/download.go | 15 +++++--- internal/cli/core/install.go | 13 ++++--- internal/cli/core/list.go | 10 +++-- internal/cli/core/search.go | 9 +++-- internal/cli/core/uninstall.go | 13 ++++--- internal/cli/core/update_index.go | 11 ++++-- internal/cli/core/upgrade.go | 15 ++++---- internal/cli/debug/debug.go | 5 ++- internal/cli/debug/debug_check.go | 3 +- internal/cli/instance/instance.go | 14 ++++--- internal/cli/lib/check_deps.go | 12 +++--- internal/cli/lib/download.go | 14 ++++--- internal/cli/lib/examples.go | 11 ++++-- internal/cli/lib/install.go | 11 +++--- internal/cli/lib/lib.go | 14 +++---- internal/cli/lib/list.go | 3 +- internal/cli/lib/search.go | 9 +++-- internal/cli/lib/uninstall.go | 13 ++++--- internal/cli/lib/update_index.go | 12 ++++-- internal/cli/lib/upgrade.go | 11 ++++-- internal/cli/monitor/monitor.go | 7 ++-- internal/cli/outdated/outdated.go | 12 ++++-- internal/cli/update/update.go | 12 ++++-- internal/cli/upgrade/upgrade.go | 13 ++++--- internal/cli/upload/upload.go | 6 ++- 42 files changed, 246 insertions(+), 182 deletions(-) diff --git a/commands/instances.go b/commands/instances.go index ba067358cca..92c317fe836 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -42,6 +42,7 @@ import ( paths "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -59,8 +60,16 @@ func installTool(pm *packagemanager.PackageManager, tool *cores.ToolRelease, dow return nil } -// Create a new CoreInstance ready to be initialized, supporting directories are also created. -func Create(req *rpc.CreateRequest, extraUserAgent ...string) (*rpc.CreateResponse, error) { +// Create a new Instance ready to be initialized, supporting directories are also created. +func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateRequest) (*rpc.CreateResponse, error) { + var userAgent []string + if md, ok := metadata.FromIncomingContext(ctx); ok { + userAgent = md.Get("user-agent") + } + if len(userAgent) == 0 { + userAgent = []string{"gRPCClientUnknown/0.0.0"} + } + // Setup downloads directory downloadsDir := configuration.DownloadsDir(configuration.Settings) if downloadsDir.NotExist() { @@ -80,7 +89,7 @@ func Create(req *rpc.CreateRequest, extraUserAgent ...string) (*rpc.CreateRespon } } - inst, err := instances.Create(dataDir, packagesDir, downloadsDir, extraUserAgent...) + inst, err := instances.Create(dataDir, packagesDir, downloadsDir, userAgent...) if err != nil { return nil, err } @@ -397,8 +406,8 @@ func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) erro return nil } -// Destroy FIXMEDOC -func Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { +// Destroy deletes an instance. +func (s *arduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { if ok := instances.Delete(req.GetInstance()); !ok { return nil, &cmderrors.InvalidInstanceError{} } diff --git a/commands/service.go b/commands/service.go index 7faa8043f47..548a93d9a5f 100644 --- a/commands/service.go +++ b/commands/service.go @@ -26,7 +26,6 @@ import ( "github.com/arduino/arduino-cli/commands/updatecheck" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" - "google.golang.org/grpc/metadata" ) // NewArduinoCoreServer returns an implementation of the ArduinoCoreService gRPC service @@ -43,11 +42,6 @@ type arduinoCoreServerImpl struct { versionString string } -// Destroy FIXMEDOC -func (s *arduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyRequest) (*rpc.DestroyResponse, error) { - return Destroy(ctx, req) -} - // UpdateIndex FIXMEDOC func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream rpc.ArduinoCoreService_UpdateIndexServer) error { syncSend := NewSynchronizedSend(stream.Send) @@ -84,18 +78,6 @@ func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd return err } -// Create FIXMEDOC -func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateRequest) (*rpc.CreateResponse, error) { - var userAgent []string - if md, ok := metadata.FromIncomingContext(ctx); ok { - userAgent = md.Get("user-agent") - } - if len(userAgent) == 0 { - userAgent = []string{"gRPCClientUnknown/0.0.0"} - } - return Create(req, userAgent...) -} - // Init FIXMEDOC func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { syncSend := NewSynchronizedSend(stream.Send) diff --git a/commands/service_platform_search_test.go b/commands/service_platform_search_test.go index c6d7b789a2d..83942433321 100644 --- a/commands/service_platform_search_test.go +++ b/commands/service_platform_search_test.go @@ -16,6 +16,7 @@ package commands import ( + "context" "testing" "github.com/arduino/arduino-cli/internal/cli/configuration" @@ -37,7 +38,9 @@ func TestPlatformSearch(t *testing.T) { configuration.Settings = configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) - createResp, err := Create(&rpc.CreateRequest{}) + srv := NewArduinoCoreServer("") + ctx := context.Background() + createResp, err := srv.Create(ctx, &rpc.CreateRequest{}) require.NoError(t, err) inst := createResp.GetInstance() @@ -337,7 +340,10 @@ func TestPlatformSearchSorting(t *testing.T) { configuration.Settings = configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) - createResp, err := Create(&rpc.CreateRequest{}) + srv := NewArduinoCoreServer("") + ctx := context.Background() + + createResp, err := srv.Create(ctx, &rpc.CreateRequest{}) require.NoError(t, err) inst := createResp.GetInstance() require.NotNil(t, inst) diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index 7291526e4d5..c86a657793a 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -27,8 +27,8 @@ import ( // GetInstalledBoards is an helper function useful to autocomplete. // It returns a list of fqbn // it's taken from cli/board/listall.go -func GetInstalledBoards(srv rpc.ArduinoCoreServiceServer) []string { - inst := instance.CreateAndInit() +func GetInstalledBoards(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { + inst := instance.CreateAndInit(srv, ctx) list, _ := srv.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ Instance: inst, @@ -45,8 +45,8 @@ func GetInstalledBoards(srv rpc.ArduinoCoreServiceServer) []string { // GetInstalledProgrammers is an helper function useful to autocomplete. // It returns a list of programmers available based on the installed boards -func GetInstalledProgrammers(srv rpc.ArduinoCoreServiceServer) []string { - inst := instance.CreateAndInit() +func GetInstalledProgrammers(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { + inst := instance.CreateAndInit(srv, ctx) // we need the list of the available fqbn in order to get the list of the programmers listAllReq := &rpc.BoardListAllRequest{ @@ -78,8 +78,8 @@ func GetInstalledProgrammers(srv rpc.ArduinoCoreServiceServer) []string { // GetUninstallableCores is an helper function useful to autocomplete. // It returns a list of cores which can be uninstalled -func GetUninstallableCores() []string { - inst := instance.CreateAndInit() +func GetUninstallableCores(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { + inst := instance.CreateAndInit(srv, ctx) platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, @@ -99,8 +99,8 @@ func GetUninstallableCores() []string { // GetInstallableCores is an helper function useful to autocomplete. // It returns a list of cores which can be installed/downloaded -func GetInstallableCores() []string { - inst := instance.CreateAndInit() +func GetInstallableCores(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { + inst := instance.CreateAndInit(srv, ctx) platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, @@ -118,18 +118,18 @@ func GetInstallableCores() []string { // GetInstalledLibraries is an helper function useful to autocomplete. // It returns a list of libs which are currently installed, including the builtin ones -func GetInstalledLibraries() []string { - return getLibraries(true) +func GetInstalledLibraries(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { + return getLibraries(srv, ctx, true) } // GetUninstallableLibraries is an helper function useful to autocomplete. // It returns a list of libs which can be uninstalled -func GetUninstallableLibraries() []string { - return getLibraries(false) +func GetUninstallableLibraries(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { + return getLibraries(srv, ctx, false) } -func getLibraries(all bool) []string { - inst := instance.CreateAndInit() +func getLibraries(srv rpc.ArduinoCoreServiceServer, ctx context.Context, all bool) []string { + inst := instance.CreateAndInit(srv, ctx) libs, _ := commands.LibraryList(context.Background(), &rpc.LibraryListRequest{ Instance: inst, All: all, @@ -147,8 +147,8 @@ func getLibraries(all bool) []string { // GetInstallableLibs is an helper function useful to autocomplete. // It returns a list of libs which can be installed/downloaded -func GetInstallableLibs() []string { - inst := instance.CreateAndInit() +func GetInstallableLibs(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { + inst := instance.CreateAndInit(srv, ctx) libs, _ := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ Instance: inst, @@ -165,10 +165,10 @@ func GetInstallableLibs() []string { // GetAvailablePorts is an helper function useful to autocomplete. // It returns a list of upload port of the boards which are currently connected. // It will not suggests network ports because the timeout is not set. -func GetAvailablePorts(srv rpc.ArduinoCoreServiceServer) []*rpc.Port { +func GetAvailablePorts(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []*rpc.Port { // Get the port list - inst := instance.CreateAndInit() - list, _ := srv.BoardList(context.Background(), &rpc.BoardListRequest{Instance: inst}) + inst := instance.CreateAndInit(srv, ctx) + list, _ := srv.BoardList(ctx, &rpc.BoardListRequest{Instance: inst}) // Transform the data structure for the completion (DetectedPort -> Port) return f.Map(list.GetPorts(), (*rpc.DetectedPort).GetPort) diff --git a/internal/cli/arguments/fqbn.go b/internal/cli/arguments/fqbn.go index a6c3505767a..26c1248e2b4 100644 --- a/internal/cli/arguments/fqbn.go +++ b/internal/cli/arguments/fqbn.go @@ -16,6 +16,7 @@ package arguments import ( + "context" "strings" "github.com/arduino/arduino-cli/commands/cmderrors" @@ -36,7 +37,7 @@ type Fqbn struct { func (f *Fqbn) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&f.fqbn, "fqbn", "b", "", tr("Fully Qualified Board Name, e.g.: arduino:avr:uno")) cmd.RegisterFlagCompletionFunc("fqbn", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetInstalledBoards(srv), cobra.ShellCompDirectiveDefault + return GetInstalledBoards(srv, context.Background()), cobra.ShellCompDirectiveDefault }) cmd.Flags().StringSliceVar(&f.boardOptions, "board-options", []string{}, tr("List of board options separated by commas. Or can be used multiple times for multiple options.")) diff --git a/internal/cli/arguments/port.go b/internal/cli/arguments/port.go index 9bd7ce99b80..51247603438 100644 --- a/internal/cli/arguments/port.go +++ b/internal/cli/arguments/port.go @@ -42,11 +42,11 @@ type Port struct { func (p *Port) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&p.address, "port", "p", "", tr("Upload port address, e.g.: COM3 or /dev/ttyACM2")) cmd.RegisterFlagCompletionFunc("port", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return f.Map(GetAvailablePorts(srv), (*rpc.Port).GetAddress), cobra.ShellCompDirectiveDefault + return f.Map(GetAvailablePorts(srv, context.Background()), (*rpc.Port).GetAddress), cobra.ShellCompDirectiveDefault }) cmd.Flags().StringVarP(&p.protocol, "protocol", "l", "", tr("Upload port protocol, e.g: serial")) cmd.RegisterFlagCompletionFunc("protocol", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return f.Map(GetAvailablePorts(srv), (*rpc.Port).GetProtocol), cobra.ShellCompDirectiveDefault + return f.Map(GetAvailablePorts(srv, context.Background()), (*rpc.Port).GetProtocol), cobra.ShellCompDirectiveDefault }) p.timeout.AddToCommand(cmd) } diff --git a/internal/cli/arguments/programmer.go b/internal/cli/arguments/programmer.go index c76271b0ede..ed3eb2f8043 100644 --- a/internal/cli/arguments/programmer.go +++ b/internal/cli/arguments/programmer.go @@ -33,7 +33,7 @@ type Programmer struct { func (p *Programmer) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&p.programmer, "programmer", "P", "", tr("Programmer to use, e.g: atmel_ice")) cmd.RegisterFlagCompletionFunc("programmer", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetInstalledProgrammers(srv), cobra.ShellCompDirectiveDefault + return GetInstalledProgrammers(srv, context.Background()), cobra.ShellCompDirectiveDefault }) } diff --git a/internal/cli/arguments/reference.go b/internal/cli/arguments/reference.go index 7593fd4e54e..a8c828890e1 100644 --- a/internal/cli/arguments/reference.go +++ b/internal/cli/arguments/reference.go @@ -16,6 +16,7 @@ package arguments import ( + "context" "fmt" "strings" @@ -43,10 +44,11 @@ func (r *Reference) String() string { // ParseReferences is a convenient wrapper that operates on a slice of strings and // calls ParseReference for each of them. It returns at the first invalid argument. -func ParseReferences(args []string) ([]*Reference, error) { +func ParseReferences(srv rpc.ArduinoCoreServiceServer, ctx context.Context, args []string) ([]*Reference, error) { ret := []*Reference{} for _, arg := range args { - reference, err := ParseReference(arg) + // TODO: This is quite resource consuming (since it creates a new instance for each call) + reference, err := ParseReference(srv, ctx, arg) if err != nil { return nil, err } @@ -60,7 +62,7 @@ func ParseReferences(args []string) ([]*Reference, error) { // To achieve that, it tries to use github.com/arduino/arduino-cli/commands/core.GetPlatform // Note that the Reference is returned rightaway if the arg inserted by the user matches perfectly one in the response of core.GetPlatform // A MultiplePlatformsError is returned if the platform searched by the user matches multiple platforms -func ParseReference(arg string) (*Reference, error) { +func ParseReference(srv rpc.ArduinoCoreServiceServer, ctx context.Context, arg string) (*Reference, error) { logrus.Infof("Parsing reference %s", arg) ret := &Reference{} if arg == "" { @@ -96,7 +98,7 @@ func ParseReference(arg string) (*Reference, error) { // try to use core.PlatformList to optimize what the user typed // (by replacing the PackageName and Architecture in ret with the content of core.GetPlatform()) platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ - Instance: instance.CreateAndInit(), + Instance: instance.CreateAndInit(srv, ctx), }) foundPlatforms := []string{} for _, platform := range platforms.GetSearchOutput() { diff --git a/internal/cli/arguments/reference_test.go b/internal/cli/arguments/reference_test.go index 047d3fc9e5c..032899e9f73 100644 --- a/internal/cli/arguments/reference_test.go +++ b/internal/cli/arguments/reference_test.go @@ -16,8 +16,10 @@ package arguments_test import ( + "context" "testing" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/stretchr/testify/assert" @@ -57,14 +59,16 @@ func TestArgsStringify(t *testing.T) { } func TestParseReferenceCores(t *testing.T) { + srv := commands.NewArduinoCoreServer("") + ctx := context.Background() for _, tt := range goodCores { - actual, err := arguments.ParseReference(tt.in) + actual, err := arguments.ParseReference(srv, ctx, tt.in) assert.Nil(t, err) assert.Equal(t, tt.expected, actual) } for _, tt := range badCores { - actual, err := arguments.ParseReference(tt.in) + actual, err := arguments.ParseReference(srv, ctx, tt.in) require.NotNil(t, err, "Testing bad core '%s'", tt.in) require.Equal(t, tt.expected, actual, "Testing bad core '%s'", tt.in) } @@ -76,7 +80,8 @@ func TestParseArgs(t *testing.T) { input = append(input, tt.in) } - refs, err := arguments.ParseReferences(input) + srv := commands.NewArduinoCoreServer("") + refs, err := arguments.ParseReferences(srv, context.Background(), input) assert.Nil(t, err) assert.Equal(t, len(goodCores), len(refs)) diff --git a/internal/cli/board/details.go b/internal/cli/board/details.go index 296078a9393..c3a7c117945 100644 --- a/internal/cli/board/details.go +++ b/internal/cli/board/details.go @@ -56,7 +56,8 @@ func initDetailsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } func runDetailsCommand(srv rpc.ArduinoCoreServiceServer, fqbn string, showFullDetails, listProgrammers bool, showProperties arguments.ShowProperties) { - inst := instance.CreateAndInit() + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli board details`") diff --git a/internal/cli/board/list.go b/internal/cli/board/list.go index b27869a459c..457797403d7 100644 --- a/internal/cli/board/list.go +++ b/internal/cli/board/list.go @@ -58,7 +58,8 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { // runListCommand detects and lists the connected arduino boards func runListCommand(srv rpc.ArduinoCoreServiceServer, watch bool, timeout int64, fqbn string) { - inst := instance.CreateAndInit() + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli board list`") diff --git a/internal/cli/board/listall.go b/internal/cli/board/listall.go index fdf39fe0a98..a0cc18e5a3d 100644 --- a/internal/cli/board/listall.go +++ b/internal/cli/board/listall.go @@ -52,7 +52,8 @@ for a specific board if you specify the board name`), // runListAllCommand list all installed boards func runListAllCommand(args []string, srv rpc.ArduinoCoreServiceServer) { - inst := instance.CreateAndInit() + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli board listall`") diff --git a/internal/cli/board/search.go b/internal/cli/board/search.go index ee3cb40e1bb..c49e640ff18 100644 --- a/internal/cli/board/search.go +++ b/internal/cli/board/search.go @@ -49,7 +49,8 @@ func initSearchCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string) { - inst := instance.CreateAndInit() + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli board search`") diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index 23dc605a710..c191d9da4d0 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -66,7 +66,8 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } func runBootloaderCommand(srv rpc.ArduinoCoreServiceServer) { - instance := instance.CreateAndInit() + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli burn-bootloader`") diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 2e633d236fd..e0e7cd27ecd 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -119,15 +119,15 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cmd.AddCommand(compile.NewCommand(srv)) cmd.AddCommand(completion.NewCommand()) cmd.AddCommand(config.NewCommand()) - cmd.AddCommand(core.NewCommand()) + cmd.AddCommand(core.NewCommand(srv)) cmd.AddCommand(daemon.NewCommand()) cmd.AddCommand(generatedocs.NewCommand()) cmd.AddCommand(lib.NewCommand(srv)) cmd.AddCommand(monitor.NewCommand(srv)) - cmd.AddCommand(outdated.NewCommand()) + cmd.AddCommand(outdated.NewCommand(srv)) cmd.AddCommand(sketch.NewCommand()) - cmd.AddCommand(update.NewCommand()) - cmd.AddCommand(upgrade.NewCommand()) + cmd.AddCommand(update.NewCommand(srv)) + cmd.AddCommand(upgrade.NewCommand(srv)) cmd.AddCommand(upload.NewCommand(srv)) cmd.AddCommand(debug.NewCommand(srv)) cmd.AddCommand(burnbootloader.NewCommand(srv)) diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 52fb6d1b60b..b5b7039e249 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -142,6 +142,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli compile`") + ctx := context.Background() if profileArg.Get() != "" { if len(libraries) > 0 { @@ -168,9 +169,9 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer var profile *rpc.SketchProfile if profileArg.Get() == "" { - inst, profile = instance.CreateAndInitWithProfile(sk.GetDefaultProfile().GetName(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(srv, ctx, sk.GetDefaultProfile().GetName(), sketchPath) } else { - inst, profile = instance.CreateAndInitWithProfile(profileArg.Get(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(srv, ctx, profileArg.Get(), sketchPath) } if fqbnArg.String() == "" { diff --git a/internal/cli/core/core.go b/internal/cli/core/core.go index 3792ad13227..ac337df6c9e 100644 --- a/internal/cli/core/core.go +++ b/internal/cli/core/core.go @@ -19,13 +19,14 @@ import ( "os" "github.com/arduino/arduino-cli/internal/i18n" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) var tr = i18n.Tr // NewCommand created a new `core` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { coreCommand := &cobra.Command{ Use: "core", Short: tr("Arduino core operations."), @@ -33,13 +34,13 @@ func NewCommand() *cobra.Command { Example: " " + os.Args[0] + " core update-index", } - coreCommand.AddCommand(initDownloadCommand()) - coreCommand.AddCommand(initInstallCommand()) - coreCommand.AddCommand(initListCommand()) - coreCommand.AddCommand(initUpdateIndexCommand()) - coreCommand.AddCommand(initUpgradeCommand()) - coreCommand.AddCommand(initUninstallCommand()) - coreCommand.AddCommand(initSearchCommand()) + coreCommand.AddCommand(initDownloadCommand(srv)) + coreCommand.AddCommand(initInstallCommand(srv)) + coreCommand.AddCommand(initListCommand(srv)) + coreCommand.AddCommand(initUpdateIndexCommand(srv)) + coreCommand.AddCommand(initUpgradeCommand(srv)) + coreCommand.AddCommand(initUninstallCommand(srv)) + coreCommand.AddCommand(initSearchCommand(srv)) return coreCommand } diff --git a/internal/cli/core/download.go b/internal/cli/core/download.go index 6fafe678b5e..909ffe30448 100644 --- a/internal/cli/core/download.go +++ b/internal/cli/core/download.go @@ -29,7 +29,7 @@ import ( "github.com/spf13/cobra" ) -func initDownloadCommand() *cobra.Command { +func initDownloadCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { downloadCommand := &cobra.Command{ Use: fmt.Sprintf("download [%s:%s[@%s]]...", tr("PACKAGER"), tr("ARCH"), tr("VERSION")), Short: tr("Downloads one or more cores and corresponding tool dependencies."), @@ -38,20 +38,23 @@ func initDownloadCommand() *cobra.Command { " " + os.Args[0] + " core download arduino:samd # " + tr("download the latest version of Arduino SAMD core.") + "\n" + " " + os.Args[0] + " core download arduino:samd@1.6.9 # " + tr("download a specific version (in this case 1.6.9)."), Args: cobra.MinimumNArgs(1), - Run: runDownloadCommand, + Run: func(cmd *cobra.Command, args []string) { + runDownloadCommand(srv, args) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableCores(), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableCores(srv, context.Background()), cobra.ShellCompDirectiveDefault }, } return downloadCommand } -func runDownloadCommand(cmd *cobra.Command, args []string) { - inst := instance.CreateAndInit() +func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli core download`") - platformsRefs, err := arguments.ParseReferences(args) + platformsRefs, err := arguments.ParseReferences(srv, ctx, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } diff --git a/internal/cli/core/install.go b/internal/cli/core/install.go index 98dc7c4135d..d59361f4ee2 100644 --- a/internal/cli/core/install.go +++ b/internal/cli/core/install.go @@ -29,7 +29,7 @@ import ( "github.com/spf13/cobra" ) -func initInstallCommand() *cobra.Command { +func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var noOverwrite bool var scriptFlags arguments.PrePostScriptsFlags installCommand := &cobra.Command{ @@ -45,10 +45,10 @@ func initInstallCommand() *cobra.Command { arguments.CheckFlagsConflicts(cmd, "run-post-install", "skip-post-install") }, Run: func(cmd *cobra.Command, args []string) { - runInstallCommand(args, scriptFlags, noOverwrite) + runInstallCommand(srv, args, scriptFlags, noOverwrite) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableCores(), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableCores(srv, context.Background()), cobra.ShellCompDirectiveDefault }, } scriptFlags.AddToCommand(installCommand) @@ -56,11 +56,12 @@ func initInstallCommand() *cobra.Command { return installCommand } -func runInstallCommand(args []string, scriptFlags arguments.PrePostScriptsFlags, noOverwrite bool) { - inst := instance.CreateAndInit() +func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, scriptFlags arguments.PrePostScriptsFlags, noOverwrite bool) { logrus.Info("Executing `arduino-cli core install`") + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) - platformsRefs, err := arguments.ParseReferences(args) + platformsRefs, err := arguments.ParseReferences(srv, ctx, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } diff --git a/internal/cli/core/list.go b/internal/cli/core/list.go index db5fbbaf927..c0ec34a8f67 100644 --- a/internal/cli/core/list.go +++ b/internal/cli/core/list.go @@ -16,6 +16,7 @@ package core import ( + "context" "os" "github.com/arduino/arduino-cli/commands" @@ -28,7 +29,7 @@ import ( "github.com/spf13/cobra" ) -func initListCommand() *cobra.Command { +func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var updatableOnly bool var all bool listCommand := &cobra.Command{ @@ -38,7 +39,7 @@ func initListCommand() *cobra.Command { Example: " " + os.Args[0] + " core list", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runListCommand(args, all, updatableOnly) + runListCommand(srv, all, updatableOnly) }, } listCommand.Flags().BoolVar(&updatableOnly, "updatable", false, tr("List updatable platforms.")) @@ -46,8 +47,9 @@ func initListCommand() *cobra.Command { return listCommand } -func runListCommand(args []string, all bool, updatableOnly bool) { - inst := instance.CreateAndInit() +func runListCommand(srv rpc.ArduinoCoreServiceServer, all bool, updatableOnly bool) { + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli core list`") List(inst, all, updatableOnly) } diff --git a/internal/cli/core/search.go b/internal/cli/core/search.go index 6a6b559a5cf..610a9fb97ca 100644 --- a/internal/cli/core/search.go +++ b/internal/cli/core/search.go @@ -32,7 +32,7 @@ import ( "github.com/spf13/cobra" ) -func initSearchCommand() *cobra.Command { +func initSearchCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var allVersions bool searchCommand := &cobra.Command{ Use: fmt.Sprintf("search <%s...>", tr("keywords")), @@ -41,7 +41,7 @@ func initSearchCommand() *cobra.Command { Example: " " + os.Args[0] + " core search MKRZero -a -v", Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { - runSearchCommand(cmd, args, allVersions) + runSearchCommand(srv, args, allVersions) }, } searchCommand.Flags().BoolVarP(&allVersions, "all", "a", false, tr("Show all available core versions.")) @@ -52,8 +52,9 @@ func initSearchCommand() *cobra.Command { // indexUpdateInterval specifies the time threshold over which indexes are updated const indexUpdateInterval = 24 * time.Hour -func runSearchCommand(cmd *cobra.Command, args []string, allVersions bool) { - inst := instance.CreateAndInit() +func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, allVersions bool) { + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) res, err := commands.UpdateIndex( context.Background(), diff --git a/internal/cli/core/uninstall.go b/internal/cli/core/uninstall.go index c8e3c212ac1..70df514cccb 100644 --- a/internal/cli/core/uninstall.go +++ b/internal/cli/core/uninstall.go @@ -29,7 +29,7 @@ import ( "github.com/spf13/cobra" ) -func initUninstallCommand() *cobra.Command { +func initUninstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var preUninstallFlags arguments.PrePostScriptsFlags uninstallCommand := &cobra.Command{ Use: fmt.Sprintf("uninstall %s:%s ...", tr("PACKAGER"), tr("ARCH")), @@ -38,21 +38,22 @@ func initUninstallCommand() *cobra.Command { Example: " " + os.Args[0] + " core uninstall arduino:samd\n", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runUninstallCommand(args, preUninstallFlags) + runUninstallCommand(srv, args, preUninstallFlags) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetUninstallableCores(), cobra.ShellCompDirectiveDefault + return arguments.GetUninstallableCores(srv, context.Background()), cobra.ShellCompDirectiveDefault }, } preUninstallFlags.AddToCommand(uninstallCommand) return uninstallCommand } -func runUninstallCommand(args []string, preUninstallFlags arguments.PrePostScriptsFlags) { - inst := instance.CreateAndInit() +func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, preUninstallFlags arguments.PrePostScriptsFlags) { logrus.Info("Executing `arduino-cli core uninstall`") + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) - platformsRefs, err := arguments.ParseReferences(args) + platformsRefs, err := arguments.ParseReferences(srv, ctx, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } diff --git a/internal/cli/core/update_index.go b/internal/cli/core/update_index.go index 37bd8898a1d..17bc7b194a3 100644 --- a/internal/cli/core/update_index.go +++ b/internal/cli/core/update_index.go @@ -28,21 +28,24 @@ import ( "github.com/spf13/cobra" ) -func initUpdateIndexCommand() *cobra.Command { +func initUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { updateIndexCommand := &cobra.Command{ Use: "update-index", Short: tr("Updates the index of cores."), Long: tr("Updates the index of cores to the latest version."), Example: " " + os.Args[0] + " core update-index", Args: cobra.NoArgs, - Run: runUpdateIndexCommand, + Run: func(cmd *cobra.Command, args []string) { + runUpdateIndexCommand(srv) + }, } return updateIndexCommand } -func runUpdateIndexCommand(cmd *cobra.Command, args []string) { - inst := instance.CreateAndInit() +func runUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli core update-index`") + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) resp := UpdateIndex(inst) feedback.PrintResult(&updateIndexResult{result.NewUpdateIndexResponse_ResultResult(resp)}) diff --git a/internal/cli/core/upgrade.go b/internal/cli/core/upgrade.go index 9bd400fc9fb..faf81ab245d 100644 --- a/internal/cli/core/upgrade.go +++ b/internal/cli/core/upgrade.go @@ -31,7 +31,7 @@ import ( "github.com/spf13/cobra" ) -func initUpgradeCommand() *cobra.Command { +func initUpgradeCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var postInstallFlags arguments.PrePostScriptsFlags upgradeCommand := &cobra.Command{ Use: fmt.Sprintf("upgrade [%s:%s] ...", tr("PACKAGER"), tr("ARCH")), @@ -43,21 +43,22 @@ func initUpgradeCommand() *cobra.Command { " # " + tr("upgrade arduino:samd to the latest version") + "\n" + " " + os.Args[0] + " core upgrade arduino:samd", Run: func(cmd *cobra.Command, args []string) { - runUpgradeCommand(args, postInstallFlags.DetectSkipPostInstallValue(), postInstallFlags.DetectSkipPreUninstallValue()) + runUpgradeCommand(srv, args, postInstallFlags.DetectSkipPostInstallValue(), postInstallFlags.DetectSkipPreUninstallValue()) }, } postInstallFlags.AddToCommand(upgradeCommand) return upgradeCommand } -func runUpgradeCommand(args []string, skipPostInstall bool, skipPreUninstall bool) { - inst := instance.CreateAndInit() +func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, args []string, skipPostInstall bool, skipPreUninstall bool) { logrus.Info("Executing `arduino-cli core upgrade`") - Upgrade(inst, args, skipPostInstall, skipPreUninstall) + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) + Upgrade(srv, ctx, inst, args, skipPostInstall, skipPreUninstall) } // Upgrade upgrades one or all installed platforms to the latest version. -func Upgrade(inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUninstall bool) { +func Upgrade(srv rpc.ArduinoCoreServiceServer, ctx context.Context, inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUninstall bool) { // if no platform was passed, upgrade allthethings if len(args) == 0 { platforms, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ @@ -102,7 +103,7 @@ func Upgrade(inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUni } // proceed upgrading, if anything is upgradable - platformsRefs, err := arguments.ParseReferences(args) + platformsRefs, err := arguments.ParseReferences(srv, ctx, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index 576f8cc6a20..56b380842d2 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -75,6 +75,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, importDir string, programmer *arguments.Programmer, printInfo bool, profileArg *arguments.Profile) { logrus.Info("Executing `arduino-cli debug`") + ctx := context.Background() path := "" if len(args) > 0 { @@ -92,9 +93,9 @@ func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs * var profile *rpc.SketchProfile if profileArg.Get() == "" { - inst, profile = instance.CreateAndInitWithProfile(sk.GetDefaultProfile().GetName(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(srv, ctx, sk.GetDefaultProfile().GetName(), sketchPath) } else { - inst, profile = instance.CreateAndInitWithProfile(profileArg.Get(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(srv, ctx, profileArg.Get(), sketchPath) } if fqbnArg.String() == "" { diff --git a/internal/cli/debug/debug_check.go b/internal/cli/debug/debug_check.go index 7be9393b5c0..569c64a880c 100644 --- a/internal/cli/debug/debug_check.go +++ b/internal/cli/debug/debug_check.go @@ -52,7 +52,8 @@ func newDebugCheckCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } func runDebugCheckCommand(srv rpc.ArduinoCoreServiceServer, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, programmerArg *arguments.Programmer) { - instance := instance.CreateAndInit() + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli debug`") port, err := portArgs.GetPort(instance, srv, "", "") diff --git a/internal/cli/instance/instance.go b/internal/cli/instance/instance.go index ec1513105aa..6572fe65802 100644 --- a/internal/cli/instance/instance.go +++ b/internal/cli/instance/instance.go @@ -16,6 +16,8 @@ package instance import ( + "context" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/i18n" @@ -29,16 +31,16 @@ var tr = i18n.Tr // If Create fails the CLI prints an error and exits since // to execute further operations a valid Instance is mandatory. // If Init returns errors they're printed only. -func CreateAndInit() *rpc.Instance { - inst, _ := CreateAndInitWithProfile("", nil) +func CreateAndInit(srv rpc.ArduinoCoreServiceServer, ctx context.Context) *rpc.Instance { + inst, _ := CreateAndInitWithProfile(srv, ctx, "", nil) return inst } // CreateAndInitWithProfile returns a new initialized instance using the given profile of the given sketch. // If Create fails the CLI prints an error and exits since to execute further operations a valid Instance is mandatory. // If Init returns errors they're printed only. -func CreateAndInitWithProfile(profileName string, sketchPath *paths.Path) (*rpc.Instance, *rpc.SketchProfile) { - instance, err := create() +func CreateAndInitWithProfile(srv rpc.ArduinoCoreServiceServer, ctx context.Context, profileName string, sketchPath *paths.Path) (*rpc.Instance, *rpc.SketchProfile) { + instance, err := create(srv, ctx) if err != nil { feedback.Fatal(tr("Error creating instance: %v", err), feedback.ErrGeneric) } @@ -47,8 +49,8 @@ func CreateAndInitWithProfile(profileName string, sketchPath *paths.Path) (*rpc. } // create and return a new Instance. -func create() (*rpc.Instance, error) { - res, err := commands.Create(&rpc.CreateRequest{}) +func create(srv rpc.ArduinoCoreServiceServer, ctx context.Context) (*rpc.Instance, error) { + res, err := srv.Create(ctx, &rpc.CreateRequest{}) if err != nil { return nil, err } diff --git a/internal/cli/lib/check_deps.go b/internal/cli/lib/check_deps.go index 248ac85843b..9c43830c671 100644 --- a/internal/cli/lib/check_deps.go +++ b/internal/cli/lib/check_deps.go @@ -32,7 +32,7 @@ import ( "github.com/spf13/cobra" ) -func initDepsCommand() *cobra.Command { +func initDepsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var noOverwrite bool depsCommand := &cobra.Command{ Use: fmt.Sprintf("deps %s[@%s]...", tr("LIBRARY"), tr("VERSION_NUMBER")), @@ -43,18 +43,20 @@ func initDepsCommand() *cobra.Command { " " + os.Args[0] + " lib deps AudioZero@1.0.0 # " + tr("for the specific version."), Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - runDepsCommand(args, noOverwrite) + runDepsCommand(srv, args, noOverwrite) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstalledLibraries(), cobra.ShellCompDirectiveDefault + return arguments.GetInstalledLibraries(srv, context.Background()), cobra.ShellCompDirectiveDefault }, } depsCommand.Flags().BoolVar(&noOverwrite, "no-overwrite", false, tr("Do not try to update library dependencies if already installed.")) return depsCommand } -func runDepsCommand(args []string, noOverwrite bool) { - instance := instance.CreateAndInit() +func runDepsCommand(srv rpc.ArduinoCoreServiceServer, args []string, noOverwrite bool) { + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) + logrus.Info("Executing `arduino-cli lib deps`") libRef, err := ParseLibraryReferenceArgAndAdjustCase(instance, args[0]) if err != nil { diff --git a/internal/cli/lib/download.go b/internal/cli/lib/download.go index 733e3567fe7..7c714bb1768 100644 --- a/internal/cli/lib/download.go +++ b/internal/cli/lib/download.go @@ -29,7 +29,7 @@ import ( "github.com/spf13/cobra" ) -func initDownloadCommand() *cobra.Command { +func initDownloadCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { downloadCommand := &cobra.Command{ Use: fmt.Sprintf("download [%s]...", tr("LIBRARY_NAME")), Short: tr("Downloads one or more libraries without installing them."), @@ -38,17 +38,21 @@ func initDownloadCommand() *cobra.Command { " " + os.Args[0] + " lib download AudioZero # " + tr("for the latest version.") + "\n" + " " + os.Args[0] + " lib download AudioZero@1.0.0 # " + tr("for a specific version."), Args: cobra.MinimumNArgs(1), - Run: runDownloadCommand, + Run: func(cmd *cobra.Command, args []string) { + runDownloadCommand(srv, args) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableLibs(), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableLibs(srv, context.Background()), cobra.ShellCompDirectiveDefault }, } return downloadCommand } -func runDownloadCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateAndInit() +func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib download`") + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) + refs, err := ParseLibraryReferenceArgsAndAdjustCase(instance, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) diff --git a/internal/cli/lib/examples.go b/internal/cli/lib/examples.go index 4a411d26ff6..e8e756ceb0d 100644 --- a/internal/cli/lib/examples.go +++ b/internal/cli/lib/examples.go @@ -45,18 +45,21 @@ func initExamplesCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Long: tr("Shows the list of the examples for libraries. A name may be given as argument to search a specific library."), Example: " " + os.Args[0] + " lib examples Wire", Args: cobra.MaximumNArgs(1), - Run: runExamplesCommand, + Run: func(cmd *cobra.Command, args []string) { + runExamplesCommand(srv, args) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstalledLibraries(), cobra.ShellCompDirectiveDefault + return arguments.GetInstalledLibraries(srv, context.Background()), cobra.ShellCompDirectiveDefault }, } fqbn.AddToCommand(examplesCommand, srv) return examplesCommand } -func runExamplesCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateAndInit() +func runExamplesCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib examples`") + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) name := "" if len(args) > 0 { diff --git a/internal/cli/lib/install.go b/internal/cli/lib/install.go index 7bd5c53764b..22b6f5f8187 100644 --- a/internal/cli/lib/install.go +++ b/internal/cli/lib/install.go @@ -34,7 +34,7 @@ import ( semver "go.bug.st/relaxed-semver" ) -func initInstallCommand() *cobra.Command { +func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var noDeps bool var noOverwrite bool var gitURL bool @@ -52,10 +52,10 @@ func initInstallCommand() *cobra.Command { " " + os.Args[0] + " lib install --zip-path /path/to/WiFi101.zip /path/to/ArduinoBLE.zip\n", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runInstallCommand(args, noDeps, noOverwrite, gitURL, zipPath, useBuiltinLibrariesDir) + runInstallCommand(srv, args, noDeps, noOverwrite, gitURL, zipPath, useBuiltinLibrariesDir) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableLibs(), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableLibs(srv, context.Background()), cobra.ShellCompDirectiveDefault }, } installCommand.Flags().BoolVar(&noDeps, "no-deps", false, tr("Do not install dependencies.")) @@ -66,8 +66,9 @@ func initInstallCommand() *cobra.Command { return installCommand } -func runInstallCommand(args []string, noDeps bool, noOverwrite bool, gitURL bool, zipPath bool, useBuiltinLibrariesDir bool) { - instance := instance.CreateAndInit() +func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps bool, noOverwrite bool, gitURL bool, zipPath bool, useBuiltinLibrariesDir bool) { + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli lib install`") if zipPath || gitURL { diff --git a/internal/cli/lib/lib.go b/internal/cli/lib/lib.go index 59cd2020650..deab795b9f5 100644 --- a/internal/cli/lib/lib.go +++ b/internal/cli/lib/lib.go @@ -36,14 +36,14 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " lib update-index", } - libCommand.AddCommand(initDownloadCommand()) - libCommand.AddCommand(initInstallCommand()) + libCommand.AddCommand(initDownloadCommand(srv)) + libCommand.AddCommand(initInstallCommand(srv)) libCommand.AddCommand(initListCommand(srv)) libCommand.AddCommand(initExamplesCommand(srv)) - libCommand.AddCommand(initSearchCommand()) - libCommand.AddCommand(initUninstallCommand()) - libCommand.AddCommand(initUpgradeCommand()) - libCommand.AddCommand(initUpdateIndexCommand()) - libCommand.AddCommand(initDepsCommand()) + libCommand.AddCommand(initSearchCommand(srv)) + libCommand.AddCommand(initUninstallCommand(srv)) + libCommand.AddCommand(initUpgradeCommand(srv)) + libCommand.AddCommand(initUpdateIndexCommand(srv)) + libCommand.AddCommand(initDepsCommand(srv)) return libCommand } diff --git a/internal/cli/lib/list.go b/internal/cli/lib/list.go index a034267db46..df22b4ef856 100644 --- a/internal/cli/lib/list.go +++ b/internal/cli/lib/list.go @@ -46,7 +46,8 @@ not listed, they can be listed by adding the --all flag.`), Example: " " + os.Args[0] + " lib list", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - instance := instance.CreateAndInit() + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli lib list`") List(instance, args, all, updatable) }, diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index 2e1e27d4e9b..6fbd0728a78 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -31,7 +31,7 @@ import ( "github.com/spf13/cobra" ) -func initSearchCommand() *cobra.Command { +func initSearchCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var namesOnly bool var omitReleasesDetails bool searchCommand := &cobra.Command{ @@ -90,7 +90,7 @@ In addition to the fields listed above, QV terms can use these qualifiers: " " + os.Args[0] + " lib search dependencies=IRremote # " + tr("libraries that depend only on \"IRremote\"") + "\n", Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { - runSearchCommand(args, namesOnly, omitReleasesDetails) + runSearchCommand(srv, args, namesOnly, omitReleasesDetails) }, } searchCommand.Flags().BoolVar(&namesOnly, "names", false, tr("Show library names only.")) @@ -101,8 +101,9 @@ In addition to the fields listed above, QV terms can use these qualifiers: // indexUpdateInterval specifies the time threshold over which indexes are updated const indexUpdateInterval = 60 * time.Minute -func runSearchCommand(args []string, namesOnly bool, omitReleasesDetails bool) { - inst := instance.CreateAndInit() +func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, namesOnly bool, omitReleasesDetails bool) { + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli lib search`") diff --git a/internal/cli/lib/uninstall.go b/internal/cli/lib/uninstall.go index 2a03a463aa1..dc80f0de7e3 100644 --- a/internal/cli/lib/uninstall.go +++ b/internal/cli/lib/uninstall.go @@ -29,24 +29,27 @@ import ( "github.com/spf13/cobra" ) -func initUninstallCommand() *cobra.Command { +func initUninstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { uninstallCommand := &cobra.Command{ Use: fmt.Sprintf("uninstall %s...", tr("LIBRARY_NAME")), Short: tr("Uninstalls one or more libraries."), Long: tr("Uninstalls one or more libraries."), Example: " " + os.Args[0] + " lib uninstall AudioZero", Args: cobra.MinimumNArgs(1), - Run: runUninstallCommand, + Run: func(cmd *cobra.Command, args []string) { + runUninstallCommand(srv, args) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetUninstallableLibraries(), cobra.ShellCompDirectiveDefault + return arguments.GetUninstallableLibraries(srv, context.Background()), cobra.ShellCompDirectiveDefault }, } return uninstallCommand } -func runUninstallCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateAndInit() +func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib uninstall`") + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) refs, err := ParseLibraryReferenceArgsAndAdjustCase(instance, args) if err != nil { diff --git a/internal/cli/lib/update_index.go b/internal/cli/lib/update_index.go index 462ba003240..9621978727c 100644 --- a/internal/cli/lib/update_index.go +++ b/internal/cli/lib/update_index.go @@ -28,20 +28,24 @@ import ( "github.com/spf13/cobra" ) -func initUpdateIndexCommand() *cobra.Command { +func initUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { updateIndexCommand := &cobra.Command{ Use: "update-index", Short: tr("Updates the libraries index."), Long: tr("Updates the libraries index to the latest version."), Example: " " + os.Args[0] + " lib update-index", Args: cobra.NoArgs, - Run: runUpdateIndexCommand, + Run: func(cmd *cobra.Command, args []string) { + runUpdateIndexCommand(srv) + }, } return updateIndexCommand } -func runUpdateIndexCommand(cmd *cobra.Command, args []string) { - inst := instance.CreateAndInit() +func runUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) { + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) + logrus.Info("Executing `arduino-cli lib update-index`") resp := UpdateIndex(inst) feedback.PrintResult(&libUpdateIndexResult{result.NewUpdateLibrariesIndexResponse_ResultResult(resp)}) diff --git a/internal/cli/lib/upgrade.go b/internal/cli/lib/upgrade.go index e83b54f20ac..9d018a6ef4a 100644 --- a/internal/cli/lib/upgrade.go +++ b/internal/cli/lib/upgrade.go @@ -28,7 +28,7 @@ import ( "github.com/spf13/cobra" ) -func initUpgradeCommand() *cobra.Command { +func initUpgradeCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { upgradeCommand := &cobra.Command{ Use: "upgrade", Short: tr("Upgrades installed libraries."), @@ -37,14 +37,17 @@ func initUpgradeCommand() *cobra.Command { " " + os.Args[0] + " lib upgrade Audio\n" + " " + os.Args[0] + " lib upgrade Audio ArduinoJson", Args: cobra.ArbitraryArgs, - Run: runUpgradeCommand, + Run: func(cmd *cobra.Command, args []string) { + runUpgradeCommand(srv, args) + }, } return upgradeCommand } -func runUpgradeCommand(cmd *cobra.Command, args []string) { - instance := instance.CreateAndInit() +func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib upgrade`") + ctx := context.Background() + instance := instance.CreateAndInit(srv, ctx) Upgrade(instance, args) } diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 597933939a3..e11c10eef05 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -86,6 +86,7 @@ func runMonitorCmd( configs []string, describe, timestamp, quiet, raw bool, ) { logrus.Info("Executing `arduino-cli monitor`") + ctx := context.Background() if !feedback.HasConsole() { quiet = true @@ -116,13 +117,13 @@ func runMonitorCmd( } if fqbnArg.String() == "" { if profileArg.Get() == "" { - inst, profile = instance.CreateAndInitWithProfile(sketch.GetDefaultProfile().GetName(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(srv, ctx, sketch.GetDefaultProfile().GetName(), sketchPath) } else { - inst, profile = instance.CreateAndInitWithProfile(profileArg.Get(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(srv, ctx, profileArg.Get(), sketchPath) } } if inst == nil { - inst = instance.CreateAndInit() + inst = instance.CreateAndInit(srv, ctx) } // Priority on how to retrieve the fqbn // 1. from flag diff --git a/internal/cli/outdated/outdated.go b/internal/cli/outdated/outdated.go index 4859f6159fc..7570da56c1b 100644 --- a/internal/cli/outdated/outdated.go +++ b/internal/cli/outdated/outdated.go @@ -16,6 +16,7 @@ package outdated import ( + "context" "fmt" "os" "sort" @@ -36,7 +37,7 @@ import ( var tr = i18n.Tr // NewCommand creates a new `outdated` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { outdatedCommand := &cobra.Command{ Use: "outdated", Short: tr("Lists cores and libraries that can be upgraded"), @@ -44,14 +45,17 @@ func NewCommand() *cobra.Command { that can be upgraded. If nothing needs to be updated the output is empty.`), Example: " " + os.Args[0] + " outdated\n", Args: cobra.NoArgs, - Run: runOutdatedCommand, + Run: func(cmd *cobra.Command, args []string) { + runOutdatedCommand(srv) + }, } return outdatedCommand } -func runOutdatedCommand(cmd *cobra.Command, args []string) { - inst := instance.CreateAndInit() +func runOutdatedCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli outdated`") + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) Outdated(inst) } diff --git a/internal/cli/update/update.go b/internal/cli/update/update.go index d516a5cc701..3c2d77cff85 100644 --- a/internal/cli/update/update.go +++ b/internal/cli/update/update.go @@ -16,6 +16,7 @@ package update import ( + "context" "os" "github.com/arduino/arduino-cli/internal/cli/core" @@ -23,6 +24,7 @@ import ( "github.com/arduino/arduino-cli/internal/cli/lib" "github.com/arduino/arduino-cli/internal/cli/outdated" "github.com/arduino/arduino-cli/internal/i18n" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -30,7 +32,7 @@ import ( var tr = i18n.Tr // NewCommand creates a new `update` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var showOutdated bool updateCommand := &cobra.Command{ Use: "update", @@ -39,16 +41,18 @@ func NewCommand() *cobra.Command { Example: " " + os.Args[0] + " update", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runUpdateCommand(showOutdated) + runUpdateCommand(srv, showOutdated) }, } updateCommand.Flags().BoolVar(&showOutdated, "show-outdated", false, tr("Show outdated cores and libraries after index update")) return updateCommand } -func runUpdateCommand(showOutdated bool) { - inst := instance.CreateAndInit() +func runUpdateCommand(srv rpc.ArduinoCoreServiceServer, showOutdated bool) { logrus.Info("Executing `arduino-cli update`") + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) + lib.UpdateIndex(inst) core.UpdateIndex(inst) instance.Init(inst) diff --git a/internal/cli/upgrade/upgrade.go b/internal/cli/upgrade/upgrade.go index cf1f71448e7..98339aad7f8 100644 --- a/internal/cli/upgrade/upgrade.go +++ b/internal/cli/upgrade/upgrade.go @@ -16,6 +16,7 @@ package upgrade import ( + "context" "os" "github.com/arduino/arduino-cli/internal/cli/arguments" @@ -23,6 +24,7 @@ import ( "github.com/arduino/arduino-cli/internal/cli/instance" "github.com/arduino/arduino-cli/internal/cli/lib" "github.com/arduino/arduino-cli/internal/i18n" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -30,7 +32,7 @@ import ( var tr = i18n.Tr // NewCommand creates a new `upgrade` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var postInstallFlags arguments.PrePostScriptsFlags upgradeCommand := &cobra.Command{ Use: "upgrade", @@ -39,16 +41,17 @@ func NewCommand() *cobra.Command { Example: " " + os.Args[0] + " upgrade", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runUpgradeCommand(postInstallFlags.DetectSkipPostInstallValue(), postInstallFlags.DetectSkipPreUninstallValue()) + runUpgradeCommand(srv, postInstallFlags.DetectSkipPostInstallValue(), postInstallFlags.DetectSkipPreUninstallValue()) }, } postInstallFlags.AddToCommand(upgradeCommand) return upgradeCommand } -func runUpgradeCommand(skipPostInstall bool, skipPreUninstall bool) { - inst := instance.CreateAndInit() +func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, skipPostInstall bool, skipPreUninstall bool) { + ctx := context.Background() + inst := instance.CreateAndInit(srv, ctx) logrus.Info("Executing `arduino-cli upgrade`") lib.Upgrade(inst, []string{}) - core.Upgrade(inst, []string{}, skipPostInstall, skipPreUninstall) + core.Upgrade(srv, ctx, inst, []string{}, skipPostInstall, skipPreUninstall) } diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 125b25d317d..0cc1f0f89f1 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -84,6 +84,8 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFieldsArgs map[string]string) { logrus.Info("Executing `arduino-cli upload`") + ctx := context.Background() + path := "" if len(args) > 0 { path = args[0] @@ -101,9 +103,9 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie var profile *rpc.SketchProfile if profileArg.Get() == "" { - inst, profile = instance.CreateAndInitWithProfile(sketch.GetDefaultProfile().GetName(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(srv, ctx, sketch.GetDefaultProfile().GetName(), sketchPath) } else { - inst, profile = instance.CreateAndInitWithProfile(profileArg.Get(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(srv, ctx, profileArg.Get(), sketchPath) } if fqbnArg.String() == "" { From 8bd0eef02ed248d92d9c803984b47d9a646e21f8 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 14 Mar 2024 13:14:38 +0100 Subject: [PATCH 14/56] Follow convetion where context must be the first argument --- internal/cli/arguments/completion.go | 36 +++++++++---------- internal/cli/arguments/fqbn.go | 2 +- internal/cli/arguments/port.go | 4 +-- internal/cli/arguments/programmer.go | 2 +- internal/cli/arguments/reference.go | 8 ++--- internal/cli/arguments/reference_test.go | 6 ++-- internal/cli/board/details.go | 2 +- internal/cli/board/list.go | 2 +- internal/cli/board/listall.go | 2 +- internal/cli/board/search.go | 2 +- internal/cli/burnbootloader/burnbootloader.go | 2 +- internal/cli/compile/compile.go | 4 +-- internal/cli/core/download.go | 6 ++-- internal/cli/core/install.go | 6 ++-- internal/cli/core/list.go | 2 +- internal/cli/core/search.go | 2 +- internal/cli/core/uninstall.go | 6 ++-- internal/cli/core/update_index.go | 2 +- internal/cli/core/upgrade.go | 8 ++--- internal/cli/debug/debug.go | 4 +-- internal/cli/debug/debug_check.go | 2 +- internal/cli/instance/instance.go | 10 +++--- internal/cli/lib/check_deps.go | 4 +-- internal/cli/lib/download.go | 4 +-- internal/cli/lib/examples.go | 4 +-- internal/cli/lib/install.go | 4 +-- internal/cli/lib/list.go | 2 +- internal/cli/lib/search.go | 2 +- internal/cli/lib/uninstall.go | 4 +-- internal/cli/lib/update_index.go | 2 +- internal/cli/lib/upgrade.go | 2 +- internal/cli/monitor/monitor.go | 6 ++-- internal/cli/outdated/outdated.go | 2 +- internal/cli/update/update.go | 2 +- internal/cli/upgrade/upgrade.go | 4 +-- internal/cli/upload/upload.go | 4 +-- 36 files changed, 83 insertions(+), 83 deletions(-) diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index c86a657793a..f5446d3e4ed 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -27,8 +27,8 @@ import ( // GetInstalledBoards is an helper function useful to autocomplete. // It returns a list of fqbn // it's taken from cli/board/listall.go -func GetInstalledBoards(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { - inst := instance.CreateAndInit(srv, ctx) +func GetInstalledBoards(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + inst := instance.CreateAndInit(ctx, srv) list, _ := srv.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ Instance: inst, @@ -45,8 +45,8 @@ func GetInstalledBoards(srv rpc.ArduinoCoreServiceServer, ctx context.Context) [ // GetInstalledProgrammers is an helper function useful to autocomplete. // It returns a list of programmers available based on the installed boards -func GetInstalledProgrammers(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { - inst := instance.CreateAndInit(srv, ctx) +func GetInstalledProgrammers(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + inst := instance.CreateAndInit(ctx, srv) // we need the list of the available fqbn in order to get the list of the programmers listAllReq := &rpc.BoardListAllRequest{ @@ -78,8 +78,8 @@ func GetInstalledProgrammers(srv rpc.ArduinoCoreServiceServer, ctx context.Conte // GetUninstallableCores is an helper function useful to autocomplete. // It returns a list of cores which can be uninstalled -func GetUninstallableCores(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { - inst := instance.CreateAndInit(srv, ctx) +func GetUninstallableCores(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + inst := instance.CreateAndInit(ctx, srv) platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, @@ -99,8 +99,8 @@ func GetUninstallableCores(srv rpc.ArduinoCoreServiceServer, ctx context.Context // GetInstallableCores is an helper function useful to autocomplete. // It returns a list of cores which can be installed/downloaded -func GetInstallableCores(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { - inst := instance.CreateAndInit(srv, ctx) +func GetInstallableCores(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + inst := instance.CreateAndInit(ctx, srv) platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ Instance: inst, @@ -118,18 +118,18 @@ func GetInstallableCores(srv rpc.ArduinoCoreServiceServer, ctx context.Context) // GetInstalledLibraries is an helper function useful to autocomplete. // It returns a list of libs which are currently installed, including the builtin ones -func GetInstalledLibraries(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { - return getLibraries(srv, ctx, true) +func GetInstalledLibraries(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + return getLibraries(ctx, srv, true) } // GetUninstallableLibraries is an helper function useful to autocomplete. // It returns a list of libs which can be uninstalled -func GetUninstallableLibraries(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { - return getLibraries(srv, ctx, false) +func GetUninstallableLibraries(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + return getLibraries(ctx, srv, false) } -func getLibraries(srv rpc.ArduinoCoreServiceServer, ctx context.Context, all bool) []string { - inst := instance.CreateAndInit(srv, ctx) +func getLibraries(ctx context.Context, srv rpc.ArduinoCoreServiceServer, all bool) []string { + inst := instance.CreateAndInit(ctx, srv) libs, _ := commands.LibraryList(context.Background(), &rpc.LibraryListRequest{ Instance: inst, All: all, @@ -147,8 +147,8 @@ func getLibraries(srv rpc.ArduinoCoreServiceServer, ctx context.Context, all boo // GetInstallableLibs is an helper function useful to autocomplete. // It returns a list of libs which can be installed/downloaded -func GetInstallableLibs(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []string { - inst := instance.CreateAndInit(srv, ctx) +func GetInstallableLibs(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + inst := instance.CreateAndInit(ctx, srv) libs, _ := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ Instance: inst, @@ -165,9 +165,9 @@ func GetInstallableLibs(srv rpc.ArduinoCoreServiceServer, ctx context.Context) [ // GetAvailablePorts is an helper function useful to autocomplete. // It returns a list of upload port of the boards which are currently connected. // It will not suggests network ports because the timeout is not set. -func GetAvailablePorts(srv rpc.ArduinoCoreServiceServer, ctx context.Context) []*rpc.Port { +func GetAvailablePorts(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []*rpc.Port { // Get the port list - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) list, _ := srv.BoardList(ctx, &rpc.BoardListRequest{Instance: inst}) // Transform the data structure for the completion (DetectedPort -> Port) diff --git a/internal/cli/arguments/fqbn.go b/internal/cli/arguments/fqbn.go index 26c1248e2b4..6369cca6bab 100644 --- a/internal/cli/arguments/fqbn.go +++ b/internal/cli/arguments/fqbn.go @@ -37,7 +37,7 @@ type Fqbn struct { func (f *Fqbn) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&f.fqbn, "fqbn", "b", "", tr("Fully Qualified Board Name, e.g.: arduino:avr:uno")) cmd.RegisterFlagCompletionFunc("fqbn", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetInstalledBoards(srv, context.Background()), cobra.ShellCompDirectiveDefault + return GetInstalledBoards(context.Background(), srv), cobra.ShellCompDirectiveDefault }) cmd.Flags().StringSliceVar(&f.boardOptions, "board-options", []string{}, tr("List of board options separated by commas. Or can be used multiple times for multiple options.")) diff --git a/internal/cli/arguments/port.go b/internal/cli/arguments/port.go index 51247603438..e3566699b0f 100644 --- a/internal/cli/arguments/port.go +++ b/internal/cli/arguments/port.go @@ -42,11 +42,11 @@ type Port struct { func (p *Port) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&p.address, "port", "p", "", tr("Upload port address, e.g.: COM3 or /dev/ttyACM2")) cmd.RegisterFlagCompletionFunc("port", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return f.Map(GetAvailablePorts(srv, context.Background()), (*rpc.Port).GetAddress), cobra.ShellCompDirectiveDefault + return f.Map(GetAvailablePorts(context.Background(), srv), (*rpc.Port).GetAddress), cobra.ShellCompDirectiveDefault }) cmd.Flags().StringVarP(&p.protocol, "protocol", "l", "", tr("Upload port protocol, e.g: serial")) cmd.RegisterFlagCompletionFunc("protocol", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return f.Map(GetAvailablePorts(srv, context.Background()), (*rpc.Port).GetProtocol), cobra.ShellCompDirectiveDefault + return f.Map(GetAvailablePorts(context.Background(), srv), (*rpc.Port).GetProtocol), cobra.ShellCompDirectiveDefault }) p.timeout.AddToCommand(cmd) } diff --git a/internal/cli/arguments/programmer.go b/internal/cli/arguments/programmer.go index ed3eb2f8043..c17ec739816 100644 --- a/internal/cli/arguments/programmer.go +++ b/internal/cli/arguments/programmer.go @@ -33,7 +33,7 @@ type Programmer struct { func (p *Programmer) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&p.programmer, "programmer", "P", "", tr("Programmer to use, e.g: atmel_ice")) cmd.RegisterFlagCompletionFunc("programmer", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetInstalledProgrammers(srv, context.Background()), cobra.ShellCompDirectiveDefault + return GetInstalledProgrammers(context.Background(), srv), cobra.ShellCompDirectiveDefault }) } diff --git a/internal/cli/arguments/reference.go b/internal/cli/arguments/reference.go index a8c828890e1..84ad12744fb 100644 --- a/internal/cli/arguments/reference.go +++ b/internal/cli/arguments/reference.go @@ -44,11 +44,11 @@ func (r *Reference) String() string { // ParseReferences is a convenient wrapper that operates on a slice of strings and // calls ParseReference for each of them. It returns at the first invalid argument. -func ParseReferences(srv rpc.ArduinoCoreServiceServer, ctx context.Context, args []string) ([]*Reference, error) { +func ParseReferences(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) ([]*Reference, error) { ret := []*Reference{} for _, arg := range args { // TODO: This is quite resource consuming (since it creates a new instance for each call) - reference, err := ParseReference(srv, ctx, arg) + reference, err := ParseReference(ctx, srv, arg) if err != nil { return nil, err } @@ -62,7 +62,7 @@ func ParseReferences(srv rpc.ArduinoCoreServiceServer, ctx context.Context, args // To achieve that, it tries to use github.com/arduino/arduino-cli/commands/core.GetPlatform // Note that the Reference is returned rightaway if the arg inserted by the user matches perfectly one in the response of core.GetPlatform // A MultiplePlatformsError is returned if the platform searched by the user matches multiple platforms -func ParseReference(srv rpc.ArduinoCoreServiceServer, ctx context.Context, arg string) (*Reference, error) { +func ParseReference(ctx context.Context, srv rpc.ArduinoCoreServiceServer, arg string) (*Reference, error) { logrus.Infof("Parsing reference %s", arg) ret := &Reference{} if arg == "" { @@ -98,7 +98,7 @@ func ParseReference(srv rpc.ArduinoCoreServiceServer, ctx context.Context, arg s // try to use core.PlatformList to optimize what the user typed // (by replacing the PackageName and Architecture in ret with the content of core.GetPlatform()) platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ - Instance: instance.CreateAndInit(srv, ctx), + Instance: instance.CreateAndInit(ctx, srv), }) foundPlatforms := []string{} for _, platform := range platforms.GetSearchOutput() { diff --git a/internal/cli/arguments/reference_test.go b/internal/cli/arguments/reference_test.go index 032899e9f73..b4176dc4e5e 100644 --- a/internal/cli/arguments/reference_test.go +++ b/internal/cli/arguments/reference_test.go @@ -62,13 +62,13 @@ func TestParseReferenceCores(t *testing.T) { srv := commands.NewArduinoCoreServer("") ctx := context.Background() for _, tt := range goodCores { - actual, err := arguments.ParseReference(srv, ctx, tt.in) + actual, err := arguments.ParseReference(ctx, srv, tt.in) assert.Nil(t, err) assert.Equal(t, tt.expected, actual) } for _, tt := range badCores { - actual, err := arguments.ParseReference(srv, ctx, tt.in) + actual, err := arguments.ParseReference(ctx, srv, tt.in) require.NotNil(t, err, "Testing bad core '%s'", tt.in) require.Equal(t, tt.expected, actual, "Testing bad core '%s'", tt.in) } @@ -81,7 +81,7 @@ func TestParseArgs(t *testing.T) { } srv := commands.NewArduinoCoreServer("") - refs, err := arguments.ParseReferences(srv, context.Background(), input) + refs, err := arguments.ParseReferences(context.Background(), srv, input) assert.Nil(t, err) assert.Equal(t, len(goodCores), len(refs)) diff --git a/internal/cli/board/details.go b/internal/cli/board/details.go index c3a7c117945..49fb5aea2b6 100644 --- a/internal/cli/board/details.go +++ b/internal/cli/board/details.go @@ -57,7 +57,7 @@ func initDetailsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runDetailsCommand(srv rpc.ArduinoCoreServiceServer, fqbn string, showFullDetails, listProgrammers bool, showProperties arguments.ShowProperties) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli board details`") diff --git a/internal/cli/board/list.go b/internal/cli/board/list.go index 457797403d7..882de46aaa5 100644 --- a/internal/cli/board/list.go +++ b/internal/cli/board/list.go @@ -59,7 +59,7 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { // runListCommand detects and lists the connected arduino boards func runListCommand(srv rpc.ArduinoCoreServiceServer, watch bool, timeout int64, fqbn string) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli board list`") diff --git a/internal/cli/board/listall.go b/internal/cli/board/listall.go index a0cc18e5a3d..8eaa2c9392b 100644 --- a/internal/cli/board/listall.go +++ b/internal/cli/board/listall.go @@ -53,7 +53,7 @@ for a specific board if you specify the board name`), // runListAllCommand list all installed boards func runListAllCommand(args []string, srv rpc.ArduinoCoreServiceServer) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli board listall`") diff --git a/internal/cli/board/search.go b/internal/cli/board/search.go index c49e640ff18..057026a23b2 100644 --- a/internal/cli/board/search.go +++ b/internal/cli/board/search.go @@ -50,7 +50,7 @@ func initSearchCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli board search`") diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index c191d9da4d0..21ea22dbf3f 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -67,7 +67,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runBootloaderCommand(srv rpc.ArduinoCoreServiceServer) { ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli burn-bootloader`") diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index b5b7039e249..2a628a752f9 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -169,9 +169,9 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer var profile *rpc.SketchProfile if profileArg.Get() == "" { - inst, profile = instance.CreateAndInitWithProfile(srv, ctx, sk.GetDefaultProfile().GetName(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(ctx, srv, sk.GetDefaultProfile().GetName(), sketchPath) } else { - inst, profile = instance.CreateAndInitWithProfile(srv, ctx, profileArg.Get(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(ctx, srv, profileArg.Get(), sketchPath) } if fqbnArg.String() == "" { diff --git a/internal/cli/core/download.go b/internal/cli/core/download.go index 909ffe30448..4fdb11815e3 100644 --- a/internal/cli/core/download.go +++ b/internal/cli/core/download.go @@ -42,7 +42,7 @@ func initDownloadCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { runDownloadCommand(srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableCores(srv, context.Background()), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableCores(context.Background(), srv), cobra.ShellCompDirectiveDefault }, } return downloadCommand @@ -50,11 +50,11 @@ func initDownloadCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli core download`") - platformsRefs, err := arguments.ParseReferences(srv, ctx, args) + platformsRefs, err := arguments.ParseReferences(ctx, srv, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } diff --git a/internal/cli/core/install.go b/internal/cli/core/install.go index d59361f4ee2..b032661a918 100644 --- a/internal/cli/core/install.go +++ b/internal/cli/core/install.go @@ -48,7 +48,7 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { runInstallCommand(srv, args, scriptFlags, noOverwrite) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableCores(srv, context.Background()), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableCores(context.Background(), srv), cobra.ShellCompDirectiveDefault }, } scriptFlags.AddToCommand(installCommand) @@ -59,9 +59,9 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, scriptFlags arguments.PrePostScriptsFlags, noOverwrite bool) { logrus.Info("Executing `arduino-cli core install`") ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) - platformsRefs, err := arguments.ParseReferences(srv, ctx, args) + platformsRefs, err := arguments.ParseReferences(ctx, srv, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } diff --git a/internal/cli/core/list.go b/internal/cli/core/list.go index c0ec34a8f67..71d7a15601e 100644 --- a/internal/cli/core/list.go +++ b/internal/cli/core/list.go @@ -49,7 +49,7 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runListCommand(srv rpc.ArduinoCoreServiceServer, all bool, updatableOnly bool) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli core list`") List(inst, all, updatableOnly) } diff --git a/internal/cli/core/search.go b/internal/cli/core/search.go index 610a9fb97ca..108f41ec2ee 100644 --- a/internal/cli/core/search.go +++ b/internal/cli/core/search.go @@ -54,7 +54,7 @@ const indexUpdateInterval = 24 * time.Hour func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, allVersions bool) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) res, err := commands.UpdateIndex( context.Background(), diff --git a/internal/cli/core/uninstall.go b/internal/cli/core/uninstall.go index 70df514cccb..83d0a2b3cec 100644 --- a/internal/cli/core/uninstall.go +++ b/internal/cli/core/uninstall.go @@ -41,7 +41,7 @@ func initUninstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { runUninstallCommand(srv, args, preUninstallFlags) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetUninstallableCores(srv, context.Background()), cobra.ShellCompDirectiveDefault + return arguments.GetUninstallableCores(context.Background(), srv), cobra.ShellCompDirectiveDefault }, } preUninstallFlags.AddToCommand(uninstallCommand) @@ -51,9 +51,9 @@ func initUninstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, preUninstallFlags arguments.PrePostScriptsFlags) { logrus.Info("Executing `arduino-cli core uninstall`") ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) - platformsRefs, err := arguments.ParseReferences(srv, ctx, args) + platformsRefs, err := arguments.ParseReferences(ctx, srv, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } diff --git a/internal/cli/core/update_index.go b/internal/cli/core/update_index.go index 17bc7b194a3..71e14c3b2ad 100644 --- a/internal/cli/core/update_index.go +++ b/internal/cli/core/update_index.go @@ -45,7 +45,7 @@ func initUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli core update-index`") ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) resp := UpdateIndex(inst) feedback.PrintResult(&updateIndexResult{result.NewUpdateIndexResponse_ResultResult(resp)}) diff --git a/internal/cli/core/upgrade.go b/internal/cli/core/upgrade.go index faf81ab245d..22ba5c0dd58 100644 --- a/internal/cli/core/upgrade.go +++ b/internal/cli/core/upgrade.go @@ -53,12 +53,12 @@ func initUpgradeCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, args []string, skipPostInstall bool, skipPreUninstall bool) { logrus.Info("Executing `arduino-cli core upgrade`") ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) - Upgrade(srv, ctx, inst, args, skipPostInstall, skipPreUninstall) + inst := instance.CreateAndInit(ctx, srv) + Upgrade(ctx, srv, inst, args, skipPostInstall, skipPreUninstall) } // Upgrade upgrades one or all installed platforms to the latest version. -func Upgrade(srv rpc.ArduinoCoreServiceServer, ctx context.Context, inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUninstall bool) { +func Upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUninstall bool) { // if no platform was passed, upgrade allthethings if len(args) == 0 { platforms, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ @@ -103,7 +103,7 @@ func Upgrade(srv rpc.ArduinoCoreServiceServer, ctx context.Context, inst *rpc.In } // proceed upgrading, if anything is upgradable - platformsRefs, err := arguments.ParseReferences(srv, ctx, args) + platformsRefs, err := arguments.ParseReferences(ctx, srv, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index 56b380842d2..90d03cd459c 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -93,9 +93,9 @@ func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs * var profile *rpc.SketchProfile if profileArg.Get() == "" { - inst, profile = instance.CreateAndInitWithProfile(srv, ctx, sk.GetDefaultProfile().GetName(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(ctx, srv, sk.GetDefaultProfile().GetName(), sketchPath) } else { - inst, profile = instance.CreateAndInitWithProfile(srv, ctx, profileArg.Get(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(ctx, srv, profileArg.Get(), sketchPath) } if fqbnArg.String() == "" { diff --git a/internal/cli/debug/debug_check.go b/internal/cli/debug/debug_check.go index 569c64a880c..81cc70cb1d5 100644 --- a/internal/cli/debug/debug_check.go +++ b/internal/cli/debug/debug_check.go @@ -53,7 +53,7 @@ func newDebugCheckCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runDebugCheckCommand(srv rpc.ArduinoCoreServiceServer, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, programmerArg *arguments.Programmer) { ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli debug`") port, err := portArgs.GetPort(instance, srv, "", "") diff --git a/internal/cli/instance/instance.go b/internal/cli/instance/instance.go index 6572fe65802..2d2db7ff52d 100644 --- a/internal/cli/instance/instance.go +++ b/internal/cli/instance/instance.go @@ -31,16 +31,16 @@ var tr = i18n.Tr // If Create fails the CLI prints an error and exits since // to execute further operations a valid Instance is mandatory. // If Init returns errors they're printed only. -func CreateAndInit(srv rpc.ArduinoCoreServiceServer, ctx context.Context) *rpc.Instance { - inst, _ := CreateAndInitWithProfile(srv, ctx, "", nil) +func CreateAndInit(ctx context.Context, srv rpc.ArduinoCoreServiceServer) *rpc.Instance { + inst, _ := CreateAndInitWithProfile(ctx, srv, "", nil) return inst } // CreateAndInitWithProfile returns a new initialized instance using the given profile of the given sketch. // If Create fails the CLI prints an error and exits since to execute further operations a valid Instance is mandatory. // If Init returns errors they're printed only. -func CreateAndInitWithProfile(srv rpc.ArduinoCoreServiceServer, ctx context.Context, profileName string, sketchPath *paths.Path) (*rpc.Instance, *rpc.SketchProfile) { - instance, err := create(srv, ctx) +func CreateAndInitWithProfile(ctx context.Context, srv rpc.ArduinoCoreServiceServer, profileName string, sketchPath *paths.Path) (*rpc.Instance, *rpc.SketchProfile) { + instance, err := create(ctx, srv) if err != nil { feedback.Fatal(tr("Error creating instance: %v", err), feedback.ErrGeneric) } @@ -49,7 +49,7 @@ func CreateAndInitWithProfile(srv rpc.ArduinoCoreServiceServer, ctx context.Cont } // create and return a new Instance. -func create(srv rpc.ArduinoCoreServiceServer, ctx context.Context) (*rpc.Instance, error) { +func create(ctx context.Context, srv rpc.ArduinoCoreServiceServer) (*rpc.Instance, error) { res, err := srv.Create(ctx, &rpc.CreateRequest{}) if err != nil { return nil, err diff --git a/internal/cli/lib/check_deps.go b/internal/cli/lib/check_deps.go index 9c43830c671..87a88837209 100644 --- a/internal/cli/lib/check_deps.go +++ b/internal/cli/lib/check_deps.go @@ -46,7 +46,7 @@ func initDepsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { runDepsCommand(srv, args, noOverwrite) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstalledLibraries(srv, context.Background()), cobra.ShellCompDirectiveDefault + return arguments.GetInstalledLibraries(context.Background(), srv), cobra.ShellCompDirectiveDefault }, } depsCommand.Flags().BoolVar(&noOverwrite, "no-overwrite", false, tr("Do not try to update library dependencies if already installed.")) @@ -55,7 +55,7 @@ func initDepsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runDepsCommand(srv rpc.ArduinoCoreServiceServer, args []string, noOverwrite bool) { ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib deps`") libRef, err := ParseLibraryReferenceArgAndAdjustCase(instance, args[0]) diff --git a/internal/cli/lib/download.go b/internal/cli/lib/download.go index 7c714bb1768..415ce52eb16 100644 --- a/internal/cli/lib/download.go +++ b/internal/cli/lib/download.go @@ -42,7 +42,7 @@ func initDownloadCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { runDownloadCommand(srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableLibs(srv, context.Background()), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableLibs(context.Background(), srv), cobra.ShellCompDirectiveDefault }, } return downloadCommand @@ -51,7 +51,7 @@ func initDownloadCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib download`") ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) refs, err := ParseLibraryReferenceArgsAndAdjustCase(instance, args) if err != nil { diff --git a/internal/cli/lib/examples.go b/internal/cli/lib/examples.go index e8e756ceb0d..06f42086fd6 100644 --- a/internal/cli/lib/examples.go +++ b/internal/cli/lib/examples.go @@ -49,7 +49,7 @@ func initExamplesCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { runExamplesCommand(srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstalledLibraries(srv, context.Background()), cobra.ShellCompDirectiveDefault + return arguments.GetInstalledLibraries(context.Background(), srv), cobra.ShellCompDirectiveDefault }, } fqbn.AddToCommand(examplesCommand, srv) @@ -59,7 +59,7 @@ func initExamplesCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runExamplesCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib examples`") ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) name := "" if len(args) > 0 { diff --git a/internal/cli/lib/install.go b/internal/cli/lib/install.go index 22b6f5f8187..64bede99f8d 100644 --- a/internal/cli/lib/install.go +++ b/internal/cli/lib/install.go @@ -55,7 +55,7 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { runInstallCommand(srv, args, noDeps, noOverwrite, gitURL, zipPath, useBuiltinLibrariesDir) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableLibs(srv, context.Background()), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableLibs(context.Background(), srv), cobra.ShellCompDirectiveDefault }, } installCommand.Flags().BoolVar(&noDeps, "no-deps", false, tr("Do not install dependencies.")) @@ -68,7 +68,7 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps bool, noOverwrite bool, gitURL bool, zipPath bool, useBuiltinLibrariesDir bool) { ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib install`") if zipPath || gitURL { diff --git a/internal/cli/lib/list.go b/internal/cli/lib/list.go index df22b4ef856..1487cf75527 100644 --- a/internal/cli/lib/list.go +++ b/internal/cli/lib/list.go @@ -47,7 +47,7 @@ not listed, they can be listed by adding the --all flag.`), Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib list`") List(instance, args, all, updatable) }, diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index 6fbd0728a78..c76526a97c2 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -103,7 +103,7 @@ const indexUpdateInterval = 60 * time.Minute func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, namesOnly bool, omitReleasesDetails bool) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib search`") diff --git a/internal/cli/lib/uninstall.go b/internal/cli/lib/uninstall.go index dc80f0de7e3..a79ba4683de 100644 --- a/internal/cli/lib/uninstall.go +++ b/internal/cli/lib/uninstall.go @@ -40,7 +40,7 @@ func initUninstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { runUninstallCommand(srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetUninstallableLibraries(srv, context.Background()), cobra.ShellCompDirectiveDefault + return arguments.GetUninstallableLibraries(context.Background(), srv), cobra.ShellCompDirectiveDefault }, } return uninstallCommand @@ -49,7 +49,7 @@ func initUninstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib uninstall`") ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) refs, err := ParseLibraryReferenceArgsAndAdjustCase(instance, args) if err != nil { diff --git a/internal/cli/lib/update_index.go b/internal/cli/lib/update_index.go index 9621978727c..5d531eb96e3 100644 --- a/internal/cli/lib/update_index.go +++ b/internal/cli/lib/update_index.go @@ -44,7 +44,7 @@ func initUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib update-index`") resp := UpdateIndex(inst) diff --git a/internal/cli/lib/upgrade.go b/internal/cli/lib/upgrade.go index 9d018a6ef4a..e7997e3869a 100644 --- a/internal/cli/lib/upgrade.go +++ b/internal/cli/lib/upgrade.go @@ -47,7 +47,7 @@ func initUpgradeCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib upgrade`") ctx := context.Background() - instance := instance.CreateAndInit(srv, ctx) + instance := instance.CreateAndInit(ctx, srv) Upgrade(instance, args) } diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index e11c10eef05..b60805e36b5 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -117,13 +117,13 @@ func runMonitorCmd( } if fqbnArg.String() == "" { if profileArg.Get() == "" { - inst, profile = instance.CreateAndInitWithProfile(srv, ctx, sketch.GetDefaultProfile().GetName(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(ctx, srv, sketch.GetDefaultProfile().GetName(), sketchPath) } else { - inst, profile = instance.CreateAndInitWithProfile(srv, ctx, profileArg.Get(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(ctx, srv, profileArg.Get(), sketchPath) } } if inst == nil { - inst = instance.CreateAndInit(srv, ctx) + inst = instance.CreateAndInit(ctx, srv) } // Priority on how to retrieve the fqbn // 1. from flag diff --git a/internal/cli/outdated/outdated.go b/internal/cli/outdated/outdated.go index 7570da56c1b..7ec59e81e57 100644 --- a/internal/cli/outdated/outdated.go +++ b/internal/cli/outdated/outdated.go @@ -55,7 +55,7 @@ that can be upgraded. If nothing needs to be updated the output is empty.`), func runOutdatedCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli outdated`") ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) Outdated(inst) } diff --git a/internal/cli/update/update.go b/internal/cli/update/update.go index 3c2d77cff85..210ba7874d6 100644 --- a/internal/cli/update/update.go +++ b/internal/cli/update/update.go @@ -51,7 +51,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUpdateCommand(srv rpc.ArduinoCoreServiceServer, showOutdated bool) { logrus.Info("Executing `arduino-cli update`") ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) lib.UpdateIndex(inst) core.UpdateIndex(inst) diff --git a/internal/cli/upgrade/upgrade.go b/internal/cli/upgrade/upgrade.go index 98339aad7f8..e80b98fa5c7 100644 --- a/internal/cli/upgrade/upgrade.go +++ b/internal/cli/upgrade/upgrade.go @@ -50,8 +50,8 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, skipPostInstall bool, skipPreUninstall bool) { ctx := context.Background() - inst := instance.CreateAndInit(srv, ctx) + inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli upgrade`") lib.Upgrade(inst, []string{}) - core.Upgrade(srv, ctx, inst, []string{}, skipPostInstall, skipPreUninstall) + core.Upgrade(ctx, srv, inst, []string{}, skipPostInstall, skipPreUninstall) } diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 0cc1f0f89f1..97bd50c5af8 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -103,9 +103,9 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie var profile *rpc.SketchProfile if profileArg.Get() == "" { - inst, profile = instance.CreateAndInitWithProfile(srv, ctx, sketch.GetDefaultProfile().GetName(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(ctx, srv, sketch.GetDefaultProfile().GetName(), sketchPath) } else { - inst, profile = instance.CreateAndInitWithProfile(srv, ctx, profileArg.Get(), sketchPath) + inst, profile = instance.CreateAndInitWithProfile(ctx, srv, profileArg.Get(), sketchPath) } if fqbnArg.String() == "" { From a81069dda0cfc5090b12796fb3a7c00a22417228 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 14 Mar 2024 15:54:39 +0100 Subject: [PATCH 15/56] Inlining methods in ArduinoCoreServiceImpl (part 6: Init) Added helpers to get init progress. --- commands/grpc_streaming_helpers.go | 42 ++++++++++++++++++++++++ commands/instances.go | 19 +++++++---- commands/service.go | 18 ++++------ commands/service_library_install.go | 5 +-- commands/service_library_upgrade.go | 17 ++++++---- commands/service_platform_install.go | 6 ++-- commands/service_platform_search_test.go | 4 +-- commands/service_platform_uninstall.go | 4 +-- commands/service_platform_upgrade.go | 4 +-- internal/cli/core/install.go | 2 +- internal/cli/core/search.go | 2 +- internal/cli/core/uninstall.go | 2 +- internal/cli/core/upgrade.go | 2 +- internal/cli/instance/instance.go | 13 ++++---- internal/cli/lib/install.go | 2 +- internal/cli/lib/search.go | 2 +- internal/cli/lib/upgrade.go | 8 ++--- internal/cli/update/update.go | 2 +- internal/cli/upgrade/upgrade.go | 2 +- 19 files changed, 103 insertions(+), 53 deletions(-) diff --git a/commands/grpc_streaming_helpers.go b/commands/grpc_streaming_helpers.go index d86dfd61795..927e5e40f2d 100644 --- a/commands/grpc_streaming_helpers.go +++ b/commands/grpc_streaming_helpers.go @@ -76,3 +76,45 @@ func (w *streamingResponseProxyToChan[T]) SetHeader(metadata.MD) error { func (w *streamingResponseProxyToChan[T]) SetTrailer(tr metadata.MD) { } + +// streamingResponseProxyToCallback is a streaming response proxy that +// forwards the responses to a callback function +type streamingResponseProxyToCallback[T any] struct { + ctx context.Context + cb func(*T) error +} + +// creates a streaming response proxy that forwards the responses to a callback function +func streamResponseToCallback[T any](ctx context.Context, cb func(*T) error) *streamingResponseProxyToCallback[T] { + if cb == nil { + cb = func(*T) error { return nil } + } + return &streamingResponseProxyToCallback[T]{ctx: ctx, cb: cb} +} + +func (w *streamingResponseProxyToCallback[T]) Send(resp *T) error { + return w.cb(resp) +} + +func (w *streamingResponseProxyToCallback[T]) Context() context.Context { + return w.ctx +} + +func (w *streamingResponseProxyToCallback[T]) RecvMsg(m any) error { + return errors.New("RecvMsg not implemented") +} + +func (w *streamingResponseProxyToCallback[T]) SendHeader(metadata.MD) error { + return errors.New("SendHeader not implemented") +} + +func (w *streamingResponseProxyToCallback[T]) SendMsg(m any) error { + return errors.New("SendMsg not implemented") +} + +func (w *streamingResponseProxyToCallback[T]) SetHeader(metadata.MD) error { + return errors.New("SetHeader not implemented") +} + +func (w *streamingResponseProxyToCallback[T]) SetTrailer(tr metadata.MD) { +} diff --git a/commands/instances.go b/commands/instances.go index 92c317fe836..f795c1ad04e 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -96,23 +96,30 @@ func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque return &rpc.CreateResponse{Instance: inst}, nil } +// InitStreamResponseToCallbackFunction returns a gRPC stream to be used in Init that sends +// all responses to the callback function. +func InitStreamResponseToCallbackFunction(ctx context.Context, cb func(r *rpc.InitResponse) error) rpc.ArduinoCoreService_InitServer { + return streamResponseToCallback(ctx, cb) +} + // Init loads installed libraries and Platforms in CoreInstance with specified ID, // a gRPC status error is returned if the CoreInstance doesn't exist. // 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)) error { - if responseCallback == nil { - responseCallback = func(r *rpc.InitResponse) {} - } +func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { instance := req.GetInstance() if !instances.IsValid(instance) { return &cmderrors.InvalidInstanceError{} } // Setup callback functions - if responseCallback == nil { - responseCallback = func(r *rpc.InitResponse) {} + var responseCallback func(*rpc.InitResponse) error + if stream != nil { + syncSend := NewSynchronizedSend(stream.Send) + responseCallback = syncSend.Send + } else { + responseCallback = func(*rpc.InitResponse) error { return nil } } responseError := func(st *status.Status) { responseCallback(&rpc.InitResponse{ diff --git a/commands/service.go b/commands/service.go index 548a93d9a5f..4fb73e74dc1 100644 --- a/commands/service.go +++ b/commands/service.go @@ -78,12 +78,6 @@ func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd return err } -// Init FIXMEDOC -func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { - syncSend := NewSynchronizedSend(stream.Send) - return Init(req, func(message *rpc.InitResponse) { syncSend.Send(message) }) -} - // Version FIXMEDOC func (s *arduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionRequest) (*rpc.VersionResponse, error) { return &rpc.VersionResponse{Version: s.versionString}, nil @@ -144,7 +138,7 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) resp, err := PlatformInstall( - stream.Context(), req, + stream.Context(), s, req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformInstallResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) }, ) @@ -171,7 +165,7 @@ func (s *arduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadReques func (s *arduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequest, stream rpc.ArduinoCoreService_PlatformUninstallServer) error { syncSend := NewSynchronizedSend(stream.Send) resp, err := PlatformUninstall( - stream.Context(), req, + stream.Context(), s, req, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) }, ) if err != nil { @@ -184,7 +178,7 @@ func (s *arduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequ func (s *arduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, stream rpc.ArduinoCoreService_PlatformUpgradeServer) error { syncSend := NewSynchronizedSend(stream.Send) resp, err := PlatformUpgrade( - stream.Context(), req, + stream.Context(), s, req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{TaskProgress: p}) }, ) @@ -304,7 +298,7 @@ func (s *arduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, stream rpc.ArduinoCoreService_LibraryInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) return LibraryInstall( - stream.Context(), req, + stream.Context(), s, req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryInstallResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) }, ) @@ -314,7 +308,7 @@ func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s func (s *arduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, stream rpc.ArduinoCoreService_LibraryUpgradeServer) error { syncSend := NewSynchronizedSend(stream.Send) return LibraryUpgrade( - stream.Context(), req, + stream.Context(), s, req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{TaskProgress: p}) }, ) @@ -331,7 +325,7 @@ func (s *arduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallReques // LibraryUpgradeAll FIXMEDOC func (s *arduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, stream rpc.ArduinoCoreService_LibraryUpgradeAllServer) error { syncSend := NewSynchronizedSend(stream.Send) - return LibraryUpgradeAll(req, + return LibraryUpgradeAll(s, req, func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{Progress: p}) }, func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) }, ) diff --git a/commands/service_library_install.go b/commands/service_library_install.go index 021eada534f..f08c50f8ccc 100644 --- a/commands/service_library_install.go +++ b/commands/service_library_install.go @@ -31,7 +31,7 @@ import ( ) // LibraryInstall resolves the library dependencies, then downloads and installs the libraries into the install location. -func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func LibraryInstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.LibraryInstallRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { // Obtain the library index from the manager li, err := instances.GetLibrariesIndex(req.GetInstance()) if err != nil { @@ -136,7 +136,8 @@ func LibraryInstall(ctx context.Context, req *rpc.LibraryInstallRequest, downloa } } - if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + stream := InitStreamResponseToCallbackFunction(ctx, nil) + if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, stream); err != nil { return err } diff --git a/commands/service_library_upgrade.go b/commands/service_library_upgrade.go index 75742a22dd3..327c0245ee7 100644 --- a/commands/service_library_upgrade.go +++ b/commands/service_library_upgrade.go @@ -24,7 +24,9 @@ import ( ) // LibraryUpgradeAll upgrades all the available libraries -func LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func LibraryUpgradeAll(srv rpc.ArduinoCoreServiceServer, req *rpc.LibraryUpgradeAllRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { + ctx := context.Background() + li, err := instances.GetLibrariesIndex(req.GetInstance()) if err != nil { return err @@ -37,11 +39,12 @@ func LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, downloadCB rpc.Downloa libsToUpgrade := listLibraries(lme, li, true, false) release() - if err := upgrade(req.GetInstance(), libsToUpgrade, downloadCB, taskCB); err != nil { + if err := upgrade(ctx, srv, req.GetInstance(), libsToUpgrade, downloadCB, taskCB); err != nil { return err } - if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + stream := InitStreamResponseToCallbackFunction(ctx, nil) + if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, stream); err != nil { return err } @@ -49,7 +52,7 @@ func LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, downloadCB rpc.Downloa } // LibraryUpgrade upgrades a library -func LibraryUpgrade(ctx context.Context, req *rpc.LibraryUpgradeRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func LibraryUpgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.LibraryUpgradeRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { li, err := instances.GetLibrariesIndex(req.GetInstance()) if err != nil { return err @@ -75,10 +78,10 @@ func LibraryUpgrade(ctx context.Context, req *rpc.LibraryUpgradeRequest, downloa } // Install update - return upgrade(req.GetInstance(), []*installedLib{lib}, downloadCB, taskCB) + return upgrade(ctx, srv, req.GetInstance(), []*installedLib{lib}, downloadCB, taskCB) } -func upgrade(instance *rpc.Instance, libs []*installedLib, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, libs []*installedLib, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { for _, lib := range libs { libInstallReq := &rpc.LibraryInstallRequest{ Instance: instance, @@ -87,7 +90,7 @@ func upgrade(instance *rpc.Instance, libs []*installedLib, downloadCB rpc.Downlo NoDeps: false, NoOverwrite: false, } - err := LibraryInstall(context.Background(), libInstallReq, downloadCB, taskCB) + err := LibraryInstall(ctx, srv, libInstallReq, downloadCB, taskCB) if err != nil { return err } diff --git a/commands/service_platform_install.go b/commands/service_platform_install.go index 1fad3919f44..94c64c07921 100644 --- a/commands/service_platform_install.go +++ b/commands/service_platform_install.go @@ -26,7 +26,7 @@ import ( ) // PlatformInstall FIXMEDOC -func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) (*rpc.PlatformInstallResponse, error) { +func PlatformInstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.PlatformInstallRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) (*rpc.PlatformInstallResponse, error) { install := func() error { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { @@ -73,7 +73,9 @@ func PlatformInstall(ctx context.Context, req *rpc.PlatformInstallRequest, downl if err := install(); err != nil { return nil, err } - if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + + stream := InitStreamResponseToCallbackFunction(ctx, nil) + if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, stream); err != nil { return nil, err } return &rpc.PlatformInstallResponse{}, nil diff --git a/commands/service_platform_search_test.go b/commands/service_platform_search_test.go index 83942433321..315a39c0fbb 100644 --- a/commands/service_platform_search_test.go +++ b/commands/service_platform_search_test.go @@ -46,7 +46,7 @@ func TestPlatformSearch(t *testing.T) { inst := createResp.GetInstance() require.NotNil(t, inst) - err = Init(&rpc.InitRequest{Instance: inst}, nil) + err = srv.Init(&rpc.InitRequest{Instance: inst}, InitStreamResponseToCallbackFunction(ctx, nil)) require.NoError(t, err) t.Run("SearchAllVersions", func(t *testing.T) { @@ -347,7 +347,7 @@ func TestPlatformSearchSorting(t *testing.T) { require.NoError(t, err) inst := createResp.GetInstance() require.NotNil(t, inst) - err = Init(&rpc.InitRequest{Instance: inst}, nil) + err = srv.Init(&rpc.InitRequest{Instance: inst}, InitStreamResponseToCallbackFunction(ctx, nil)) require.NoError(t, err) res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ diff --git a/commands/service_platform_uninstall.go b/commands/service_platform_uninstall.go index 9459a92ba86..b6679b891cb 100644 --- a/commands/service_platform_uninstall.go +++ b/commands/service_platform_uninstall.go @@ -25,11 +25,11 @@ import ( ) // PlatformUninstall FIXMEDOC -func PlatformUninstall(ctx context.Context, req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgressCB) (*rpc.PlatformUninstallResponse, error) { +func PlatformUninstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgressCB) (*rpc.PlatformUninstallResponse, error) { if err := platformUninstall(req, taskCB); err != nil { return nil, err } - if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, InitStreamResponseToCallbackFunction(ctx, nil)); err != nil { return nil, err } return &rpc.PlatformUninstallResponse{}, nil diff --git a/commands/service_platform_upgrade.go b/commands/service_platform_upgrade.go index 2b8c5811364..25d7de2fc79 100644 --- a/commands/service_platform_upgrade.go +++ b/commands/service_platform_upgrade.go @@ -25,7 +25,7 @@ import ( ) // PlatformUpgrade FIXMEDOC -func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) (*rpc.PlatformUpgradeResponse, error) { +func PlatformUpgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.PlatformUpgradeRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) (*rpc.PlatformUpgradeResponse, error) { upgrade := func() (*cores.PlatformRelease, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { @@ -57,7 +57,7 @@ func PlatformUpgrade(ctx context.Context, req *rpc.PlatformUpgradeRequest, downl if err != nil { return &rpc.PlatformUpgradeResponse{Platform: rpcPlatform}, err } - if err := Init(&rpc.InitRequest{Instance: req.GetInstance()}, nil); err != nil { + if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, InitStreamResponseToCallbackFunction(ctx, nil)); err != nil { return nil, err } diff --git a/internal/cli/core/install.go b/internal/cli/core/install.go index b032661a918..a6f1b7a35b3 100644 --- a/internal/cli/core/install.go +++ b/internal/cli/core/install.go @@ -76,7 +76,7 @@ func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, scriptFl NoOverwrite: noOverwrite, SkipPreUninstall: scriptFlags.DetectSkipPreUninstallValue(), } - _, err := commands.PlatformInstall(context.Background(), platformInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) + _, err := commands.PlatformInstall(ctx, srv, platformInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) if err != nil { feedback.Fatal(tr("Error during install: %v", err), feedback.ErrGeneric) } diff --git a/internal/cli/core/search.go b/internal/cli/core/search.go index 108f41ec2ee..030fdc981e2 100644 --- a/internal/cli/core/search.go +++ b/internal/cli/core/search.go @@ -66,7 +66,7 @@ func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, allVersio for _, idxRes := range res.GetUpdatedIndexes() { if idxRes.GetStatus() == rpc.IndexUpdateReport_STATUS_UPDATED { // At least one index has been updated, reinitialize the instance - instance.Init(inst) + instance.Init(ctx, srv, inst) break } } diff --git a/internal/cli/core/uninstall.go b/internal/cli/core/uninstall.go index 83d0a2b3cec..6c8e7526211 100644 --- a/internal/cli/core/uninstall.go +++ b/internal/cli/core/uninstall.go @@ -64,7 +64,7 @@ func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, preUni } } for _, platformRef := range platformsRefs { - _, err := commands.PlatformUninstall(context.Background(), &rpc.PlatformUninstallRequest{ + _, err := commands.PlatformUninstall(ctx, srv, &rpc.PlatformUninstallRequest{ Instance: inst, PlatformPackage: platformRef.PackageName, Architecture: platformRef.Architecture, diff --git a/internal/cli/core/upgrade.go b/internal/cli/core/upgrade.go index 22ba5c0dd58..131fe713ede 100644 --- a/internal/cli/core/upgrade.go +++ b/internal/cli/core/upgrade.go @@ -123,7 +123,7 @@ func Upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.In SkipPostInstall: skipPostInstall, SkipPreUninstall: skipPreUninstall, } - response, err := commands.PlatformUpgrade(context.Background(), r, feedback.ProgressBar(), feedback.TaskProgress()) + response, err := commands.PlatformUpgrade(ctx, srv, r, feedback.ProgressBar(), feedback.TaskProgress()) warningMissingIndex(response) if err != nil { var alreadyAtLatestVersionErr *cmderrors.PlatformAlreadyAtTheLatestVersionError diff --git a/internal/cli/instance/instance.go b/internal/cli/instance/instance.go index 2d2db7ff52d..28a19ad6e5a 100644 --- a/internal/cli/instance/instance.go +++ b/internal/cli/instance/instance.go @@ -44,7 +44,7 @@ func CreateAndInitWithProfile(ctx context.Context, srv rpc.ArduinoCoreServiceSer if err != nil { feedback.Fatal(tr("Error creating instance: %v", err), feedback.ErrGeneric) } - profile := InitWithProfile(instance, profileName, sketchPath) + profile := InitWithProfile(ctx, srv, instance, profileName, sketchPath) return instance, profile } @@ -62,14 +62,14 @@ func create(ctx context.Context, srv rpc.ArduinoCoreServiceServer) (*rpc.Instanc // 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) { - InitWithProfile(instance, "", nil) +func Init(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance) { + InitWithProfile(ctx, srv, instance, "", nil) } // InitWithProfile initializes instance by loading libraries and platforms specified in the given profile of the given sketch. // In case of loading failures return a list of errors for each platform or library that we failed to load. // Required Package and library indexes files are automatically downloaded. -func InitWithProfile(instance *rpc.Instance, profileName string, sketchPath *paths.Path) *rpc.SketchProfile { +func InitWithProfile(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, profileName string, sketchPath *paths.Path) *rpc.SketchProfile { downloadCallback := feedback.ProgressBar() taskCallback := feedback.TaskProgress() @@ -79,7 +79,7 @@ func InitWithProfile(instance *rpc.Instance, profileName string, sketchPath *pat initReq.Profile = profileName } var profile *rpc.SketchProfile - err := commands.Init(initReq, func(res *rpc.InitResponse) { + err := srv.Init(initReq, commands.InitStreamResponseToCallbackFunction(ctx, func(res *rpc.InitResponse) error { if st := res.GetError(); st != nil { feedback.Warning(tr("Error initializing instance: %v", st.GetMessage())) } @@ -96,7 +96,8 @@ func InitWithProfile(instance *rpc.Instance, profileName string, sketchPath *pat if p := res.GetProfile(); p != nil { profile = p } - }) + return nil + })) if err != nil { feedback.Warning(tr("Error initializing instance: %v", err)) } diff --git a/internal/cli/lib/install.go b/internal/cli/lib/install.go index 64bede99f8d..0fe9fca84ed 100644 --- a/internal/cli/lib/install.go +++ b/internal/cli/lib/install.go @@ -141,7 +141,7 @@ func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps b NoOverwrite: noOverwrite, InstallLocation: installLocation, } - err := commands.LibraryInstall(context.Background(), libraryInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) + err := commands.LibraryInstall(ctx, srv, libraryInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) if err != nil { feedback.Fatal(tr("Error installing %s: %v", libRef.Name, err), feedback.ErrGeneric) } diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index c76526a97c2..94a4cc616fb 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -116,7 +116,7 @@ func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, namesOnly feedback.Fatal(tr("Error updating library index: %v", err), feedback.ErrGeneric) } if res.GetLibrariesIndex().GetStatus() == rpc.IndexUpdateReport_STATUS_UPDATED { - instance.Init(inst) + instance.Init(ctx, srv, inst) } searchResp, err := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ diff --git a/internal/cli/lib/upgrade.go b/internal/cli/lib/upgrade.go index e7997e3869a..52bd644c730 100644 --- a/internal/cli/lib/upgrade.go +++ b/internal/cli/lib/upgrade.go @@ -48,22 +48,22 @@ func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib upgrade`") ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) - Upgrade(instance, args) + Upgrade(ctx, srv, instance, args) } // Upgrade upgrades the specified libraries -func Upgrade(instance *rpc.Instance, libraries []string) { +func Upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, libraries []string) { var upgradeErr error if len(libraries) == 0 { req := &rpc.LibraryUpgradeAllRequest{Instance: instance} - upgradeErr = commands.LibraryUpgradeAll(req, feedback.ProgressBar(), feedback.TaskProgress()) + upgradeErr = commands.LibraryUpgradeAll(srv, req, feedback.ProgressBar(), feedback.TaskProgress()) } else { for _, libName := range libraries { req := &rpc.LibraryUpgradeRequest{ Instance: instance, Name: libName, } - upgradeErr = commands.LibraryUpgrade(context.Background(), req, feedback.ProgressBar(), feedback.TaskProgress()) + upgradeErr = commands.LibraryUpgrade(ctx, srv, req, feedback.ProgressBar(), feedback.TaskProgress()) if upgradeErr != nil { break } diff --git a/internal/cli/update/update.go b/internal/cli/update/update.go index 210ba7874d6..f589efa9975 100644 --- a/internal/cli/update/update.go +++ b/internal/cli/update/update.go @@ -55,7 +55,7 @@ func runUpdateCommand(srv rpc.ArduinoCoreServiceServer, showOutdated bool) { lib.UpdateIndex(inst) core.UpdateIndex(inst) - instance.Init(inst) + instance.Init(ctx, srv, inst) if showOutdated { outdated.Outdated(inst) } diff --git a/internal/cli/upgrade/upgrade.go b/internal/cli/upgrade/upgrade.go index e80b98fa5c7..1fee19a4443 100644 --- a/internal/cli/upgrade/upgrade.go +++ b/internal/cli/upgrade/upgrade.go @@ -52,6 +52,6 @@ func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, skipPostInstall bool, s ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli upgrade`") - lib.Upgrade(inst, []string{}) + lib.Upgrade(ctx, srv, inst, []string{}) core.Upgrade(ctx, srv, inst, []string{}, skipPostInstall, skipPreUninstall) } From 917dcc5df6c206f6d1c6e93ec745fd931937cf3d Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 14 Mar 2024 15:56:47 +0100 Subject: [PATCH 16/56] Inlining methods in ArduinoCoreServiceImpl (part 7: UpdateIndex) Added helpers to get download progress. --- commands/instances.go | 43 +++++++++++++++++++++++++------ commands/service.go | 18 ------------- internal/cli/core/search.go | 8 +++--- internal/cli/core/update_index.go | 9 ++++--- internal/cli/update/update.go | 2 +- 5 files changed, 45 insertions(+), 35 deletions(-) diff --git a/commands/instances.go b/commands/instances.go index f795c1ad04e..614825c19af 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -184,7 +184,8 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor allPackageIndexUrls = append(allPackageIndexUrls, URL) } } - if err := firstUpdate(context.Background(), req.GetInstance(), downloadCallback, allPackageIndexUrls); err != nil { + + if err := firstUpdate(context.Background(), s, req.GetInstance(), downloadCallback, allPackageIndexUrls); err != nil { e := &cmderrors.InitFailedError{ Code: codes.InvalidArgument, Cause: err, @@ -464,10 +465,27 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequ return result(rpc.IndexUpdateReport_STATUS_UPDATED), nil } +// UpdateIndexStreamResponseToCallbackFunction returns a gRPC stream to be used in UpdateIndex that sends +// all responses to the callback function. +func UpdateIndexStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB) (rpc.ArduinoCoreService_UpdateIndexServer, func() *rpc.UpdateIndexResponse_Result) { + var result *rpc.UpdateIndexResponse_Result + return streamResponseToCallback(ctx, func(r *rpc.UpdateIndexResponse) error { + if r.GetDownloadProgress() != nil { + downloadCB(r.GetDownloadProgress()) + } + if r.GetResult() != nil { + result = r.GetResult() + } + return nil + }), func() *rpc.UpdateIndexResponse_Result { + return result + } +} + // UpdateIndex FIXMEDOC -func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB rpc.DownloadProgressCB) (*rpc.UpdateIndexResponse_Result, error) { +func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream rpc.ArduinoCoreService_UpdateIndexServer) error { if !instances.IsValid(req.GetInstance()) { - return nil, &cmderrors.InvalidInstanceError{} + return &cmderrors.InvalidInstanceError{} } report := func(indexURL *url.URL, status rpc.IndexUpdateReport_Status) *rpc.IndexUpdateReport { @@ -477,6 +495,12 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB rp } } + syncSend := NewSynchronizedSend(stream.Send) + var downloadCB rpc.DownloadProgressCB = func(p *rpc.DownloadProgress) { + syncSend.Send(&rpc.UpdateIndexResponse{ + Message: &rpc.UpdateIndexResponse_DownloadProgress{DownloadProgress: p}, + }) + } indexpath := configuration.DataDir(configuration.Settings) urls := []string{globals.DefaultIndexURL} @@ -549,16 +573,18 @@ func UpdateIndex(ctx context.Context, req *rpc.UpdateIndexRequest, downloadCB rp result.UpdatedIndexes = append(result.GetUpdatedIndexes(), report(URL, rpc.IndexUpdateReport_STATUS_UPDATED)) } } - + syncSend.Send(&rpc.UpdateIndexResponse{ + Message: &rpc.UpdateIndexResponse_Result_{Result: result}, + }) if failed { - return result, &cmderrors.FailedDownloadError{Message: tr("Some indexes could not be updated.")} + return &cmderrors.FailedDownloadError{Message: tr("Some indexes could not be updated.")} } - return result, nil + return nil } // 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(ctx context.Context, instance *rpc.Instance, downloadCb func(msg *rpc.DownloadProgress), externalPackageIndexes []*url.URL) error { +func firstUpdate(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, downloadCb func(msg *rpc.DownloadProgress), externalPackageIndexes []*url.URL) error { // Gets the data directory to verify if library_index.json and package_index.json exist dataDir := configuration.DataDir(configuration.Settings) libraryIndex := dataDir.Join("library_index.json") @@ -589,7 +615,8 @@ func firstUpdate(ctx context.Context, instance *rpc.Instance, downloadCb func(ms // library update we download that file and all the other package indexes from // additional_urls req := &rpc.UpdateIndexRequest{Instance: instance} - if _, err := UpdateIndex(ctx, req, downloadCb); err != nil { + stream, _ := UpdateIndexStreamResponseToCallbackFunction(ctx, downloadCb) + if err := srv.UpdateIndex(req, stream); err != nil { return err } break diff --git a/commands/service.go b/commands/service.go index 4fb73e74dc1..4f503fe4ceb 100644 --- a/commands/service.go +++ b/commands/service.go @@ -42,24 +42,6 @@ type arduinoCoreServerImpl struct { versionString string } -// UpdateIndex FIXMEDOC -func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream rpc.ArduinoCoreService_UpdateIndexServer) error { - syncSend := NewSynchronizedSend(stream.Send) - res, err := UpdateIndex(stream.Context(), req, - func(p *rpc.DownloadProgress) { - syncSend.Send(&rpc.UpdateIndexResponse{ - Message: &rpc.UpdateIndexResponse_DownloadProgress{DownloadProgress: p}, - }) - }, - ) - if res != nil { - syncSend.Send(&rpc.UpdateIndexResponse{ - Message: &rpc.UpdateIndexResponse_Result_{Result: res}, - }) - } - return err -} - // UpdateLibrariesIndex FIXMEDOC func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesIndexRequest, stream rpc.ArduinoCoreService_UpdateLibrariesIndexServer) error { syncSend := NewSynchronizedSend(stream.Send) diff --git a/internal/cli/core/search.go b/internal/cli/core/search.go index 030fdc981e2..096ef44e500 100644 --- a/internal/cli/core/search.go +++ b/internal/cli/core/search.go @@ -56,14 +56,14 @@ func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, allVersio ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) - res, err := commands.UpdateIndex( - context.Background(), + stream, res := commands.UpdateIndexStreamResponseToCallbackFunction(ctx, feedback.ProgressBar()) + err := srv.UpdateIndex( &rpc.UpdateIndexRequest{Instance: inst, UpdateIfOlderThanSecs: int64(indexUpdateInterval.Seconds())}, - feedback.ProgressBar()) + stream) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } - for _, idxRes := range res.GetUpdatedIndexes() { + for _, idxRes := range res().GetUpdatedIndexes() { if idxRes.GetStatus() == rpc.IndexUpdateReport_STATUS_UPDATED { // At least one index has been updated, reinitialize the instance instance.Init(ctx, srv, inst) diff --git a/internal/cli/core/update_index.go b/internal/cli/core/update_index.go index 71e14c3b2ad..01cecd4fd9a 100644 --- a/internal/cli/core/update_index.go +++ b/internal/cli/core/update_index.go @@ -46,18 +46,19 @@ func runUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli core update-index`") ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) - resp := UpdateIndex(inst) + resp := UpdateIndex(ctx, srv, inst) feedback.PrintResult(&updateIndexResult{result.NewUpdateIndexResponse_ResultResult(resp)}) } // UpdateIndex updates the index of platforms. -func UpdateIndex(inst *rpc.Instance) *rpc.UpdateIndexResponse_Result { - res, err := commands.UpdateIndex(context.Background(), &rpc.UpdateIndexRequest{Instance: inst}, feedback.ProgressBar()) +func UpdateIndex(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.Instance) *rpc.UpdateIndexResponse_Result { + stream, res := commands.UpdateIndexStreamResponseToCallbackFunction(ctx, feedback.ProgressBar()) + err := srv.UpdateIndex(&rpc.UpdateIndexRequest{Instance: inst}, stream) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } - return res + return res() } type updateIndexResult struct { diff --git a/internal/cli/update/update.go b/internal/cli/update/update.go index f589efa9975..64ea2b77562 100644 --- a/internal/cli/update/update.go +++ b/internal/cli/update/update.go @@ -54,7 +54,7 @@ func runUpdateCommand(srv rpc.ArduinoCoreServiceServer, showOutdated bool) { inst := instance.CreateAndInit(ctx, srv) lib.UpdateIndex(inst) - core.UpdateIndex(inst) + core.UpdateIndex(ctx, srv, inst) instance.Init(ctx, srv, inst) if showOutdated { outdated.Outdated(inst) From bb815cfe050d31ea827b7db3814bd24cf88049ee Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 15 Mar 2024 19:01:35 +0100 Subject: [PATCH 17/56] Inlining methods in ArduinoCoreServiceImpl (part 8: Monitor) This change is quite challenging because it implements a bidirectional streaming service. The gRPC implementation is slightly simpler, BTW the command-line requires a bit of streams fiddling to get the same behaviour as before because now: * the Monitor call do not return anymore a clean io.ReadWriteCloser. * the call to srv.Monitor is blocking until the port is closed or the context is canceled. --- commands/service.go | 101 -------------- commands/service_monitor.go | 230 ++++++++++++++++++++++++-------- internal/cli/monitor/monitor.go | 32 ++--- 3 files changed, 195 insertions(+), 168 deletions(-) diff --git a/commands/service.go b/commands/service.go index 4f503fe4ceb..2d32e1c368f 100644 --- a/commands/service.go +++ b/commands/service.go @@ -17,15 +17,10 @@ package commands import ( "context" - "errors" - "io" - "sync/atomic" "github.com/arduino/arduino-cli/commands/cache" - "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/updatecheck" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "github.com/sirupsen/logrus" ) // NewArduinoCoreServer returns an implementation of the ArduinoCoreService gRPC service @@ -356,102 +351,6 @@ func (s *arduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context return EnumerateMonitorPortSettings(ctx, req) } -// Monitor FIXMEDOC -func (s *arduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorServer) error { - syncSend := NewSynchronizedSend(stream.Send) - - // The configuration must be sent on the first message - req, err := stream.Recv() - if err != nil { - return err - } - - openReq := req.GetOpenRequest() - if openReq == nil { - return &cmderrors.InvalidInstanceError{} - } - portProxy, _, err := Monitor(stream.Context(), openReq) - if err != nil { - return err - } - - // Send a message with Success set to true to notify the caller of the port being now active - _ = syncSend.Send(&rpc.MonitorResponse{Success: true}) - - cancelCtx, cancel := context.WithCancel(stream.Context()) - gracefulCloseInitiated := &atomic.Bool{} - gracefuleCloseCtx, gracefulCloseCancel := context.WithCancel(context.Background()) - - // gRPC stream receiver (gRPC data -> monitor, config, close) - go func() { - defer cancel() - for { - msg, err := stream.Recv() - if errors.Is(err, io.EOF) { - return - } - if err != nil { - syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) - return - } - if conf := msg.GetUpdatedConfiguration(); conf != nil { - for _, c := range conf.GetSettings() { - if err := portProxy.Config(c.GetSettingId(), c.GetValue()); err != nil { - syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) - } - } - } - if closeMsg := msg.GetClose(); closeMsg { - gracefulCloseInitiated.Store(true) - if err := portProxy.Close(); err != nil { - logrus.WithError(err).Debug("Error closing monitor port") - } - gracefulCloseCancel() - } - tx := msg.GetTxData() - for len(tx) > 0 { - n, err := portProxy.Write(tx) - if errors.Is(err, io.EOF) { - return - } - if err != nil { - syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) - return - } - tx = tx[n:] - } - } - }() - - // gRPC stream sender (monitor -> gRPC) - go func() { - defer cancel() // unlock the receiver - buff := make([]byte, 4096) - for { - n, err := portProxy.Read(buff) - if errors.Is(err, io.EOF) { - break - } - if err != nil { - syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) - break - } - if err := syncSend.Send(&rpc.MonitorResponse{RxData: buff[:n]}); err != nil { - break - } - } - }() - - <-cancelCtx.Done() - if gracefulCloseInitiated.Load() { - // Port closing has been initiated in the receiver - <-gracefuleCloseCtx.Done() - } else { - portProxy.Close() - } - return nil -} - // CheckForArduinoCLIUpdates FIXMEDOC func (s *arduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, req *rpc.CheckForArduinoCLIUpdatesRequest) (*rpc.CheckForArduinoCLIUpdatesResponse, error) { return updatecheck.CheckForArduinoCLIUpdates(ctx, req) diff --git a/commands/service_monitor.go b/commands/service_monitor.go index 538e99795bb..1e9b0e7d1f5 100644 --- a/commands/service_monitor.go +++ b/commands/service_monitor.go @@ -17,8 +17,10 @@ package commands import ( "context" + "errors" "fmt" "io" + "sync/atomic" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" @@ -27,87 +29,211 @@ import ( pluggableMonitor "github.com/arduino/arduino-cli/internal/arduino/monitor" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-properties-orderedmap" + "github.com/djherbis/buffer" + "github.com/djherbis/nio/v3" "github.com/sirupsen/logrus" + "google.golang.org/grpc/metadata" ) -// portProxy is an io.ReadWriteCloser that maps into the monitor port of the board -type portProxy struct { - rw io.ReadWriter - changeSettingsCB func(setting, value string) error - closeCB func() error +type monitorPipeServer struct { + ctx context.Context + req atomic.Pointer[rpc.MonitorPortOpenRequest] + in *nio.PipeReader + out *nio.PipeWriter } -func (p *portProxy) Read(buff []byte) (int, error) { - return p.rw.Read(buff) +func (s *monitorPipeServer) Send(resp *rpc.MonitorResponse) error { + if len(resp.GetRxData()) > 0 { + if _, err := s.out.Write(resp.GetRxData()); err != nil { + return err + } + } + return nil +} + +func (s *monitorPipeServer) Recv() (r *rpc.MonitorRequest, e error) { + if conf := s.req.Swap(nil); conf != nil { + return &rpc.MonitorRequest{Message: &rpc.MonitorRequest_OpenRequest{OpenRequest: conf}}, nil + } + buff := make([]byte, 4096) + n, err := s.in.Read(buff) + if err != nil { + return nil, err + } + return &rpc.MonitorRequest{Message: &rpc.MonitorRequest_TxData{TxData: buff[:n]}}, nil } -func (p *portProxy) Write(buff []byte) (int, error) { - return p.rw.Write(buff) +func (s *monitorPipeServer) Context() context.Context { + return s.ctx } -// Config sets the port configuration setting to the specified value -func (p *portProxy) Config(setting, value string) error { - return p.changeSettingsCB(setting, value) +func (s *monitorPipeServer) RecvMsg(m any) error { return nil } +func (s *monitorPipeServer) SendHeader(metadata.MD) error { return nil } +func (s *monitorPipeServer) SendMsg(m any) error { return nil } +func (s *monitorPipeServer) SetHeader(metadata.MD) error { return nil } +func (s *monitorPipeServer) SetTrailer(metadata.MD) {} + +type monitorPipeClient struct { + in *nio.PipeReader + out *nio.PipeWriter + close func() } -// Close the port -func (p *portProxy) Close() error { - return p.closeCB() +func (s *monitorPipeClient) Read(buff []byte) (n int, err error) { + return s.in.Read(buff) } -// Monitor opens a communication port. It returns a PortProxy to communicate with the port and a PortDescriptor -// that describes the available configuration settings. -func Monitor(ctx context.Context, req *rpc.MonitorPortOpenRequest) (*portProxy, *pluggableMonitor.PortDescriptor, error) { - pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) - if err != nil { - return nil, nil, err - } - defer release() +func (s *monitorPipeClient) Write(buff []byte) (n int, err error) { + return s.out.Write(buff) +} - m, boardSettings, err := findMonitorAndSettingsForProtocolAndBoard(pme, req.GetPort().GetProtocol(), req.GetFqbn()) +func (s *monitorPipeClient) Close() error { + s.in.Close() + s.out.Close() + s.close() + return nil +} + +// MonitorServerToReadWriteCloser creates a monitor server that proxies the data to a ReadWriteCloser. +// The server is returned along with the ReadWriteCloser that can be used to send and receive data +// to the server. The MonitorPortOpenRequest is used to configure the monitor. +func MonitorServerToReadWriteCloser(ctx context.Context, req *rpc.MonitorPortOpenRequest) (rpc.ArduinoCoreService_MonitorServer, io.ReadWriteCloser) { + server := &monitorPipeServer{} + client := &monitorPipeClient{} + server.req.Store(req) + server.ctx, client.close = context.WithCancel(ctx) + client.in, server.out = nio.Pipe(buffer.New(32 * 1024)) + server.in, client.out = nio.Pipe(buffer.New(32 * 1024)) + return server, client +} + +// Monitor opens a port monitor and streams data back and forth until the request is kept alive. +func (s *arduinoCoreServerImpl) Monitor(stream rpc.ArduinoCoreService_MonitorServer) error { + // The configuration must be sent on the first message + req, err := stream.Recv() if err != nil { - return nil, nil, err + return err } - if err := m.Run(); err != nil { - return nil, nil, &cmderrors.FailedMonitorError{Cause: err} + openReq := req.GetOpenRequest() + if openReq == nil { + return &cmderrors.InvalidInstanceError{} } - descriptor, err := m.Describe() + pme, release, err := instances.GetPackageManagerExplorer(openReq.GetInstance()) if err != nil { - m.Quit() - return nil, nil, &cmderrors.FailedMonitorError{Cause: err} + return err } - - // Apply user-requested settings - if portConfig := req.GetPortConfiguration(); portConfig != nil { + defer release() + monitor, boardSettings, err := findMonitorAndSettingsForProtocolAndBoard(pme, openReq.GetPort().GetProtocol(), openReq.GetFqbn()) + if err != nil { + return err + } + if err := monitor.Run(); err != nil { + return &cmderrors.FailedMonitorError{Cause: err} + } + if _, err := monitor.Describe(); err != nil { + monitor.Quit() + return &cmderrors.FailedMonitorError{Cause: err} + } + if portConfig := openReq.GetPortConfiguration(); portConfig != nil { for _, setting := range portConfig.GetSettings() { - boardSettings.Remove(setting.GetSettingId()) // Remove board settings overridden by the user - if err := m.Configure(setting.GetSettingId(), setting.GetValue()); err != nil { + boardSettings.Remove(setting.GetSettingId()) + if err := monitor.Configure(setting.GetSettingId(), setting.GetValue()); err != nil { logrus.Errorf("Could not set configuration %s=%s: %s", setting.GetSettingId(), setting.GetValue(), err) } } } - // Apply specific board settings for setting, value := range boardSettings.AsMap() { - m.Configure(setting, value) + monitor.Configure(setting, value) } - - monIO, err := m.Open(req.GetPort().GetAddress(), req.GetPort().GetProtocol()) + monitorIO, err := monitor.Open(openReq.GetPort().GetAddress(), openReq.GetPort().GetProtocol()) if err != nil { - m.Quit() - return nil, nil, &cmderrors.FailedMonitorError{Cause: err} - } - - logrus.Infof("Port %s successfully opened", req.GetPort().GetAddress()) - return &portProxy{ - rw: monIO, - changeSettingsCB: m.Configure, - closeCB: func() error { - m.Close() - return m.Quit() - }, - }, descriptor, nil + monitor.Quit() + return &cmderrors.FailedMonitorError{Cause: err} + } + logrus.Infof("Port %s successfully opened", openReq.GetPort().GetAddress()) + monitorClose := func() error { + monitor.Close() + return monitor.Quit() + } + + // Send a message with Success set to true to notify the caller of the port being now active + syncSend := NewSynchronizedSend(stream.Send) + _ = syncSend.Send(&rpc.MonitorResponse{Success: true}) + + ctx, cancel := context.WithCancel(stream.Context()) + gracefulCloseInitiated := &atomic.Bool{} + gracefuleCloseCtx, gracefulCloseCancel := context.WithCancel(context.Background()) + + // gRPC stream receiver (gRPC data -> monitor, config, close) + go func() { + defer cancel() + for { + msg, err := stream.Recv() + if errors.Is(err, io.EOF) { + return + } + if err != nil { + syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) + return + } + if conf := msg.GetUpdatedConfiguration(); conf != nil { + for _, c := range conf.GetSettings() { + if err := monitor.Configure(c.GetSettingId(), c.GetValue()); err != nil { + syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) + } + } + } + if closeMsg := msg.GetClose(); closeMsg { + gracefulCloseInitiated.Store(true) + if err := monitorClose(); err != nil { + logrus.WithError(err).Debug("Error closing monitor port") + } + gracefulCloseCancel() + } + tx := msg.GetTxData() + for len(tx) > 0 { + n, err := monitorIO.Write(tx) + if errors.Is(err, io.EOF) { + return + } + if err != nil { + syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) + return + } + tx = tx[n:] + } + } + }() + + // gRPC stream sender (monitor -> gRPC) + go func() { + defer cancel() // unlock the receiver + buff := make([]byte, 4096) + for { + n, err := monitorIO.Read(buff) + if errors.Is(err, io.EOF) { + break + } + if err != nil { + syncSend.Send(&rpc.MonitorResponse{Error: err.Error()}) + break + } + if err := syncSend.Send(&rpc.MonitorResponse{RxData: buff[:n]}); err != nil { + break + } + } + }() + + <-ctx.Done() + if gracefulCloseInitiated.Load() { + // Port closing has been initiated in the receiver + <-gracefuleCloseCtx.Done() + } else { + monitorClose() + } + return nil } func findMonitorAndSettingsForProtocolAndBoard(pme *packagemanager.Explorer, protocol, fqbn string) (*pluggableMonitor.PluggableMonitor, *properties.Map, error) { diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index b60805e36b5..94c495068c5 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -204,20 +204,6 @@ func runMonitorCmd( } } } - portProxy, _, err := commands.Monitor(context.Background(), &rpc.MonitorPortOpenRequest{ - Instance: inst, - Port: &rpc.Port{Address: portAddress, Protocol: portProtocol}, - Fqbn: fqbn, - PortConfiguration: configuration, - }) - if err != nil { - feedback.FatalError(err, feedback.ErrGeneric) - } - defer portProxy.Close() - - if !quiet { - feedback.Print(tr("Connected to %s! Press CTRL-C to exit.", portAddress)) - } ttyIn, ttyOut, err := feedback.InteractiveStreams() if err != nil { @@ -228,7 +214,7 @@ func runMonitorCmd( ttyOut = newTimeStampWriter(ttyOut) } - ctx, cancel := cleanup.InterruptableContext(context.Background()) + ctx, cancel := cleanup.InterruptableContext(ctx) if raw { if feedback.IsInteractive() { if err := feedback.SetRawModeStdin(); err != nil { @@ -246,6 +232,22 @@ func runMonitorCmd( ttyIn = io.TeeReader(ttyIn, ctrlCDetector) } + monitorServer, portProxy := commands.MonitorServerToReadWriteCloser(ctx, &rpc.MonitorPortOpenRequest{ + Instance: inst, + Port: &rpc.Port{Address: portAddress, Protocol: portProtocol}, + Fqbn: fqbn, + PortConfiguration: configuration, + }) + go func() { + if !quiet { + feedback.Print(tr("Connecting to %s. Press CTRL-C to exit.", portAddress)) + } + if err := srv.Monitor(monitorServer); err != nil { + feedback.FatalError(err, feedback.ErrGeneric) + } + portProxy.Close() + cancel() + }() go func() { _, err := io.Copy(ttyOut, portProxy) if err != nil && !errors.Is(err, io.EOF) { From 0e434f236743afb0599fd478785a46a0a2f9a7af Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 18 Mar 2024 11:05:25 +0100 Subject: [PATCH 18/56] Inlining methods in ArduinoCoreServiceImpl (part 9: Compile) --- commands/service.go | 35 -------- commands/service_compile.go | 120 +++++++++++++++++++--------- internal/arduino/builder/builder.go | 2 + internal/cli/compile/compile.go | 4 +- 4 files changed, 88 insertions(+), 73 deletions(-) diff --git a/commands/service.go b/commands/service.go index 2d32e1c368f..27efafc14d8 100644 --- a/commands/service.go +++ b/commands/service.go @@ -76,41 +76,6 @@ func (s *arduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc. return SetSketchDefaults(ctx, req) } -// Compile FIXMEDOC -func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.ArduinoCoreService_CompileServer) error { - syncSend := NewSynchronizedSend(stream.Send) - outStream := feedStreamTo(func(data []byte) { - syncSend.Send(&rpc.CompileResponse{ - Message: &rpc.CompileResponse_OutStream{OutStream: data}, - }) - }) - errStream := feedStreamTo(func(data []byte) { - syncSend.Send(&rpc.CompileResponse{ - Message: &rpc.CompileResponse_ErrStream{ErrStream: data}, - }) - }) - progressStream := func(p *rpc.TaskProgress) { - syncSend.Send(&rpc.CompileResponse{ - Message: &rpc.CompileResponse_Progress{Progress: p}, - }) - } - compileRes, compileErr := Compile(stream.Context(), req, outStream, errStream, progressStream) - outStream.Close() - errStream.Close() - var compileRespSendErr error - if compileRes != nil { - compileRespSendErr = syncSend.Send(&rpc.CompileResponse{ - Message: &rpc.CompileResponse_Result{ - Result: compileRes, - }, - }) - } - if compileErr != nil { - return compileErr - } - return compileRespSendErr -} - // PlatformInstall FIXMEDOC func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error { syncSend := NewSynchronizedSend(stream.Send) diff --git a/commands/service_compile.go b/commands/service_compile.go index 94157244cba..512ca766249 100644 --- a/commands/service_compile.go +++ b/commands/service_compile.go @@ -38,8 +38,34 @@ import ( "github.com/sirupsen/logrus" ) -// Compile FIXMEDOC -func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream io.Writer, progressCB rpc.TaskProgressCB) (r *rpc.BuilderResult, e error) { +// CompilerServerToStreams creates a gRPC CompileServer that sends the responses to the provided streams. +// The returned callback function can be used to retrieve the builder result after the compilation is done. +func CompilerServerToStreams(ctx context.Context, stdOut, stderr io.Writer) (server rpc.ArduinoCoreService_CompileServer, resultCB func() *rpc.BuilderResult) { + var builderResult *rpc.BuilderResult + stream := streamResponseToCallback(ctx, func(resp *rpc.CompileResponse) error { + if out := resp.GetOutStream(); len(out) > 0 { + if _, err := stdOut.Write(out); err != nil { + return err + } + } + if err := resp.GetErrStream(); len(err) > 0 { + if _, err := stderr.Write(err); err != nil { + return err + } + } + if result := resp.GetResult(); result != nil { + builderResult = result + } + return nil + }) + return stream, func() *rpc.BuilderResult { return builderResult } +} + +// Compile performs a compilation of a sketch. +func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.ArduinoCoreService_CompileServer) error { + ctx := stream.Context() + syncSend := NewSynchronizedSend(stream.Send) + exportBinaries := configuration.Settings.GetBool("sketch.always_export_binaries") if e := req.ExportBinaries; e != nil { exportBinaries = *e @@ -47,27 +73,27 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { - return nil, err + return err } defer release() if pme.Dirty() { - return nil, &cmderrors.InstanceNeedsReinitialization{} + return &cmderrors.InstanceNeedsReinitialization{} } lm, err := instances.GetLibraryManager(req.GetInstance()) if err != nil { - return nil, err + return err } logrus.Tracef("Compile %s for %s started", req.GetSketchPath(), req.GetFqbn()) if req.GetSketchPath() == "" { - return nil, &cmderrors.MissingSketchPathError{} + return &cmderrors.MissingSketchPathError{} } sketchPath := paths.New(req.GetSketchPath()) sk, err := sketch.New(sketchPath) if err != nil { - return nil, &cmderrors.CantOpenSketchError{Cause: err} + return &cmderrors.CantOpenSketchError{Cause: err} } fqbnIn := req.GetFqbn() @@ -79,25 +105,30 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream } } if fqbnIn == "" { - return nil, &cmderrors.MissingFQBNError{} + return &cmderrors.MissingFQBNError{} } fqbn, err := cores.ParseFQBN(fqbnIn) if err != nil { - return nil, &cmderrors.InvalidFQBNError{Cause: err} + return &cmderrors.InvalidFQBNError{Cause: err} } _, targetPlatform, targetBoard, boardBuildProperties, buildPlatform, err := pme.ResolveFQBN(fqbn) if err != nil { if targetPlatform == nil { - return nil, &cmderrors.PlatformNotFoundError{ + return &cmderrors.PlatformNotFoundError{ Platform: fmt.Sprintf("%s:%s", fqbn.Package, fqbn.PlatformArch), Cause: fmt.Errorf(tr("platform not installed")), } } - return nil, &cmderrors.InvalidFQBNError{Cause: err} + return &cmderrors.InvalidFQBNError{Cause: err} } - r = &rpc.BuilderResult{} + r := &rpc.BuilderResult{} + defer func() { + syncSend.Send(&rpc.CompileResponse{ + Message: &rpc.CompileResponse_Result{Result: r}, + }) + }() r.BoardPlatform = targetPlatform.ToRPCPlatformReference() r.BuildPlatform = buildPlatform.ToRPCPlatformReference() @@ -120,7 +151,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream encryptProp := boardBuildProperties.ContainsKey("build.keys.encrypt_key") // we verify that all the properties for the secure boot keys are defined or none of them is defined. if !(keychainProp == signProp && signProp == encryptProp) { - return nil, fmt.Errorf(tr("Firmware encryption/signing requires all the following properties to be defined: %s", "build.keys.keychain, build.keys.sign_key, build.keys.encrypt_key")) + return fmt.Errorf(tr("Firmware encryption/signing requires all the following properties to be defined: %s", "build.keys.keychain, build.keys.sign_key, build.keys.encrypt_key")) } // Generate or retrieve build path @@ -129,7 +160,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream buildPath = paths.New(req.GetBuildPath()).Canonical() if in, _ := buildPath.IsInsideDir(sk.FullPath); in && buildPath.IsDir() { if sk.AdditionalFiles, err = removeBuildFromSketchFiles(sk.AdditionalFiles, buildPath); err != nil { - return nil, err + return err } } } @@ -137,7 +168,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream buildPath = sk.DefaultBuildPath() } if err = buildPath.MkdirAll(); err != nil { - return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build directory"), Cause: err} + return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build directory"), Cause: err} } buildcache.New(buildPath.Parent()).GetOrCreate(buildPath.Base()) // cache is purged after compilation to not remove entries that might be required @@ -149,16 +180,16 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream } else { buildCachePath, err := paths.New(req.GetBuildCachePath()).Abs() if err != nil { - return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err} + return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err} } if err := buildCachePath.MkdirAll(); err != nil { - return nil, &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err} + return &cmderrors.PermissionDeniedError{Message: tr("Cannot create build cache directory"), Cause: err} } coreBuildCachePath = buildCachePath.Join("core") } if _, err := pme.FindToolsRequiredForBuild(targetPlatform, buildPlatform); err != nil { - return nil, err + return err } actualPlatform := buildPlatform @@ -170,7 +201,25 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream libsManager = lm } + outStream := feedStreamTo(func(data []byte) { + syncSend.Send(&rpc.CompileResponse{ + Message: &rpc.CompileResponse_OutStream{OutStream: data}, + }) + }) + defer outStream.Close() + errStream := feedStreamTo(func(data []byte) { + syncSend.Send(&rpc.CompileResponse{ + Message: &rpc.CompileResponse_ErrStream{ErrStream: data}, + }) + }) + defer errStream.Close() + progressCB := func(p *rpc.TaskProgress) { + syncSend.Send(&rpc.CompileResponse{ + Message: &rpc.CompileResponse_Progress{Progress: p}, + }) + } sketchBuilder, err := builder.NewBuilder( + ctx, sk, boardBuildProperties, buildPath, @@ -195,14 +244,14 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream ) if err != nil { if strings.Contains(err.Error(), "invalid build properties") { - return nil, &cmderrors.InvalidArgumentError{Message: tr("Invalid build properties"), Cause: err} + return &cmderrors.InvalidArgumentError{Message: tr("Invalid build properties"), Cause: err} } if errors.Is(err, builder.ErrSketchCannotBeLocatedInBuildPath) { - return r, &cmderrors.CompileFailedError{ + return &cmderrors.CompileFailedError{ Message: tr("Sketch cannot be located in build path. Please specify a different build path"), } } - return r, &cmderrors.CompileFailedError{Message: err.Error()} + return &cmderrors.CompileFailedError{Message: err.Error()} } defer func() { @@ -232,7 +281,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream // Just get build properties and exit if req.GetShowProperties() { - return r, nil + return nil } if req.GetPreprocess() { @@ -240,10 +289,10 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream preprocessedSketch, err := sketchBuilder.Preprocess() if err != nil { err = &cmderrors.CompileFailedError{Message: err.Error()} - return r, err + return err } _, err = outStream.Write(preprocessedSketch) - return r, err + return err } defer func() { @@ -285,7 +334,7 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream } if err := sketchBuilder.Build(); err != nil { - return r, &cmderrors.CompileFailedError{Message: err.Error()} + return &cmderrors.CompileFailedError{Message: err.Error()} } // If the export directory is set we assume you want to export the binaries @@ -297,9 +346,8 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream exportBinaries = false } if exportBinaries { - err := sketchBuilder.RunRecipe("recipe.hooks.savehex.presavehex", ".pattern", false) - if err != nil { - return r, err + if err := sketchBuilder.RunRecipe("recipe.hooks.savehex.presavehex", ".pattern", false); err != nil { + return err } exportPath := paths.New(req.GetExportDir()) @@ -313,38 +361,36 @@ func Compile(ctx context.Context, req *rpc.CompileRequest, outStream, errStream if !buildPath.EqualsTo(exportPath) { logrus.WithField("path", exportPath).Trace("Saving sketch to export path.") if err := exportPath.MkdirAll(); err != nil { - return r, &cmderrors.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err} + return &cmderrors.PermissionDeniedError{Message: tr("Error creating output dir"), Cause: err} } baseName, ok := sketchBuilder.GetBuildProperties().GetOk("build.project_name") // == "sketch.ino" if !ok { - return r, &cmderrors.MissingPlatformPropertyError{Property: "build.project_name"} + return &cmderrors.MissingPlatformPropertyError{Property: "build.project_name"} } buildFiles, err := sketchBuilder.GetBuildPath().ReadDir() if err != nil { - return r, &cmderrors.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err} + return &cmderrors.PermissionDeniedError{Message: tr("Error reading build directory"), Cause: err} } buildFiles.FilterPrefix(baseName) for _, buildFile := range buildFiles { exportedFile := exportPath.Join(buildFile.Base()) logrus.WithField("src", buildFile).WithField("dest", exportedFile).Trace("Copying artifact.") if err = buildFile.CopyTo(exportedFile); err != nil { - return r, &cmderrors.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err} + return &cmderrors.PermissionDeniedError{Message: tr("Error copying output file %s", buildFile), Cause: err} } } } - err = sketchBuilder.RunRecipe("recipe.hooks.savehex.postsavehex", ".pattern", false) - if err != nil { - return r, err + if err = sketchBuilder.RunRecipe("recipe.hooks.savehex.postsavehex", ".pattern", false); err != nil { + return err } } r.ExecutableSectionsSize = sketchBuilder.ExecutableSectionsSize().ToRPCExecutableSectionSizeArray() logrus.Tracef("Compile %s for %s successful", sk.Name, fqbnIn) - - return r, nil + return nil } // maybePurgeBuildCache runs the build files cache purge if the policy conditions are met. diff --git a/internal/arduino/builder/builder.go b/internal/arduino/builder/builder.go index 303caaa2063..ad6af436128 100644 --- a/internal/arduino/builder/builder.go +++ b/internal/arduino/builder/builder.go @@ -16,6 +16,7 @@ package builder import ( + "context" "errors" "fmt" "io" @@ -111,6 +112,7 @@ type buildArtifacts struct { // NewBuilder creates a sketch Builder. func NewBuilder( + ctx context.Context, sk *sketch.Sketch, boardBuildProperties *properties.Map, buildPath *paths.Path, diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 2a628a752f9..3ed3b5ca2a8 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -246,7 +246,9 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer DoNotExpandBuildProperties: showProperties == arguments.ShowPropertiesUnexpanded, Jobs: jobs, } - builderRes, compileError := commands.Compile(context.Background(), compileRequest, stdOut, stdErr, nil) + server, builderResCB := commands.CompilerServerToStreams(ctx, stdOut, stdErr) + compileError := srv.Compile(compileRequest, server) + builderRes := builderResCB() var uploadRes *rpc.UploadResult if compileError == nil && uploadAfterCompile { From 12cf52e7f67ca4a4945217208c1c6fa84e21890e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 18 Mar 2024 12:11:12 +0100 Subject: [PATCH 19/56] Inlining methods in ArduinoCoreServiceImpl (part 10: PlatformInstall, PlatformDownload, PlatformUninstall, PlatformUpgrade, PlatformSearch) --- commands/service.go | 59 ------------------------ commands/service_platform_download.go | 34 ++++++++++---- commands/service_platform_install.go | 38 ++++++++++++--- commands/service_platform_search.go | 3 +- commands/service_platform_search_test.go | 14 +++--- commands/service_platform_uninstall.go | 31 +++++++++---- commands/service_platform_upgrade.go | 50 +++++++++++++++----- internal/cli/arguments/completion.go | 4 +- internal/cli/arguments/reference.go | 3 +- internal/cli/compile/compile.go | 2 +- internal/cli/core/download.go | 4 +- internal/cli/core/install.go | 4 +- internal/cli/core/list.go | 11 ++--- internal/cli/core/search.go | 2 +- internal/cli/core/uninstall.go | 7 +-- internal/cli/core/upgrade.go | 15 +++--- internal/cli/outdated/outdated.go | 6 +-- internal/cli/update/update.go | 2 +- internal/cli/upload/upload.go | 2 +- 19 files changed, 159 insertions(+), 132 deletions(-) diff --git a/commands/service.go b/commands/service.go index 27efafc14d8..5ad16c8a0e4 100644 --- a/commands/service.go +++ b/commands/service.go @@ -76,65 +76,6 @@ func (s *arduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc. return SetSketchDefaults(ctx, req) } -// PlatformInstall FIXMEDOC -func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error { - syncSend := NewSynchronizedSend(stream.Send) - resp, err := PlatformInstall( - stream.Context(), s, req, - func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformInstallResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) }, - ) - if err != nil { - return err - } - return syncSend.Send(resp) -} - -// PlatformDownload FIXMEDOC -func (s *arduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadRequest, stream rpc.ArduinoCoreService_PlatformDownloadServer) error { - syncSend := NewSynchronizedSend(stream.Send) - resp, err := PlatformDownload( - stream.Context(), req, - func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformDownloadResponse{Progress: p}) }, - ) - if err != nil { - return err - } - return syncSend.Send(resp) -} - -// PlatformUninstall FIXMEDOC -func (s *arduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequest, stream rpc.ArduinoCoreService_PlatformUninstallServer) error { - syncSend := NewSynchronizedSend(stream.Send) - resp, err := PlatformUninstall( - stream.Context(), s, req, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) }, - ) - if err != nil { - return err - } - return syncSend.Send(resp) -} - -// PlatformUpgrade FIXMEDOC -func (s *arduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, stream rpc.ArduinoCoreService_PlatformUpgradeServer) error { - syncSend := NewSynchronizedSend(stream.Send) - resp, err := PlatformUpgrade( - stream.Context(), s, req, - func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{TaskProgress: p}) }, - ) - if err2 := syncSend.Send(resp); err2 != nil { - return err2 - } - return err -} - -// PlatformSearch FIXMEDOC -func (s *arduinoCoreServerImpl) PlatformSearch(ctx context.Context, req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { - return PlatformSearch(req) -} - // Upload FIXMEDOC func (s *arduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.ArduinoCoreService_UploadServer) error { syncSend := NewSynchronizedSend(stream.Send) diff --git a/commands/service_platform_download.go b/commands/service_platform_download.go index a8039af55b9..a4227fa30b9 100644 --- a/commands/service_platform_download.go +++ b/commands/service_platform_download.go @@ -27,17 +27,30 @@ import ( var tr = i18n.Tr -// PlatformDownload FIXMEDOC -func PlatformDownload(ctx context.Context, req *rpc.PlatformDownloadRequest, downloadCB rpc.DownloadProgressCB) (*rpc.PlatformDownloadResponse, error) { +// PlatformDownloadStreamResponseToCallbackFunction returns a gRPC stream to be used in PlatformDownload that sends +// all responses to the callback function. +func PlatformDownloadStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB) rpc.ArduinoCoreService_PlatformDownloadServer { + return streamResponseToCallback(ctx, func(r *rpc.PlatformDownloadResponse) error { + if r.GetProgress() != nil { + downloadCB(r.GetProgress()) + } + return nil + }) +} + +// PlatformDownload downloads a platform package +func (s *arduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadRequest, stream rpc.ArduinoCoreService_PlatformDownloadServer) error { + syncSend := NewSynchronizedSend(stream.Send) + pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { - return nil, err + return err } defer release() version, err := ParseVersion(req.GetVersion()) if err != nil { - return nil, &cmderrors.InvalidVersionError{Cause: err} + return &cmderrors.InvalidVersionError{Cause: err} } ref := &packagemanager.PlatformReference{ @@ -47,18 +60,23 @@ func PlatformDownload(ctx context.Context, req *rpc.PlatformDownloadRequest, dow } platform, tools, err := pme.FindPlatformReleaseDependencies(ref) if err != nil { - return nil, &cmderrors.PlatformNotFoundError{Platform: ref.String(), Cause: err} + return &cmderrors.PlatformNotFoundError{Platform: ref.String(), Cause: err} } + downloadCB := func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformDownloadResponse{Progress: p}) } + + // TODO: pass context + // ctx := stream.Context() if err := pme.DownloadPlatformRelease(platform, nil, downloadCB); err != nil { - return nil, err + return err } for _, tool := range tools { + // TODO: pass context if err := pme.DownloadToolRelease(tool, nil, downloadCB); err != nil { - return nil, err + return err } } - return &rpc.PlatformDownloadResponse{}, nil + return syncSend.Send(&rpc.PlatformDownloadResponse{}) } diff --git a/commands/service_platform_install.go b/commands/service_platform_install.go index 94c64c07921..06c8891fcc3 100644 --- a/commands/service_platform_install.go +++ b/commands/service_platform_install.go @@ -25,8 +25,27 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) -// PlatformInstall FIXMEDOC -func PlatformInstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.PlatformInstallRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) (*rpc.PlatformInstallResponse, error) { +// UpdateIndexStreamResponseToCallbackFunction returns a gRPC stream to be used in PlatformInstall that sends +// all responses to the callback function. +func PlatformInstallStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) rpc.ArduinoCoreService_PlatformInstallServer { + return streamResponseToCallback(ctx, func(r *rpc.PlatformInstallResponse) error { + if r.GetProgress() != nil { + downloadCB(r.GetProgress()) + } + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + return nil + }) +} + +// PlatformInstall installs a platform package +func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, stream rpc.ArduinoCoreService_PlatformInstallServer) error { + ctx := stream.Context() + syncSend := NewSynchronizedSend(stream.Send) + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformInstallResponse{TaskProgress: p}) } + downloadCB := func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformInstallResponse{Progress: p}) } + install := func() error { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { @@ -63,6 +82,7 @@ func PlatformInstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req } } + // TODO: Pass context if err := pme.DownloadAndInstallPlatformAndTools(platformRelease, tools, downloadCB, taskCB, req.GetSkipPostInstall(), req.GetSkipPreUninstall()); err != nil { return err } @@ -71,12 +91,16 @@ func PlatformInstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req } if err := install(); err != nil { - return nil, err + return err } - stream := InitStreamResponseToCallbackFunction(ctx, nil) - if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, stream); err != nil { - return nil, err + err := s.Init( + &rpc.InitRequest{Instance: req.GetInstance()}, + InitStreamResponseToCallbackFunction(ctx, nil), + ) + if err != nil { + return err } - return &rpc.PlatformInstallResponse{}, nil + + return syncSend.Send(&rpc.PlatformInstallResponse{}) } diff --git a/commands/service_platform_search.go b/commands/service_platform_search.go index 99f66ffa39a..dfa0d33ffd8 100644 --- a/commands/service_platform_search.go +++ b/commands/service_platform_search.go @@ -16,6 +16,7 @@ package commands import ( + "context" "regexp" "sort" "strings" @@ -27,7 +28,7 @@ import ( ) // PlatformSearch FIXMEDOC -func PlatformSearch(req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { +func (s *arduinoCoreServerImpl) PlatformSearch(_ context.Context, req *rpc.PlatformSearchRequest) (*rpc.PlatformSearchResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/commands/service_platform_search_test.go b/commands/service_platform_search_test.go index 315a39c0fbb..63dc02c5265 100644 --- a/commands/service_platform_search_test.go +++ b/commands/service_platform_search_test.go @@ -50,7 +50,7 @@ func TestPlatformSearch(t *testing.T) { require.NoError(t, err) t.Run("SearchAllVersions", func(t *testing.T) { - res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "retrokit", }) @@ -91,7 +91,7 @@ func TestPlatformSearch(t *testing.T) { }) t.Run("SearchThePackageMaintainer", func(t *testing.T) { - res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "Retrokits (www.retrokits.com)", }) @@ -131,7 +131,7 @@ func TestPlatformSearch(t *testing.T) { }) t.Run("SearchPackageName", func(t *testing.T) { - res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "Retrokits-RK002", }) @@ -171,7 +171,7 @@ func TestPlatformSearch(t *testing.T) { }) t.Run("SearchPlatformName", func(t *testing.T) { - res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "rk002", }) @@ -211,7 +211,7 @@ func TestPlatformSearch(t *testing.T) { }) t.Run("SearchBoardName", func(t *testing.T) { - res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "Yún", }) @@ -269,7 +269,7 @@ func TestPlatformSearch(t *testing.T) { }) t.Run("SearchBoardName2", func(t *testing.T) { - res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "yun", }) @@ -350,7 +350,7 @@ func TestPlatformSearchSorting(t *testing.T) { err = srv.Init(&rpc.InitRequest{Instance: inst}, InitStreamResponseToCallbackFunction(ctx, nil)) require.NoError(t, err) - res, stat := PlatformSearch(&rpc.PlatformSearchRequest{ + res, stat := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "", }) diff --git a/commands/service_platform_uninstall.go b/commands/service_platform_uninstall.go index b6679b891cb..07a32988a6a 100644 --- a/commands/service_platform_uninstall.go +++ b/commands/service_platform_uninstall.go @@ -24,19 +24,33 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) -// PlatformUninstall FIXMEDOC -func PlatformUninstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgressCB) (*rpc.PlatformUninstallResponse, error) { - if err := platformUninstall(req, taskCB); err != nil { - return nil, err +// PlatformUninstallStreamResponseToCallbackFunction returns a gRPC stream to be used in PlatformUninstall that sends +// all responses to the callback function. +func PlatformUninstallStreamResponseToCallbackFunction(ctx context.Context, taskCB rpc.TaskProgressCB) rpc.ArduinoCoreService_PlatformUninstallServer { + return streamResponseToCallback(ctx, func(r *rpc.PlatformUninstallResponse) error { + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + return nil + }) +} + +// PlatformUninstall uninstalls a platform package +func (s *arduinoCoreServerImpl) PlatformUninstall(req *rpc.PlatformUninstallRequest, stream rpc.ArduinoCoreService_PlatformUninstallServer) error { + syncSend := NewSynchronizedSend(stream.Send) + ctx := stream.Context() + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUninstallResponse{TaskProgress: p}) } + if err := platformUninstall(ctx, req, taskCB); err != nil { + return err } - if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, InitStreamResponseToCallbackFunction(ctx, nil)); err != nil { - return nil, err + if err := s.Init(&rpc.InitRequest{Instance: req.GetInstance()}, InitStreamResponseToCallbackFunction(ctx, nil)); err != nil { + return err } - return &rpc.PlatformUninstallResponse{}, nil + return syncSend.Send(&rpc.PlatformUninstallResponse{}) } // platformUninstall is the implementation of platform unistaller -func platformUninstall(req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgressCB) error { +func platformUninstall(_ context.Context, req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgressCB) error { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return &cmderrors.InvalidInstanceError{} @@ -64,6 +78,7 @@ func platformUninstall(req *rpc.PlatformUninstallRequest, taskCB rpc.TaskProgres return &cmderrors.NotFoundError{Message: tr("Can't find dependencies for platform %s", ref), Cause: err} } + // TODO: pass context if err := pme.UninstallPlatform(platform, taskCB, req.GetSkipPreUninstall()); err != nil { return err } diff --git a/commands/service_platform_upgrade.go b/commands/service_platform_upgrade.go index 25d7de2fc79..a9b65fe5bfa 100644 --- a/commands/service_platform_upgrade.go +++ b/commands/service_platform_upgrade.go @@ -24,8 +24,34 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) -// PlatformUpgrade FIXMEDOC -func PlatformUpgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.PlatformUpgradeRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) (*rpc.PlatformUpgradeResponse, error) { +// PlatformUpgradeStreamResponseToCallbackFunction returns a gRPC stream to be used in PlatformUpgrade that sends +// all responses to the callback function. +func PlatformUpgradeStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) (rpc.ArduinoCoreService_PlatformUpgradeServer, func() *rpc.Platform) { + var resp *rpc.Platform + return streamResponseToCallback(ctx, func(r *rpc.PlatformUpgradeResponse) error { + // TODO: use oneof in protoc files? + if r.GetProgress() != nil { + downloadCB(r.GetProgress()) + } + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + if r.GetPlatform() != nil { + resp = r.GetPlatform() + } + return nil + }), func() *rpc.Platform { + return resp + } +} + +// PlatformUpgrade upgrades a platform package +func (s *arduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, stream rpc.ArduinoCoreService_PlatformUpgradeServer) error { + syncSend := NewSynchronizedSend(stream.Send) + ctx := stream.Context() + downloadCB := func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{Progress: p}) } + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.PlatformUpgradeResponse{TaskProgress: p}) } + upgrade := func() (*cores.PlatformRelease, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { @@ -46,20 +72,22 @@ func PlatformUpgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req return platform, nil } - var rpcPlatform *rpc.Platform platformRelease, err := upgrade() if platformRelease != nil { - rpcPlatform = &rpc.Platform{ - Metadata: PlatformToRPCPlatformMetadata(platformRelease.Platform), - Release: PlatformReleaseToRPC(platformRelease), - } + syncSend.Send(&rpc.PlatformUpgradeResponse{ + Platform: &rpc.Platform{ + Metadata: PlatformToRPCPlatformMetadata(platformRelease.Platform), + Release: PlatformReleaseToRPC(platformRelease), + }, + }) } if err != nil { - return &rpc.PlatformUpgradeResponse{Platform: rpcPlatform}, err + return err } - if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, InitStreamResponseToCallbackFunction(ctx, nil)); err != nil { - return nil, err + + if err := s.Init(&rpc.InitRequest{Instance: req.GetInstance()}, InitStreamResponseToCallbackFunction(ctx, nil)); err != nil { + return err } - return &rpc.PlatformUpgradeResponse{Platform: rpcPlatform}, nil + return nil } diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index f5446d3e4ed..d27e68005ae 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -81,7 +81,7 @@ func GetInstalledProgrammers(ctx context.Context, srv rpc.ArduinoCoreServiceServ func GetUninstallableCores(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { inst := instance.CreateAndInit(ctx, srv) - platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, _ := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, ManuallyInstalled: true, }) @@ -102,7 +102,7 @@ func GetUninstallableCores(ctx context.Context, srv rpc.ArduinoCoreServiceServer func GetInstallableCores(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { inst := instance.CreateAndInit(ctx, srv) - platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, _ := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: "", }) diff --git a/internal/cli/arguments/reference.go b/internal/cli/arguments/reference.go index 84ad12744fb..613a16912fa 100644 --- a/internal/cli/arguments/reference.go +++ b/internal/cli/arguments/reference.go @@ -20,7 +20,6 @@ import ( "fmt" "strings" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -97,7 +96,7 @@ func ParseReference(ctx context.Context, srv rpc.ArduinoCoreServiceServer, arg s // Now that we have the required informations in `ret` we can // try to use core.PlatformList to optimize what the user typed // (by replacing the PackageName and Architecture in ret with the content of core.GetPlatform()) - platforms, _ := commands.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, _ := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: instance.CreateAndInit(ctx, srv), }) foundPlatforms := []string{} diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 3ed3b5ca2a8..1a72719dac9 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -386,7 +386,7 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer if profileArg.String() == "" { res.Error += fmt.Sprintln() - if platform, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ + if platform, err := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: platformErr.Platform, }); err != nil { diff --git a/internal/cli/core/download.go b/internal/cli/core/download.go index 4fdb11815e3..790945fa3c7 100644 --- a/internal/cli/core/download.go +++ b/internal/cli/core/download.go @@ -66,8 +66,8 @@ func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { Architecture: platformRef.Architecture, Version: platformRef.Version, } - _, err := commands.PlatformDownload(context.Background(), platformDownloadreq, feedback.ProgressBar()) - if err != nil { + stream := commands.PlatformDownloadStreamResponseToCallbackFunction(ctx, feedback.ProgressBar()) + if err := srv.PlatformDownload(platformDownloadreq, stream); err != nil { feedback.Fatal(tr("Error downloading %[1]s: %[2]v", args[i], err), feedback.ErrNetwork) } } diff --git a/internal/cli/core/install.go b/internal/cli/core/install.go index a6f1b7a35b3..18dfe910d51 100644 --- a/internal/cli/core/install.go +++ b/internal/cli/core/install.go @@ -76,8 +76,8 @@ func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, scriptFl NoOverwrite: noOverwrite, SkipPreUninstall: scriptFlags.DetectSkipPreUninstallValue(), } - _, err := commands.PlatformInstall(ctx, srv, platformInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) - if err != nil { + stream := commands.PlatformInstallStreamResponseToCallbackFunction(ctx, feedback.ProgressBar(), feedback.TaskProgress()) + if err := srv.PlatformInstall(platformInstallRequest, stream); err != nil { feedback.Fatal(tr("Error during install: %v", err), feedback.ErrGeneric) } } diff --git a/internal/cli/core/list.go b/internal/cli/core/list.go index 71d7a15601e..ec926240fea 100644 --- a/internal/cli/core/list.go +++ b/internal/cli/core/list.go @@ -19,7 +19,6 @@ import ( "context" "os" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -51,18 +50,18 @@ func runListCommand(srv rpc.ArduinoCoreServiceServer, all bool, updatableOnly bo ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli core list`") - List(inst, all, updatableOnly) + List(ctx, srv, inst, all, updatableOnly) } // List gets and prints a list of installed platforms. -func List(inst *rpc.Instance, all bool, updatableOnly bool) { - platforms := GetList(inst, all, updatableOnly) +func List(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.Instance, all bool, updatableOnly bool) { + platforms := GetList(ctx, srv, inst, all, updatableOnly) feedback.PrintResult(newCoreListResult(platforms, updatableOnly)) } // GetList returns a list of installed platforms. -func GetList(inst *rpc.Instance, all bool, updatableOnly bool) []*rpc.PlatformSummary { - platforms, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ +func GetList(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.Instance, all bool, updatableOnly bool) []*rpc.PlatformSummary { + platforms, err := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, ManuallyInstalled: true, }) diff --git a/internal/cli/core/search.go b/internal/cli/core/search.go index 096ef44e500..6ec72e4246f 100644 --- a/internal/cli/core/search.go +++ b/internal/cli/core/search.go @@ -74,7 +74,7 @@ func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, allVersio arguments := strings.ToLower(strings.Join(args, " ")) logrus.Infof("Executing `arduino-cli core search` with args: '%s'", arguments) - resp, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ + resp, err := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: arguments, }) diff --git a/internal/cli/core/uninstall.go b/internal/cli/core/uninstall.go index 6c8e7526211..e06f630bf31 100644 --- a/internal/cli/core/uninstall.go +++ b/internal/cli/core/uninstall.go @@ -64,13 +64,14 @@ func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, preUni } } for _, platformRef := range platformsRefs { - _, err := commands.PlatformUninstall(ctx, srv, &rpc.PlatformUninstallRequest{ + req := &rpc.PlatformUninstallRequest{ Instance: inst, PlatformPackage: platformRef.PackageName, Architecture: platformRef.Architecture, SkipPreUninstall: preUninstallFlags.DetectSkipPreUninstallValue(), - }, feedback.NewTaskProgressCB()) - if err != nil { + } + stream := commands.PlatformUninstallStreamResponseToCallbackFunction(ctx, feedback.NewTaskProgressCB()) + if err := srv.PlatformUninstall(req, stream); err != nil { feedback.Fatal(tr("Error during uninstall: %v", err), feedback.ErrGeneric) } } diff --git a/internal/cli/core/upgrade.go b/internal/cli/core/upgrade.go index 131fe713ede..3d831d0a8db 100644 --- a/internal/cli/core/upgrade.go +++ b/internal/cli/core/upgrade.go @@ -61,7 +61,7 @@ func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, args []string, skipPost func Upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.Instance, args []string, skipPostInstall bool, skipPreUninstall bool) { // if no platform was passed, upgrade allthethings if len(args) == 0 { - platforms, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ + platforms, err := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, }) if err != nil { @@ -93,12 +93,12 @@ func Upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.In } } - warningMissingIndex := func(response *rpc.PlatformUpgradeResponse) { - if response == nil || response.GetPlatform() == nil { + warningMissingIndex := func(platform *rpc.Platform) { + if platform == nil { return } - if !response.GetPlatform().GetMetadata().GetIndexed() { - feedback.Warning(tr("missing package index for %s, future updates cannot be guaranteed", response.GetPlatform().GetMetadata().GetId())) + if !platform.GetMetadata().GetIndexed() { + feedback.Warning(tr("missing package index for %s, future updates cannot be guaranteed", platform.GetMetadata().GetId())) } } @@ -123,8 +123,9 @@ func Upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.In SkipPostInstall: skipPostInstall, SkipPreUninstall: skipPreUninstall, } - response, err := commands.PlatformUpgrade(ctx, srv, r, feedback.ProgressBar(), feedback.TaskProgress()) - warningMissingIndex(response) + stream, respCB := commands.PlatformUpgradeStreamResponseToCallbackFunction(ctx, feedback.ProgressBar(), feedback.TaskProgress()) + err := srv.PlatformUpgrade(r, stream) + warningMissingIndex(respCB()) if err != nil { var alreadyAtLatestVersionErr *cmderrors.PlatformAlreadyAtTheLatestVersionError if errors.As(err, &alreadyAtLatestVersionErr) { diff --git a/internal/cli/outdated/outdated.go b/internal/cli/outdated/outdated.go index 7ec59e81e57..7a105dbfa9b 100644 --- a/internal/cli/outdated/outdated.go +++ b/internal/cli/outdated/outdated.go @@ -56,13 +56,13 @@ func runOutdatedCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli outdated`") ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) - Outdated(inst) + Outdated(ctx, srv, inst) } // Outdated prints a list of outdated platforms and libraries -func Outdated(inst *rpc.Instance) { +func Outdated(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.Instance) { feedback.PrintResult( - newOutdatedResult(core.GetList(inst, false, true), lib.GetList(inst, []string{}, false, true)), + newOutdatedResult(core.GetList(ctx, srv, inst, false, true), lib.GetList(inst, []string{}, false, true)), ) } diff --git a/internal/cli/update/update.go b/internal/cli/update/update.go index 64ea2b77562..944a027fc5e 100644 --- a/internal/cli/update/update.go +++ b/internal/cli/update/update.go @@ -57,6 +57,6 @@ func runUpdateCommand(srv rpc.ArduinoCoreServiceServer, showOutdated bool) { core.UpdateIndex(ctx, srv, inst) instance.Init(ctx, srv, inst) if showOutdated { - outdated.Outdated(inst) + outdated.Outdated(ctx, srv, inst) } } diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 97bd50c5af8..ed49145b98c 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -135,7 +135,7 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie } msg += "\n" - if platform, err := commands.PlatformSearch(&rpc.PlatformSearchRequest{ + if platform, err := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{ Instance: inst, SearchArgs: platformErr.Platform, }); err != nil { From cfe4b272598bafbc4829f0a02e9dac0c7bd141df Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 18 Mar 2024 13:11:24 +0100 Subject: [PATCH 20/56] Inlining methods in ArduinoCoreServiceImpl (part 11: LibraryDownload, LibraryInstall, LibraryUpgrade, LibraryUninstall, LibraryUpgradeAll, LibraryResolveDependencies, LibrarySearch, LibraryList, ZipLibraryInstall, GitLibraryInstall) --- commands/service.go | 83 ------------------------ commands/service_library_download.go | 40 +++++++----- commands/service_library_install.go | 64 ++++++++++++++++-- commands/service_library_list.go | 2 +- commands/service_library_resolve_deps.go | 2 +- commands/service_library_search.go | 2 +- commands/service_library_uninstall.go | 20 +++++- commands/service_library_upgrade.go | 58 ++++++++++++++--- internal/cli/arguments/completion.go | 4 +- internal/cli/lib/args.go | 9 ++- internal/cli/lib/check_deps.go | 5 +- internal/cli/lib/download.go | 6 +- internal/cli/lib/examples.go | 3 +- internal/cli/lib/install.go | 20 +++--- internal/cli/lib/list.go | 16 ++--- internal/cli/lib/search.go | 2 +- internal/cli/lib/uninstall.go | 9 +-- internal/cli/lib/upgrade.go | 7 +- internal/cli/outdated/outdated.go | 4 +- 19 files changed, 193 insertions(+), 163 deletions(-) diff --git a/commands/service.go b/commands/service.go index 5ad16c8a0e4..e1904c5fc81 100644 --- a/commands/service.go +++ b/commands/service.go @@ -164,94 +164,11 @@ func (s *arduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Co return ListProgrammersAvailableForUpload(ctx, req) } -// LibraryDownload FIXMEDOC -func (s *arduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, stream rpc.ArduinoCoreService_LibraryDownloadServer) error { - syncSend := NewSynchronizedSend(stream.Send) - resp, err := LibraryDownload( - stream.Context(), req, - func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryDownloadResponse{Progress: p}) }, - ) - if err != nil { - return err - } - return syncSend.Send(resp) -} - -// LibraryInstall FIXMEDOC -func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, stream rpc.ArduinoCoreService_LibraryInstallServer) error { - syncSend := NewSynchronizedSend(stream.Send) - return LibraryInstall( - stream.Context(), s, req, - func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryInstallResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) }, - ) -} - -// LibraryUpgrade FIXMEDOC -func (s *arduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, stream rpc.ArduinoCoreService_LibraryUpgradeServer) error { - syncSend := NewSynchronizedSend(stream.Send) - return LibraryUpgrade( - stream.Context(), s, req, - func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{TaskProgress: p}) }, - ) -} - -// LibraryUninstall FIXMEDOC -func (s *arduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallRequest, stream rpc.ArduinoCoreService_LibraryUninstallServer) error { - syncSend := NewSynchronizedSend(stream.Send) - return LibraryUninstall(stream.Context(), req, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) }, - ) -} - -// LibraryUpgradeAll FIXMEDOC -func (s *arduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, stream rpc.ArduinoCoreService_LibraryUpgradeAllServer) error { - syncSend := NewSynchronizedSend(stream.Send) - return LibraryUpgradeAll(s, req, - func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{Progress: p}) }, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) }, - ) -} - -// LibraryResolveDependencies FIXMEDOC -func (s *arduinoCoreServerImpl) LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { - return LibraryResolveDependencies(ctx, req) -} - -// LibrarySearch FIXMEDOC -func (s *arduinoCoreServerImpl) LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { - return LibrarySearch(ctx, req) -} - -// LibraryList FIXMEDOC -func (s *arduinoCoreServerImpl) LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { - return LibraryList(ctx, req) -} - // ArchiveSketch FIXMEDOC func (s *arduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { return ArchiveSketch(ctx, req) } -// ZipLibraryInstall FIXMEDOC -func (s *arduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequest, stream rpc.ArduinoCoreService_ZipLibraryInstallServer) error { - syncSend := NewSynchronizedSend(stream.Send) - return ZipLibraryInstall( - stream.Context(), req, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.ZipLibraryInstallResponse{TaskProgress: p}) }, - ) -} - -// GitLibraryInstall FIXMEDOC -func (s *arduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequest, stream rpc.ArduinoCoreService_GitLibraryInstallServer) error { - syncSend := NewSynchronizedSend(stream.Send) - return GitLibraryInstall( - stream.Context(), req, - func(p *rpc.TaskProgress) { syncSend.Send(&rpc.GitLibraryInstallResponse{TaskProgress: p}) }, - ) -} - // EnumerateMonitorPortSettings FIXMEDOC func (s *arduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { return EnumerateMonitorPortSettings(ctx, req) diff --git a/commands/service_library_download.go b/commands/service_library_download.go index 56102942ec2..152afa466ba 100644 --- a/commands/service_library_download.go +++ b/commands/service_library_download.go @@ -24,17 +24,28 @@ import ( "github.com/arduino/arduino-cli/internal/arduino/libraries/librariesindex" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" - "github.com/sirupsen/logrus" ) -// LibraryDownload executes the download of the library. -// A DownloadProgressCB callback function must be passed to monitor download progress. -func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downloadCB rpc.DownloadProgressCB) (*rpc.LibraryDownloadResponse, error) { - logrus.Info("Executing `arduino-cli lib download`") +// LibraryDownloadStreamResponseToCallbackFunction returns a gRPC stream to be used in LibraryDownload that sends +// all responses to the callback function. +func LibraryDownloadStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB) rpc.ArduinoCoreService_LibraryDownloadServer { + return streamResponseToCallback(ctx, func(r *rpc.LibraryDownloadResponse) error { + if r.GetProgress() != nil { + downloadCB(r.GetProgress()) + } + return nil + }) +} + +// LibraryDownload downloads a library +func (s *arduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, stream rpc.ArduinoCoreService_LibraryDownloadServer) error { + syncSend := NewSynchronizedSend(stream.Send) + ctx := stream.Context() + downloadCB := func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryDownloadResponse{Progress: p}) } var downloadsDir *paths.Path if pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()); err != nil { - return nil, err + return err } else { downloadsDir = pme.DownloadDir release() @@ -42,29 +53,27 @@ func LibraryDownload(ctx context.Context, req *rpc.LibraryDownloadRequest, downl li, err := instances.GetLibrariesIndex(req.GetInstance()) if err != nil { - return nil, err + return err } - logrus.Info("Preparing download") - version, err := ParseVersion(req.GetVersion()) if err != nil { - return nil, err + return err } lib, err := li.FindRelease(req.GetName(), version) if err != nil { - return nil, err + return err } - if err := downloadLibrary(downloadsDir, lib, downloadCB, func(*rpc.TaskProgress) {}, "download"); err != nil { - return nil, err + if err := downloadLibrary(ctx, downloadsDir, lib, downloadCB, func(*rpc.TaskProgress) {}, "download"); err != nil { + return err } - return &rpc.LibraryDownloadResponse{}, nil + return syncSend.Send(&rpc.LibraryDownloadResponse{}) } -func downloadLibrary(downloadsDir *paths.Path, libRelease *librariesindex.Release, +func downloadLibrary(_ context.Context, downloadsDir *paths.Path, libRelease *librariesindex.Release, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, queryParameter string) error { taskCB(&rpc.TaskProgress{Name: tr("Downloading %s", libRelease)}) @@ -72,6 +81,7 @@ func downloadLibrary(downloadsDir *paths.Path, libRelease *librariesindex.Releas if err != nil { return &cmderrors.FailedDownloadError{Message: tr("Can't download library"), Cause: err} } + // TODO: Pass context if err := libRelease.Resource.Download(downloadsDir, config, libRelease.String(), downloadCB, queryParameter); err != nil { return &cmderrors.FailedDownloadError{Message: tr("Can't download library"), Cause: err} } diff --git a/commands/service_library_install.go b/commands/service_library_install.go index f08c50f8ccc..c2b9aa7ad1e 100644 --- a/commands/service_library_install.go +++ b/commands/service_library_install.go @@ -30,8 +30,27 @@ import ( "github.com/sirupsen/logrus" ) +// LibraryInstallStreamResponseToCallbackFunction returns a gRPC stream to be used in LibraryInstall that sends +// all responses to the callback function. +func LibraryInstallStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) rpc.ArduinoCoreService_LibraryInstallServer { + return streamResponseToCallback(ctx, func(r *rpc.LibraryInstallResponse) error { + if r.GetProgress() != nil { + downloadCB(r.GetProgress()) + } + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + return nil + }) +} + // LibraryInstall resolves the library dependencies, then downloads and installs the libraries into the install location. -func LibraryInstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.LibraryInstallRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, stream rpc.ArduinoCoreService_LibraryInstallServer) error { + ctx := stream.Context() + syncSend := NewSynchronizedSend(stream.Send) + downloadCB := func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryInstallResponse{Progress: p}) } + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryInstallResponse{TaskProgress: p}) } + // Obtain the library index from the manager li, err := instances.GetLibrariesIndex(req.GetInstance()) if err != nil { @@ -128,7 +147,7 @@ func LibraryInstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req * downloadReason += "-builtin" } } - if err := downloadLibrary(downloadsDir, libRelease, downloadCB, taskCB, downloadReason); err != nil { + if err := downloadLibrary(ctx, downloadsDir, libRelease, downloadCB, taskCB, downloadReason); err != nil { return err } if err := installLibrary(lmi, downloadsDir, libRelease, installTask, taskCB); err != nil { @@ -136,8 +155,10 @@ func LibraryInstall(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req * } } - stream := InitStreamResponseToCallbackFunction(ctx, nil) - if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, stream); err != nil { + err = s.Init( + &rpc.InitRequest{Instance: req.GetInstance()}, + InitStreamResponseToCallbackFunction(ctx, nil)) + if err != nil { return err } @@ -166,8 +187,23 @@ func installLibrary(lmi *librariesmanager.Installer, downloadsDir *paths.Path, l return nil } +// ZipLibraryInstallStreamResponseToCallbackFunction returns a gRPC stream to be used in ZipLibraryInstall that sends +// all responses to the callback function. +func ZipLibraryInstallStreamResponseToCallbackFunction(ctx context.Context, taskCB rpc.TaskProgressCB) rpc.ArduinoCoreService_ZipLibraryInstallServer { + return streamResponseToCallback(ctx, func(r *rpc.ZipLibraryInstallResponse) error { + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + return nil + }) +} + // ZipLibraryInstall FIXMEDOC -func ZipLibraryInstall(ctx context.Context, req *rpc.ZipLibraryInstallRequest, taskCB rpc.TaskProgressCB) error { +func (s *arduinoCoreServerImpl) ZipLibraryInstall(req *rpc.ZipLibraryInstallRequest, stream rpc.ArduinoCoreService_ZipLibraryInstallServer) error { + ctx := stream.Context() + syncSend := NewSynchronizedSend(stream.Send) + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.ZipLibraryInstallResponse{TaskProgress: p}) } + lm, err := instances.GetLibraryManager(req.GetInstance()) if err != nil { return err @@ -181,14 +217,30 @@ func ZipLibraryInstall(ctx context.Context, req *rpc.ZipLibraryInstallRequest, t return nil } +// GitLibraryInstallStreamResponseToCallbackFunction returns a gRPC stream to be used in GitLibraryInstall that sends +// all responses to the callback function. +func GitLibraryInstallStreamResponseToCallbackFunction(ctx context.Context, taskCB rpc.TaskProgressCB) rpc.ArduinoCoreService_GitLibraryInstallServer { + return streamResponseToCallback(ctx, func(r *rpc.GitLibraryInstallResponse) error { + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + return nil + }) +} + // GitLibraryInstall FIXMEDOC -func GitLibraryInstall(ctx context.Context, req *rpc.GitLibraryInstallRequest, taskCB rpc.TaskProgressCB) error { +func (s *arduinoCoreServerImpl) GitLibraryInstall(req *rpc.GitLibraryInstallRequest, stream rpc.ArduinoCoreService_GitLibraryInstallServer) error { + syncSend := NewSynchronizedSend(stream.Send) + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.GitLibraryInstallResponse{TaskProgress: p}) } lm, err := instances.GetLibraryManager(req.GetInstance()) if err != nil { return err } lmi, release := lm.NewInstaller() defer release() + + // TODO: pass context + // ctx := stream.Context() if err := lmi.InstallGitLib(req.GetUrl(), req.GetOverwrite()); err != nil { return &cmderrors.FailedLibraryInstallError{Cause: err} } diff --git a/commands/service_library_list.go b/commands/service_library_list.go index 84030341a43..be293c6161d 100644 --- a/commands/service_library_list.go +++ b/commands/service_library_list.go @@ -35,7 +35,7 @@ type installedLib struct { } // LibraryList FIXMEDOC -func LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { +func (s *arduinoCoreServerImpl) LibraryList(ctx context.Context, req *rpc.LibraryListRequest) (*rpc.LibraryListResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/commands/service_library_resolve_deps.go b/commands/service_library_resolve_deps.go index ccfef15b742..013199dbe29 100644 --- a/commands/service_library_resolve_deps.go +++ b/commands/service_library_resolve_deps.go @@ -30,7 +30,7 @@ import ( ) // LibraryResolveDependencies FIXMEDOC -func LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { +func (s *arduinoCoreServerImpl) LibraryResolveDependencies(ctx context.Context, req *rpc.LibraryResolveDependenciesRequest) (*rpc.LibraryResolveDependenciesResponse, error) { lme, release, err := instances.GetLibraryManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/commands/service_library_search.go b/commands/service_library_search.go index d5ab7c86d80..39ff4c51c6e 100644 --- a/commands/service_library_search.go +++ b/commands/service_library_search.go @@ -27,7 +27,7 @@ import ( ) // LibrarySearch FIXMEDOC -func LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { +func (s *arduinoCoreServerImpl) LibrarySearch(ctx context.Context, req *rpc.LibrarySearchRequest) (*rpc.LibrarySearchResponse, error) { li, err := instances.GetLibrariesIndex(req.GetInstance()) if err != nil { return nil, err diff --git a/commands/service_library_uninstall.go b/commands/service_library_uninstall.go index 6f613760890..e436cbe15a9 100644 --- a/commands/service_library_uninstall.go +++ b/commands/service_library_uninstall.go @@ -25,8 +25,23 @@ import ( "github.com/arduino/go-paths-helper" ) -// LibraryUninstall FIXMEDOC -func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallRequest, taskCB rpc.TaskProgressCB) error { +// LibraryUninstallStreamResponseToCallbackFunction returns a gRPC stream to be used in LibraryUninstall that sends +// all responses to the callback function. +func LibraryUninstallStreamResponseToCallbackFunction(ctx context.Context, taskCB rpc.TaskProgressCB) rpc.ArduinoCoreService_LibraryUninstallServer { + return streamResponseToCallback(ctx, func(r *rpc.LibraryUninstallResponse) error { + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + return nil + }) +} + +// LibraryUninstall uninstalls a library +func (s *arduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallRequest, stream rpc.ArduinoCoreService_LibraryUninstallServer) error { + // ctx := stream.Context() + syncSend := NewSynchronizedSend(stream.Send) + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUninstallResponse{TaskProgress: p}) } + lm, err := instances.GetLibraryManager(req.GetInstance()) if err != nil { return err @@ -47,6 +62,7 @@ func LibraryUninstall(ctx context.Context, req *rpc.LibraryUninstallRequest, tas if len(libs) == 1 { taskCB(&rpc.TaskProgress{Name: tr("Uninstalling %s", libs)}) + // TODO: pass context lmi.Uninstall(libs[0]) taskCB(&rpc.TaskProgress{Completed: true}) return nil diff --git a/commands/service_library_upgrade.go b/commands/service_library_upgrade.go index 327c0245ee7..ff8af393705 100644 --- a/commands/service_library_upgrade.go +++ b/commands/service_library_upgrade.go @@ -23,9 +23,26 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) +// LibraryUpgradeAllStreamResponseToCallbackFunction returns a gRPC stream to be used in LibraryUpgradeAll that sends +// all responses to the callback function. +func LibraryUpgradeAllStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) rpc.ArduinoCoreService_LibraryUpgradeAllServer { + return streamResponseToCallback(ctx, func(r *rpc.LibraryUpgradeAllResponse) error { + if r.GetProgress() != nil { + downloadCB(r.GetProgress()) + } + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + return nil + }) +} + // LibraryUpgradeAll upgrades all the available libraries -func LibraryUpgradeAll(srv rpc.ArduinoCoreServiceServer, req *rpc.LibraryUpgradeAllRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { - ctx := context.Background() +func (s *arduinoCoreServerImpl) LibraryUpgradeAll(req *rpc.LibraryUpgradeAllRequest, stream rpc.ArduinoCoreService_LibraryUpgradeAllServer) error { + ctx := stream.Context() + syncSend := NewSynchronizedSend(stream.Send) + downloadCB := func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{Progress: p}) } + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeAllResponse{TaskProgress: p}) } li, err := instances.GetLibrariesIndex(req.GetInstance()) if err != nil { @@ -39,20 +56,41 @@ func LibraryUpgradeAll(srv rpc.ArduinoCoreServiceServer, req *rpc.LibraryUpgrade libsToUpgrade := listLibraries(lme, li, true, false) release() - if err := upgrade(ctx, srv, req.GetInstance(), libsToUpgrade, downloadCB, taskCB); err != nil { + if err := s.libraryUpgrade(ctx, req.GetInstance(), libsToUpgrade, downloadCB, taskCB); err != nil { return err } - stream := InitStreamResponseToCallbackFunction(ctx, nil) - if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, stream); err != nil { + err = s.Init( + &rpc.InitRequest{Instance: req.GetInstance()}, + InitStreamResponseToCallbackFunction(ctx, nil)) + if err != nil { return err } return nil } +// LibraryUpgradeStreamResponseToCallbackFunction returns a gRPC stream to be used in LibraryUpgrade that sends +// all responses to the callback function. +func LibraryUpgradeStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) rpc.ArduinoCoreService_LibraryUpgradeServer { + return streamResponseToCallback(ctx, func(r *rpc.LibraryUpgradeResponse) error { + if r.GetProgress() != nil { + downloadCB(r.GetProgress()) + } + if r.GetTaskProgress() != nil { + taskCB(r.GetTaskProgress()) + } + return nil + }) +} + // LibraryUpgrade upgrades a library -func LibraryUpgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req *rpc.LibraryUpgradeRequest, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func (s *arduinoCoreServerImpl) LibraryUpgrade(req *rpc.LibraryUpgradeRequest, stream rpc.ArduinoCoreService_LibraryUpgradeServer) error { + ctx := stream.Context() + syncSend := NewSynchronizedSend(stream.Send) + downloadCB := func(p *rpc.DownloadProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{Progress: p}) } + taskCB := func(p *rpc.TaskProgress) { syncSend.Send(&rpc.LibraryUpgradeResponse{TaskProgress: p}) } + li, err := instances.GetLibrariesIndex(req.GetInstance()) if err != nil { return err @@ -78,10 +116,10 @@ func LibraryUpgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, req * } // Install update - return upgrade(ctx, srv, req.GetInstance(), []*installedLib{lib}, downloadCB, taskCB) + return s.libraryUpgrade(ctx, req.GetInstance(), []*installedLib{lib}, downloadCB, taskCB) } -func upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, libs []*installedLib, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func (s *arduinoCoreServerImpl) libraryUpgrade(ctx context.Context, instance *rpc.Instance, libs []*installedLib, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { for _, lib := range libs { libInstallReq := &rpc.LibraryInstallRequest{ Instance: instance, @@ -90,8 +128,8 @@ func upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rp NoDeps: false, NoOverwrite: false, } - err := LibraryInstall(ctx, srv, libInstallReq, downloadCB, taskCB) - if err != nil { + stream := LibraryInstallStreamResponseToCallbackFunction(ctx, downloadCB, taskCB) + if err := s.LibraryInstall(libInstallReq, stream); err != nil { return err } } diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index d27e68005ae..ad0f9d1f1b8 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -130,7 +130,7 @@ func GetUninstallableLibraries(ctx context.Context, srv rpc.ArduinoCoreServiceSe func getLibraries(ctx context.Context, srv rpc.ArduinoCoreServiceServer, all bool) []string { inst := instance.CreateAndInit(ctx, srv) - libs, _ := commands.LibraryList(context.Background(), &rpc.LibraryListRequest{ + libs, _ := srv.LibraryList(ctx, &rpc.LibraryListRequest{ Instance: inst, All: all, Updatable: false, @@ -150,7 +150,7 @@ func getLibraries(ctx context.Context, srv rpc.ArduinoCoreServiceServer, all boo func GetInstallableLibs(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { inst := instance.CreateAndInit(ctx, srv) - libs, _ := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ + libs, _ := srv.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ Instance: inst, SearchArgs: "", // if no query is specified all the libs are returned }) diff --git a/internal/cli/lib/args.go b/internal/cli/lib/args.go index b69b0664910..3d3546a0c7e 100644 --- a/internal/cli/lib/args.go +++ b/internal/cli/lib/args.go @@ -20,7 +20,6 @@ import ( "fmt" "strings" - "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) @@ -74,9 +73,9 @@ 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) { +func ParseLibraryReferenceArgAndAdjustCase(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, arg string) (*LibraryReferenceArg, error) { libRef, _ := ParseLibraryReferenceArg(arg) - res, err := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ + res, err := srv.LibrarySearch(ctx, &rpc.LibrarySearchRequest{ Instance: instance, SearchArgs: libRef.Name, }) @@ -98,10 +97,10 @@ func ParseLibraryReferenceArgAndAdjustCase(instance *rpc.Instance, arg string) ( // ParseLibraryReferenceArgsAndAdjustCase is a convenient wrapper that operates on a slice of // strings and calls ParseLibraryReferenceArgAndAdjustCase for each of them. It returns at the first invalid argument. -func ParseLibraryReferenceArgsAndAdjustCase(instance *rpc.Instance, args []string) ([]*LibraryReferenceArg, error) { +func ParseLibraryReferenceArgsAndAdjustCase(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, args []string) ([]*LibraryReferenceArg, error) { ret := []*LibraryReferenceArg{} for _, arg := range args { - if reference, err := ParseLibraryReferenceArgAndAdjustCase(instance, arg); err == nil { + if reference, err := ParseLibraryReferenceArgAndAdjustCase(ctx, srv, instance, arg); err == nil { ret = append(ret, reference) } else { return nil, err diff --git a/internal/cli/lib/check_deps.go b/internal/cli/lib/check_deps.go index 87a88837209..26cd954739c 100644 --- a/internal/cli/lib/check_deps.go +++ b/internal/cli/lib/check_deps.go @@ -21,7 +21,6 @@ import ( "os" "sort" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -58,12 +57,12 @@ func runDepsCommand(srv rpc.ArduinoCoreServiceServer, args []string, noOverwrite instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib deps`") - libRef, err := ParseLibraryReferenceArgAndAdjustCase(instance, args[0]) + libRef, err := ParseLibraryReferenceArgAndAdjustCase(ctx, srv, instance, args[0]) if err != nil { feedback.Fatal(tr("Arguments error: %v", err), feedback.ErrBadArgument) } - deps, err := commands.LibraryResolveDependencies(context.Background(), &rpc.LibraryResolveDependenciesRequest{ + deps, err := srv.LibraryResolveDependencies(ctx, &rpc.LibraryResolveDependenciesRequest{ Instance: instance, Name: libRef.Name, Version: libRef.Version, diff --git a/internal/cli/lib/download.go b/internal/cli/lib/download.go index 415ce52eb16..b20877bea01 100644 --- a/internal/cli/lib/download.go +++ b/internal/cli/lib/download.go @@ -53,7 +53,7 @@ func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) - refs, err := ParseLibraryReferenceArgsAndAdjustCase(instance, args) + refs, err := ParseLibraryReferenceArgsAndAdjustCase(ctx, srv, instance, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } @@ -64,8 +64,8 @@ func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { Name: library.Name, Version: library.Version, } - _, err := commands.LibraryDownload(context.Background(), libraryDownloadRequest, feedback.ProgressBar()) - if err != nil { + stream := commands.LibraryDownloadStreamResponseToCallbackFunction(ctx, feedback.ProgressBar()) + if err := srv.LibraryDownload(libraryDownloadRequest, stream); err != nil { feedback.Fatal(tr("Error downloading %[1]s: %[2]v", library, err), feedback.ErrNetwork) } } diff --git a/internal/cli/lib/examples.go b/internal/cli/lib/examples.go index 06f42086fd6..3b5921f8ea0 100644 --- a/internal/cli/lib/examples.go +++ b/internal/cli/lib/examples.go @@ -22,7 +22,6 @@ import ( "sort" "strings" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" @@ -66,7 +65,7 @@ func runExamplesCommand(srv rpc.ArduinoCoreServiceServer, args []string) { name = args[0] } - res, err := commands.LibraryList(context.Background(), &rpc.LibraryListRequest{ + res, err := srv.LibraryList(ctx, &rpc.LibraryListRequest{ Instance: instance, All: true, Name: name, diff --git a/internal/cli/lib/install.go b/internal/cli/lib/install.go index 0fe9fca84ed..dce521eb6d3 100644 --- a/internal/cli/lib/install.go +++ b/internal/cli/lib/install.go @@ -90,12 +90,13 @@ func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps b if zipPath { for _, path := range args { - err := commands.ZipLibraryInstall(context.Background(), &rpc.ZipLibraryInstallRequest{ + req := &rpc.ZipLibraryInstallRequest{ Instance: instance, Path: path, Overwrite: !noOverwrite, - }, feedback.TaskProgress()) - if err != nil { + } + stream := commands.ZipLibraryInstallStreamResponseToCallbackFunction(ctx, feedback.TaskProgress()) + if err := srv.ZipLibraryInstall(req, stream); err != nil { feedback.Fatal(tr("Error installing Zip Library: %v", err), feedback.ErrGeneric) } } @@ -111,19 +112,20 @@ func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps b } url = wd.String() } - err := commands.GitLibraryInstall(context.Background(), &rpc.GitLibraryInstallRequest{ + req := &rpc.GitLibraryInstallRequest{ Instance: instance, Url: url, Overwrite: !noOverwrite, - }, feedback.TaskProgress()) - if err != nil { + } + stream := commands.GitLibraryInstallStreamResponseToCallbackFunction(ctx, feedback.TaskProgress()) + if err := srv.GitLibraryInstall(req, stream); err != nil { feedback.Fatal(tr("Error installing Git Library: %v", err), feedback.ErrGeneric) } } return } - libRefs, err := ParseLibraryReferenceArgsAndAdjustCase(instance, args) + libRefs, err := ParseLibraryReferenceArgsAndAdjustCase(ctx, srv, instance, args) if err != nil { feedback.Fatal(tr("Arguments error: %v", err), feedback.ErrBadArgument) } @@ -141,8 +143,8 @@ func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps b NoOverwrite: noOverwrite, InstallLocation: installLocation, } - err := commands.LibraryInstall(ctx, srv, libraryInstallRequest, feedback.ProgressBar(), feedback.TaskProgress()) - if err != nil { + stream := commands.LibraryInstallStreamResponseToCallbackFunction(ctx, feedback.ProgressBar(), feedback.TaskProgress()) + if err := srv.LibraryInstall(libraryInstallRequest, stream); err != nil { feedback.Fatal(tr("Error installing %s: %v", libRef.Name, err), feedback.ErrGeneric) } } diff --git a/internal/cli/lib/list.go b/internal/cli/lib/list.go index 1487cf75527..8d743bb3ba3 100644 --- a/internal/cli/lib/list.go +++ b/internal/cli/lib/list.go @@ -22,7 +22,6 @@ import ( "sort" "strings" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -49,7 +48,7 @@ not listed, they can be listed by adding the --all flag.`), ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib list`") - List(instance, args, all, updatable) + List(ctx, srv, instance, args, all, updatable) }, } listCommand.Flags().BoolVar(&all, "all", false, tr("Include built-in libraries (from platforms and IDE) in listing.")) @@ -59,8 +58,8 @@ not listed, they can be listed by adding the --all flag.`), } // List gets and prints a list of installed libraries. -func List(instance *rpc.Instance, args []string, all bool, updatable bool) { - installedLibs := GetList(instance, args, all, updatable) +func List(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, args []string, all bool, updatable bool) { + installedLibs := GetList(ctx, srv, instance, args, all, updatable) installedLibsResult := make([]*result.InstalledLibrary, len(installedLibs)) for i, v := range installedLibs { @@ -74,18 +73,13 @@ func List(instance *rpc.Instance, args []string, all bool, updatable bool) { } // GetList returns a list of installed libraries. -func GetList( - instance *rpc.Instance, - args []string, - all bool, - updatable bool, -) []*rpc.InstalledLibrary { +func GetList(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, args []string, all bool, updatable bool) []*rpc.InstalledLibrary { name := "" if len(args) > 0 { name = args[0] } - res, err := commands.LibraryList(context.Background(), &rpc.LibraryListRequest{ + res, err := srv.LibraryList(ctx, &rpc.LibraryListRequest{ Instance: instance, All: all, Updatable: updatable, diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index 94a4cc616fb..833b51f6558 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -119,7 +119,7 @@ func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, namesOnly instance.Init(ctx, srv, inst) } - searchResp, err := commands.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ + searchResp, err := srv.LibrarySearch(ctx, &rpc.LibrarySearchRequest{ Instance: inst, SearchArgs: strings.Join(args, " "), OmitReleasesDetails: omitReleasesDetails, diff --git a/internal/cli/lib/uninstall.go b/internal/cli/lib/uninstall.go index a79ba4683de..d8129ec42db 100644 --- a/internal/cli/lib/uninstall.go +++ b/internal/cli/lib/uninstall.go @@ -51,18 +51,19 @@ func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string) { ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) - refs, err := ParseLibraryReferenceArgsAndAdjustCase(instance, args) + refs, err := ParseLibraryReferenceArgsAndAdjustCase(ctx, srv, instance, args) if err != nil { feedback.Fatal(tr("Invalid argument passed: %v", err), feedback.ErrBadArgument) } for _, library := range refs { - err := commands.LibraryUninstall(context.Background(), &rpc.LibraryUninstallRequest{ + req := &rpc.LibraryUninstallRequest{ Instance: instance, Name: library.Name, Version: library.Version, - }, feedback.TaskProgress()) - if err != nil { + } + stream := commands.LibraryUninstallStreamResponseToCallbackFunction(ctx, feedback.TaskProgress()) + if err := srv.LibraryUninstall(req, stream); err != nil { feedback.Fatal(tr("Error uninstalling %[1]s: %[2]v", library, err), feedback.ErrGeneric) } } diff --git a/internal/cli/lib/upgrade.go b/internal/cli/lib/upgrade.go index 52bd644c730..6c612eb0089 100644 --- a/internal/cli/lib/upgrade.go +++ b/internal/cli/lib/upgrade.go @@ -56,15 +56,16 @@ func Upgrade(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rp var upgradeErr error if len(libraries) == 0 { req := &rpc.LibraryUpgradeAllRequest{Instance: instance} - upgradeErr = commands.LibraryUpgradeAll(srv, req, feedback.ProgressBar(), feedback.TaskProgress()) + stream := commands.LibraryUpgradeAllStreamResponseToCallbackFunction(ctx, feedback.ProgressBar(), feedback.TaskProgress()) + upgradeErr = srv.LibraryUpgradeAll(req, stream) } else { for _, libName := range libraries { req := &rpc.LibraryUpgradeRequest{ Instance: instance, Name: libName, } - upgradeErr = commands.LibraryUpgrade(ctx, srv, req, feedback.ProgressBar(), feedback.TaskProgress()) - if upgradeErr != nil { + stream := commands.LibraryUpgradeStreamResponseToCallbackFunction(ctx, feedback.ProgressBar(), feedback.TaskProgress()) + if upgradeErr = srv.LibraryUpgrade(req, stream); upgradeErr != nil { break } } diff --git a/internal/cli/outdated/outdated.go b/internal/cli/outdated/outdated.go index 7a105dbfa9b..54d1aec70b7 100644 --- a/internal/cli/outdated/outdated.go +++ b/internal/cli/outdated/outdated.go @@ -62,7 +62,9 @@ func runOutdatedCommand(srv rpc.ArduinoCoreServiceServer) { // Outdated prints a list of outdated platforms and libraries func Outdated(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.Instance) { feedback.PrintResult( - newOutdatedResult(core.GetList(ctx, srv, inst, false, true), lib.GetList(inst, []string{}, false, true)), + newOutdatedResult( + core.GetList(ctx, srv, inst, false, true), + lib.GetList(ctx, srv, inst, []string{}, false, true)), ) } From a3800fa2834b64f4a6586b92072f0af1b984d794 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 18 Mar 2024 13:20:40 +0100 Subject: [PATCH 21/56] Inlining methods in ArduinoCoreServiceImpl (part 12: UpdateLibrariesIndex) --- commands/instances.go | 62 ++++++++++++++++++++++++-------- commands/service.go | 18 ---------- internal/cli/lib/search.go | 11 +++--- internal/cli/lib/update_index.go | 13 ++++--- internal/cli/update/update.go | 2 +- 5 files changed, 58 insertions(+), 48 deletions(-) diff --git a/commands/instances.go b/commands/instances.go index 614825c19af..1b51231c657 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -422,30 +422,56 @@ func (s *arduinoCoreServerImpl) Destroy(ctx context.Context, req *rpc.DestroyReq return &rpc.DestroyResponse{}, nil } +// UpdateLibrariesIndexStreamResponseToCallbackFunction returns a gRPC stream to be used in UpdateLibrariesIndex that sends +// all responses to the callback function. +func UpdateLibrariesIndexStreamResponseToCallbackFunction(ctx context.Context, downloadCB rpc.DownloadProgressCB) (rpc.ArduinoCoreService_UpdateLibrariesIndexServer, func() *rpc.UpdateLibrariesIndexResponse_Result) { + var result *rpc.UpdateLibrariesIndexResponse_Result + return streamResponseToCallback(ctx, func(r *rpc.UpdateLibrariesIndexResponse) error { + if r.GetDownloadProgress() != nil { + downloadCB(r.GetDownloadProgress()) + } + if r.GetResult() != nil { + result = r.GetResult() + } + return nil + }), func() *rpc.UpdateLibrariesIndexResponse_Result { + return result + } +} + // UpdateLibrariesIndex updates the library_index.json -func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequest, downloadCB rpc.DownloadProgressCB) (*rpc.UpdateLibrariesIndexResponse_Result, error) { - logrus.Info("Updating libraries index") +func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesIndexRequest, stream rpc.ArduinoCoreService_UpdateLibrariesIndexServer) error { + syncSend := NewSynchronizedSend(stream.Send) + downloadCB := func(p *rpc.DownloadProgress) { + syncSend.Send(&rpc.UpdateLibrariesIndexResponse{ + Message: &rpc.UpdateLibrariesIndexResponse_DownloadProgress{DownloadProgress: p}}) + } pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { - return nil, err + return err } indexDir := pme.IndexDir release() - index := globals.LibrariesIndexResource - result := func(status rpc.IndexUpdateReport_Status) *rpc.UpdateLibrariesIndexResponse_Result { - return &rpc.UpdateLibrariesIndexResponse_Result{ - LibrariesIndex: &rpc.IndexUpdateReport{ - IndexUrl: globals.LibrariesIndexResource.URL.String(), - Status: status, + + resultCB := func(status rpc.IndexUpdateReport_Status) { + syncSend.Send(&rpc.UpdateLibrariesIndexResponse{ + Message: &rpc.UpdateLibrariesIndexResponse_Result_{ + Result: &rpc.UpdateLibrariesIndexResponse_Result{ + LibrariesIndex: &rpc.IndexUpdateReport{ + IndexUrl: index.URL.String(), + Status: status, + }, + }, }, - } + }) } // Create the index directory if it doesn't exist if err := indexDir.MkdirAll(); err != nil { - return result(rpc.IndexUpdateReport_STATUS_FAILED), &cmderrors.PermissionDeniedError{Message: tr("Could not create index directory"), Cause: err} + resultCB(rpc.IndexUpdateReport_STATUS_FAILED) + return &cmderrors.PermissionDeniedError{Message: tr("Could not create index directory"), Cause: err} } // Check if the index file is already up-to-date @@ -453,16 +479,21 @@ func UpdateLibrariesIndex(ctx context.Context, req *rpc.UpdateLibrariesIndexRequ if info, err := indexDir.Join(indexFileName).Stat(); err == nil { ageSecs := int64(time.Since(info.ModTime()).Seconds()) if ageSecs < req.GetUpdateIfOlderThanSecs() { - return result(rpc.IndexUpdateReport_STATUS_ALREADY_UP_TO_DATE), nil + resultCB(rpc.IndexUpdateReport_STATUS_ALREADY_UP_TO_DATE) + return nil } } // Perform index update + // TODO: pass context + // ctx := stream.Context() if err := globals.LibrariesIndexResource.Download(indexDir, downloadCB); err != nil { - return nil, err + resultCB(rpc.IndexUpdateReport_STATUS_FAILED) + return err } - return result(rpc.IndexUpdateReport_STATUS_UPDATED), nil + resultCB(rpc.IndexUpdateReport_STATUS_UPDATED) + return nil } // UpdateIndexStreamResponseToCallbackFunction returns a gRPC stream to be used in UpdateIndex that sends @@ -593,7 +624,8 @@ func firstUpdate(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance // The library_index.json file doesn't exists, that means the CLI is run for the first time // so we proceed with the first update that downloads the file req := &rpc.UpdateLibrariesIndexRequest{Instance: instance} - if _, err := UpdateLibrariesIndex(ctx, req, downloadCb); err != nil { + stream, _ := UpdateLibrariesIndexStreamResponseToCallbackFunction(ctx, downloadCb) + if err := srv.UpdateLibrariesIndex(req, stream); err != nil { return err } } diff --git a/commands/service.go b/commands/service.go index e1904c5fc81..997f5f88a63 100644 --- a/commands/service.go +++ b/commands/service.go @@ -37,24 +37,6 @@ type arduinoCoreServerImpl struct { versionString string } -// UpdateLibrariesIndex FIXMEDOC -func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesIndexRequest, stream rpc.ArduinoCoreService_UpdateLibrariesIndexServer) error { - syncSend := NewSynchronizedSend(stream.Send) - res, err := UpdateLibrariesIndex(stream.Context(), req, - func(p *rpc.DownloadProgress) { - syncSend.Send(&rpc.UpdateLibrariesIndexResponse{ - Message: &rpc.UpdateLibrariesIndexResponse_DownloadProgress{DownloadProgress: p}, - }) - }, - ) - if res != nil { - syncSend.Send(&rpc.UpdateLibrariesIndexResponse{ - Message: &rpc.UpdateLibrariesIndexResponse_Result_{Result: res}, - }) - } - return err -} - // Version FIXMEDOC func (s *arduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionRequest) (*rpc.VersionResponse, error) { return &rpc.VersionResponse{Version: s.versionString}, nil diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index 833b51f6558..aa1d0f1b314 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -107,15 +107,12 @@ func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, namesOnly logrus.Info("Executing `arduino-cli lib search`") - res, err := commands.UpdateLibrariesIndex( - context.Background(), - &rpc.UpdateLibrariesIndexRequest{Instance: inst, UpdateIfOlderThanSecs: int64(indexUpdateInterval.Seconds())}, - feedback.ProgressBar(), - ) - if err != nil { + stream, res := commands.UpdateLibrariesIndexStreamResponseToCallbackFunction(ctx, feedback.ProgressBar()) + req := &rpc.UpdateLibrariesIndexRequest{Instance: inst, UpdateIfOlderThanSecs: int64(indexUpdateInterval.Seconds())} + if err := srv.UpdateLibrariesIndex(req, stream); err != nil { feedback.Fatal(tr("Error updating library index: %v", err), feedback.ErrGeneric) } - if res.GetLibrariesIndex().GetStatus() == rpc.IndexUpdateReport_STATUS_UPDATED { + if res().GetLibrariesIndex().GetStatus() == rpc.IndexUpdateReport_STATUS_UPDATED { instance.Init(ctx, srv, inst) } diff --git a/internal/cli/lib/update_index.go b/internal/cli/lib/update_index.go index 5d531eb96e3..f5f5c62cea8 100644 --- a/internal/cli/lib/update_index.go +++ b/internal/cli/lib/update_index.go @@ -47,19 +47,18 @@ func runUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib update-index`") - resp := UpdateIndex(inst) + resp := UpdateIndex(ctx, srv, inst) feedback.PrintResult(&libUpdateIndexResult{result.NewUpdateLibrariesIndexResponse_ResultResult(resp)}) } // UpdateIndex updates the index of libraries. -func UpdateIndex(inst *rpc.Instance) *rpc.UpdateLibrariesIndexResponse_Result { - resp, err := commands.UpdateLibrariesIndex(context.Background(), &rpc.UpdateLibrariesIndexRequest{ - Instance: inst, - }, feedback.ProgressBar()) - if err != nil { +func UpdateIndex(ctx context.Context, srv rpc.ArduinoCoreServiceServer, inst *rpc.Instance) *rpc.UpdateLibrariesIndexResponse_Result { + req := &rpc.UpdateLibrariesIndexRequest{Instance: inst} + stream, resp := commands.UpdateLibrariesIndexStreamResponseToCallbackFunction(ctx, feedback.ProgressBar()) + if err := srv.UpdateLibrariesIndex(req, stream); err != nil { feedback.Fatal(tr("Error updating library index: %v", err), feedback.ErrGeneric) } - return resp + return resp() } type libUpdateIndexResult struct { diff --git a/internal/cli/update/update.go b/internal/cli/update/update.go index 944a027fc5e..82b94135f74 100644 --- a/internal/cli/update/update.go +++ b/internal/cli/update/update.go @@ -53,7 +53,7 @@ func runUpdateCommand(srv rpc.ArduinoCoreServiceServer, showOutdated bool) { ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) - lib.UpdateIndex(inst) + lib.UpdateIndex(ctx, srv, inst) core.UpdateIndex(ctx, srv, inst) instance.Init(ctx, srv, inst) if showOutdated { From 738ad7c875f7a09e6b6bbc8a67d731fbe0d673e9 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 18 Mar 2024 13:37:09 +0100 Subject: [PATCH 22/56] Inlining methods in ArduinoCoreServiceImpl (part 13: NewSketch, LoadSketch, SetSketchDefaults, ArchiveSketch) --- commands/service.go | 21 --------------------- commands/service_set_sketch_defaults.go | 2 +- commands/service_sketch_archive.go | 8 ++++---- commands/service_sketch_load.go | 4 ++-- commands/service_sketch_load_test.go | 7 ++++--- commands/service_sketch_new.go | 2 +- commands/service_sketch_new_test.go | 21 +++++++++++++-------- internal/cli/arguments/profiles.go | 11 ++++++++--- internal/cli/arguments/sketch.go | 7 +++---- internal/cli/board/attach.go | 4 ++-- internal/cli/cli.go | 2 +- internal/cli/compile/compile.go | 5 +++-- internal/cli/debug/debug.go | 5 +++-- internal/cli/monitor/monitor.go | 5 +++-- internal/cli/sketch/archive.go | 16 +++++++++------- internal/cli/sketch/new.go | 12 +++++++----- internal/cli/sketch/sketch.go | 7 ++++--- internal/cli/upload/upload.go | 5 +++-- 18 files changed, 71 insertions(+), 73 deletions(-) diff --git a/commands/service.go b/commands/service.go index 997f5f88a63..581928fdba9 100644 --- a/commands/service.go +++ b/commands/service.go @@ -42,22 +42,6 @@ func (s *arduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionReq return &rpc.VersionResponse{Version: s.versionString}, nil } -// NewSketch FIXMEDOC -func (s *arduinoCoreServerImpl) NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { - return NewSketch(ctx, req) -} - -// LoadSketch FIXMEDOC -func (s *arduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { - resp, err := LoadSketch(ctx, req) - return &rpc.LoadSketchResponse{Sketch: resp}, err -} - -// SetSketchDefaults FIXMEDOC -func (s *arduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) { - return SetSketchDefaults(ctx, req) -} - // Upload FIXMEDOC func (s *arduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.ArduinoCoreService_UploadServer) error { syncSend := NewSynchronizedSend(stream.Send) @@ -146,11 +130,6 @@ func (s *arduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Co return ListProgrammersAvailableForUpload(ctx, req) } -// ArchiveSketch FIXMEDOC -func (s *arduinoCoreServerImpl) ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { - return ArchiveSketch(ctx, req) -} - // EnumerateMonitorPortSettings FIXMEDOC func (s *arduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { return EnumerateMonitorPortSettings(ctx, req) diff --git a/commands/service_set_sketch_defaults.go b/commands/service_set_sketch_defaults.go index e90b1ef58c4..6b3ba044899 100644 --- a/commands/service_set_sketch_defaults.go +++ b/commands/service_set_sketch_defaults.go @@ -26,7 +26,7 @@ import ( // SetSketchDefaults updates the sketch project file (sketch.yaml) with the given defaults // for the values `default_fqbn`, `default_port`, and `default_protocol`. -func SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) { +func (s *arduinoCoreServerImpl) SetSketchDefaults(ctx context.Context, req *rpc.SetSketchDefaultsRequest) (*rpc.SetSketchDefaultsResponse, error) { sk, err := sketch.New(paths.New(req.GetSketchPath())) if err != nil { return nil, &cmderrors.CantOpenSketchError{Cause: err} diff --git a/commands/service_sketch_archive.go b/commands/service_sketch_archive.go index b2b28ae4bdd..67515406382 100644 --- a/commands/service_sketch_archive.go +++ b/commands/service_sketch_archive.go @@ -29,7 +29,7 @@ import ( ) // ArchiveSketch FIXMEDOC -func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.ArchiveSketchResponse, error) { +func (s *arduinoCoreServerImpl) 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 @@ -38,13 +38,13 @@ func ArchiveSketch(ctx context.Context, req *rpc.ArchiveSketchRequest) (*rpc.Arc sketchPath = paths.New(".") } - s, err := sketch.New(sketchPath) + sk, err := sketch.New(sketchPath) if err != nil { return nil, &cmderrors.CantOpenSketchError{Cause: err} } - sketchPath = s.FullPath - sketchName = s.Name + sketchPath = sk.FullPath + sketchName = sk.Name archivePath := paths.New(req.GetArchivePath()) if archivePath == nil { diff --git a/commands/service_sketch_load.go b/commands/service_sketch_load.go index ffca3016715..8360ce7adfd 100644 --- a/commands/service_sketch_load.go +++ b/commands/service_sketch_load.go @@ -25,10 +25,10 @@ import ( ) // LoadSketch collects and returns all information about a sketch -func LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.Sketch, error) { +func (s *arduinoCoreServerImpl) LoadSketch(ctx context.Context, req *rpc.LoadSketchRequest) (*rpc.LoadSketchResponse, error) { sk, err := sketch.New(paths.New(req.GetSketchPath())) if err != nil { return nil, &cmderrors.CantOpenSketchError{Cause: err} } - return sk.ToRpc(), nil + return &rpc.LoadSketchResponse{Sketch: sk.ToRpc()}, nil } diff --git a/commands/service_sketch_load_test.go b/commands/service_sketch_load_test.go index 9d058e7035f..36bb58ea351 100644 --- a/commands/service_sketch_load_test.go +++ b/commands/service_sketch_load_test.go @@ -24,10 +24,11 @@ import ( ) func TestLoadSketchProfiles(t *testing.T) { - loadResp, err := LoadSketch(context.Background(), &commands.LoadSketchRequest{ + srv := NewArduinoCoreServer("") + loadResp, err := srv.LoadSketch(context.Background(), &commands.LoadSketchRequest{ SketchPath: "./testdata/sketch_with_profile", }) require.NoError(t, err) - require.Len(t, loadResp.GetProfiles(), 2) - require.Equal(t, loadResp.GetDefaultProfile().GetName(), "nanorp") + require.Len(t, loadResp.GetSketch().GetProfiles(), 2) + require.Equal(t, loadResp.GetSketch().GetDefaultProfile().GetName(), "nanorp") } diff --git a/commands/service_sketch_new.go b/commands/service_sketch_new.go index 1a39615c9eb..a8eb518a815 100644 --- a/commands/service_sketch_new.go +++ b/commands/service_sketch_new.go @@ -43,7 +43,7 @@ var invalidNames = []string{"CON", "PRN", "AUX", "NUL", "COM0", "COM1", "COM2", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"} // NewSketch creates a new sketch via gRPC -func NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { +func (s *arduinoCoreServerImpl) NewSketch(ctx context.Context, req *rpc.NewSketchRequest) (*rpc.NewSketchResponse, error) { var sketchesDir string if len(req.GetSketchDir()) > 0 { sketchesDir = req.GetSketchDir() diff --git a/commands/service_sketch_new_test.go b/commands/service_sketch_new_test.go index 0ba8b56767c..0d0b3e05aa6 100644 --- a/commands/service_sketch_new_test.go +++ b/commands/service_sketch_new_test.go @@ -20,7 +20,7 @@ import ( "fmt" "testing" - "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/stretchr/testify/require" ) @@ -34,8 +34,10 @@ func Test_SketchNameWrongPattern(t *testing.T) { "||||||||||||||", ",`hack[}attempt{];", } + + srv := NewArduinoCoreServer("") for _, name := range invalidNames { - _, err := NewSketch(context.Background(), &commands.NewSketchRequest{ + _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, SketchDir: t.TempDir(), }) @@ -46,9 +48,9 @@ func Test_SketchNameWrongPattern(t *testing.T) { } func Test_SketchNameEmpty(t *testing.T) { - emptyName := "" - _, err := NewSketch(context.Background(), &commands.NewSketchRequest{ - SketchName: emptyName, + srv := NewArduinoCoreServer("") + _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ + SketchName: "", SketchDir: t.TempDir(), }) @@ -60,7 +62,8 @@ func Test_SketchNameTooLong(t *testing.T) { for i := range tooLongName { tooLongName[i] = 'a' } - _, err := NewSketch(context.Background(), &commands.NewSketchRequest{ + srv := NewArduinoCoreServer("") + _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: string(tooLongName), SketchDir: t.TempDir(), }) @@ -83,8 +86,9 @@ func Test_SketchNameOk(t *testing.T) { "_hello_world", string(lengthLimitName), } + srv := NewArduinoCoreServer("") for _, name := range validNames { - _, err := NewSketch(context.Background(), &commands.NewSketchRequest{ + _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, SketchDir: t.TempDir(), }) @@ -95,8 +99,9 @@ func Test_SketchNameOk(t *testing.T) { func Test_SketchNameReserved(t *testing.T) { invalidNames := []string{"CON", "PRN", "AUX", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"} + srv := NewArduinoCoreServer("") for _, name := range invalidNames { - _, err := NewSketch(context.Background(), &commands.NewSketchRequest{ + _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, SketchDir: t.TempDir(), }) diff --git a/internal/cli/arguments/profiles.go b/internal/cli/arguments/profiles.go index 6516cbdec08..1631fe35d9f 100644 --- a/internal/cli/arguments/profiles.go +++ b/internal/cli/arguments/profiles.go @@ -15,7 +15,12 @@ package arguments -import "github.com/spf13/cobra" +import ( + "context" + + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "github.com/spf13/cobra" +) // Profile contains the profile flag data. // This is useful so all flags used by commands that need @@ -25,14 +30,14 @@ type Profile struct { } // AddToCommand adds the flags used to set fqbn to the specified Command -func (f *Profile) AddToCommand(cmd *cobra.Command) { +func (f *Profile) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&f.profile, "profile", "m", "", tr("Sketch profile to use")) cmd.RegisterFlagCompletionFunc("profile", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { var sketchProfile string if len(args) > 0 { sketchProfile = args[0] } - return GetSketchProfiles(sketchProfile), cobra.ShellCompDirectiveDefault + return GetSketchProfiles(context.Background(), srv, sketchProfile), cobra.ShellCompDirectiveDefault }) } diff --git a/internal/cli/arguments/sketch.go b/internal/cli/arguments/sketch.go index 57a3463bcc3..e946c4fd6a2 100644 --- a/internal/cli/arguments/sketch.go +++ b/internal/cli/arguments/sketch.go @@ -18,7 +18,6 @@ package arguments import ( "context" - "github.com/arduino/arduino-cli/commands" f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -44,7 +43,7 @@ func InitSketchPath(path string) (sketchPath *paths.Path) { // GetSketchProfiles is an helper function useful to autocomplete. // It returns the profile names set in the sketch.yaml -func GetSketchProfiles(sketchPath string) []string { +func GetSketchProfiles(ctx context.Context, srv rpc.ArduinoCoreServiceServer, sketchPath string) []string { if sketchPath == "" { if wd, _ := paths.Getwd(); wd != nil && wd.String() != "" { sketchPath = wd.String() @@ -52,10 +51,10 @@ func GetSketchProfiles(sketchPath string) []string { return nil } } - sk, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath}) + resp, err := srv.LoadSketch(ctx, &rpc.LoadSketchRequest{SketchPath: sketchPath}) if err != nil { return nil } - profiles := sk.GetProfiles() + profiles := resp.GetSketch().GetProfiles() return f.Map(profiles, (*rpc.SketchProfile).GetName) } diff --git a/internal/cli/board/attach.go b/internal/cli/board/attach.go index 627f014760c..9c5a8dc268e 100644 --- a/internal/cli/board/attach.go +++ b/internal/cli/board/attach.go @@ -20,7 +20,6 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -56,10 +55,11 @@ func initAttachCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } func runAttachCommand(srv rpc.ArduinoCoreServiceServer, path string, port *arguments.Port, fqbn string, programmer *arguments.Programmer) { + ctx := context.Background() sketchPath := arguments.InitSketchPath(path) portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(nil, srv, "", "") - newDefaults, err := commands.SetSketchDefaults(context.Background(), &rpc.SetSketchDefaultsRequest{ + newDefaults, err := srv.SetSketchDefaults(ctx, &rpc.SetSketchDefaultsRequest{ SketchPath: sketchPath.String(), DefaultFqbn: fqbn, DefaultProgrammer: programmer.GetProgrammer(), diff --git a/internal/cli/cli.go b/internal/cli/cli.go index e0e7cd27ecd..851ced7ddc5 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -125,7 +125,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cmd.AddCommand(lib.NewCommand(srv)) cmd.AddCommand(monitor.NewCommand(srv)) cmd.AddCommand(outdated.NewCommand(srv)) - cmd.AddCommand(sketch.NewCommand()) + cmd.AddCommand(sketch.NewCommand(srv)) cmd.AddCommand(update.NewCommand(srv)) cmd.AddCommand(upgrade.NewCommand(srv)) cmd.AddCommand(upload.NewCommand(srv)) diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 1a72719dac9..d0cd6ca4c8b 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -94,7 +94,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } fqbnArg.AddToCommand(compileCommand, srv) - profileArg.AddToCommand(compileCommand) + profileArg.AddToCommand(compileCommand, srv) compileCommand.Flags().BoolVar(&dumpProfile, "dump-profile", false, tr("Create and print a profile configuration from the build.")) showPropertiesArg.AddToCommand(compileCommand) compileCommand.Flags().BoolVar(&preprocess, "preprocess", false, tr("Print preprocessed code to stdout instead of compiling.")) @@ -159,10 +159,11 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer } sketchPath := arguments.InitSketchPath(path) - sk, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + resp, err := srv.LoadSketch(ctx, &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } + sk := resp.GetSketch() feedback.WarnAboutDeprecatedFiles(sk) var inst *rpc.Instance diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index 90d03cd459c..cb0f37fce58 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -64,7 +64,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { fqbnArg.AddToCommand(debugCommand, srv) portArgs.AddToCommand(debugCommand, srv) programmer.AddToCommand(debugCommand, srv) - profileArg.AddToCommand(debugCommand) + profileArg.AddToCommand(debugCommand, srv) debugCommand.Flags().StringVar(&interpreter, "interpreter", "console", tr("Debug interpreter e.g.: %s", "console, mi, mi1, mi2, mi3")) debugCommand.Flags().StringVarP(&importDir, "input-dir", "", "", tr("Directory containing binaries for debug.")) debugCommand.Flags().BoolVarP(&printInfo, "info", "I", false, tr("Show metadata about the debug session instead of starting the debugger.")) @@ -83,10 +83,11 @@ func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs * } sketchPath := arguments.InitSketchPath(path) - sk, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + resp, err := srv.LoadSketch(ctx, &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } + sk := resp.GetSketch() feedback.WarnAboutDeprecatedFiles(sk) var inst *rpc.Instance diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 94c495068c5..975f68ba1dd 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -70,7 +70,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { }, } portArgs.AddToCommand(monitorCommand, srv) - profileArg.AddToCommand(monitorCommand) + profileArg.AddToCommand(monitorCommand, srv) monitorCommand.Flags().BoolVar(&raw, "raw", false, tr("Set terminal in raw mode (unbuffered).")) monitorCommand.Flags().BoolVar(&describe, "describe", false, tr("Show all the settings of the communication port.")) monitorCommand.Flags().StringSliceVarP(&configs, "config", "c", []string{}, tr("Configure communication port settings. The format is =[,=]...")) @@ -105,13 +105,14 @@ func runMonitorCmd( // If only --port is set we read the fqbn in the following order: default_fqbn -> discovery // If only --fqbn is set we read the port in the following order: default_port sketchPath := arguments.InitSketchPath(sketchPathArg) - sketch, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + resp, err := srv.LoadSketch(ctx, &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if err != nil && !portArgs.IsPortFlagSet() { feedback.Fatal( tr("Error getting default port from `sketch.yaml`. Check if you're in the correct sketch folder or provide the --port flag: %s", err), feedback.ErrGeneric, ) } + sketch := resp.GetSketch() if sketch != nil { defaultPort, defaultProtocol = sketch.GetDefaultPort(), sketch.GetDefaultProtocol() } diff --git a/internal/cli/sketch/archive.go b/internal/cli/sketch/archive.go index 9b8836daba3..2de1cd0ddaf 100644 --- a/internal/cli/sketch/archive.go +++ b/internal/cli/sketch/archive.go @@ -20,7 +20,6 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -29,7 +28,7 @@ import ( ) // initArchiveCommand creates a new `archive` command -func initArchiveCommand() *cobra.Command { +func initArchiveCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var includeBuildDir, overwrite bool archiveCommand := &cobra.Command{ @@ -43,7 +42,9 @@ func initArchiveCommand() *cobra.Command { " " + os.Args[0] + " archive /home/user/Arduino/MySketch\n" + " " + os.Args[0] + " archive /home/user/Arduino/MySketch /home/user/MySketchArchive.zip", Args: cobra.MaximumNArgs(2), - Run: func(cmd *cobra.Command, args []string) { runArchiveCommand(args, includeBuildDir, overwrite) }, + Run: func(cmd *cobra.Command, args []string) { + runArchiveCommand(srv, args, includeBuildDir, overwrite) + }, } archiveCommand.Flags().BoolVar(&includeBuildDir, "include-build-dir", false, tr("Includes %s directory in the archive.", "build")) @@ -52,9 +53,9 @@ func initArchiveCommand() *cobra.Command { return archiveCommand } -func runArchiveCommand(args []string, includeBuildDir bool, overwrite bool) { +func runArchiveCommand(srv rpc.ArduinoCoreServiceServer, args []string, includeBuildDir bool, overwrite bool) { logrus.Info("Executing `arduino-cli sketch archive`") - + ctx := context.Background() sketchPathArg := "" if len(args) > 0 { sketchPathArg = args[0] @@ -66,13 +67,14 @@ func runArchiveCommand(args []string, includeBuildDir bool, overwrite bool) { } sketchPath := arguments.InitSketchPath(sketchPathArg) - sk, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + resp, err := srv.LoadSketch(ctx, &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } + sk := resp.GetSketch() feedback.WarnAboutDeprecatedFiles(sk) - if _, err := commands.ArchiveSketch(context.Background(), + if _, err := srv.ArchiveSketch(ctx, &rpc.ArchiveSketchRequest{ SketchPath: sketchPath.String(), ArchivePath: archivePathArg, diff --git a/internal/cli/sketch/new.go b/internal/cli/sketch/new.go index 1bfdf36c764..5be99e4308b 100644 --- a/internal/cli/sketch/new.go +++ b/internal/cli/sketch/new.go @@ -20,7 +20,6 @@ import ( "os" "strings" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/arduino/globals" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -29,7 +28,7 @@ import ( "github.com/spf13/cobra" ) -func initNewCommand() *cobra.Command { +func initNewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var overwrite bool newCommand := &cobra.Command{ @@ -38,7 +37,9 @@ func initNewCommand() *cobra.Command { Long: tr("Create a new Sketch"), Example: " " + os.Args[0] + " sketch new MultiBlinker", Args: cobra.ExactArgs(1), - Run: func(cmd *cobra.Command, args []string) { runNewCommand(args, overwrite) }, + Run: func(cmd *cobra.Command, args []string) { + runNewCommand(srv, args, overwrite) + }, } newCommand.Flags().BoolVarP(&overwrite, "overwrite", "f", false, tr("Overwrites an existing .ino sketch.")) @@ -46,7 +47,8 @@ func initNewCommand() *cobra.Command { return newCommand } -func runNewCommand(args []string, overwrite bool) { +func runNewCommand(srv rpc.ArduinoCoreServiceServer, args []string, overwrite bool) { + ctx := context.Background() logrus.Info("Executing `arduino-cli sketch new`") // Trim to avoid issues if user creates a sketch adding the .ino extesion to the name inputSketchName := args[0] @@ -72,7 +74,7 @@ func runNewCommand(args []string, overwrite bool) { sketchName = sketchDirPath.Base() } - _, err = commands.NewSketch(context.Background(), &rpc.NewSketchRequest{ + _, err = srv.NewSketch(ctx, &rpc.NewSketchRequest{ SketchName: sketchName, SketchDir: sketchDir, Overwrite: overwrite, diff --git a/internal/cli/sketch/sketch.go b/internal/cli/sketch/sketch.go index 5d8da390eed..2530c72247d 100644 --- a/internal/cli/sketch/sketch.go +++ b/internal/cli/sketch/sketch.go @@ -19,13 +19,14 @@ import ( "os" "github.com/arduino/arduino-cli/internal/i18n" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) var tr = i18n.Tr // NewCommand created a new `sketch` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { sketchCommand := &cobra.Command{ Use: "sketch", Short: tr("Arduino CLI sketch commands."), @@ -33,8 +34,8 @@ func NewCommand() *cobra.Command { Example: " " + os.Args[0] + " sketch new MySketch", } - sketchCommand.AddCommand(initNewCommand()) - sketchCommand.AddCommand(initArchiveCommand()) + sketchCommand.AddCommand(initNewCommand(srv)) + sketchCommand.AddCommand(initArchiveCommand(srv)) return sketchCommand } diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index ed49145b98c..751083aebd5 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -69,7 +69,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { fqbnArg.AddToCommand(uploadCommand, srv) portArgs.AddToCommand(uploadCommand, srv) - profileArg.AddToCommand(uploadCommand) + profileArg.AddToCommand(uploadCommand, srv) uploadCommand.Flags().StringVarP(&importDir, "input-dir", "", "", tr("Directory containing binaries to upload.")) uploadCommand.Flags().StringVarP(&importFile, "input-file", "i", "", tr("Binary file to upload.")) uploadCommand.Flags().BoolVarP(&verify, "verify", "t", false, tr("Verify uploaded binary after the upload.")) @@ -91,7 +91,8 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie path = args[0] } sketchPath := arguments.InitSketchPath(path) - sketch, err := commands.LoadSketch(context.Background(), &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + resp, err := srv.LoadSketch(ctx, &rpc.LoadSketchRequest{SketchPath: sketchPath.String()}) + sketch := resp.GetSketch() if importDir == "" && importFile == "" { if err != nil { feedback.Fatal(tr("Error during Upload: %v", err), feedback.ErrGeneric) From 0442319a3ceb1adbbdb6ea54bc73f2f92d99b5e1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 18 Mar 2024 15:52:44 +0100 Subject: [PATCH 23/56] Inlining methods in ArduinoCoreServiceImpl (part 14: Upload, UploadUsingProgrammer, BurnBootloader) --- commands/service.go | 78 ----------------- commands/service_upload.go | 87 ++++++++++++++++--- commands/service_upload_burnbootloader.go | 44 ++++++++-- internal/cli/burnbootloader/burnbootloader.go | 5 +- internal/cli/compile/compile.go | 5 +- internal/cli/upload/upload.go | 5 +- 6 files changed, 122 insertions(+), 102 deletions(-) diff --git a/commands/service.go b/commands/service.go index 581928fdba9..cf2980f12b3 100644 --- a/commands/service.go +++ b/commands/service.go @@ -42,89 +42,11 @@ func (s *arduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionReq return &rpc.VersionResponse{Version: s.versionString}, nil } -// Upload FIXMEDOC -func (s *arduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.ArduinoCoreService_UploadServer) error { - syncSend := NewSynchronizedSend(stream.Send) - outStream := feedStreamTo(func(data []byte) { - syncSend.Send(&rpc.UploadResponse{ - Message: &rpc.UploadResponse_OutStream{OutStream: data}, - }) - }) - errStream := feedStreamTo(func(data []byte) { - syncSend.Send(&rpc.UploadResponse{ - Message: &rpc.UploadResponse_ErrStream{ErrStream: data}, - }) - }) - res, err := Upload(stream.Context(), req, outStream, errStream) - outStream.Close() - errStream.Close() - if res != nil { - syncSend.Send(&rpc.UploadResponse{ - Message: &rpc.UploadResponse_Result{ - Result: res, - }, - }) - } - return err -} - -// UploadUsingProgrammer FIXMEDOC -func (s *arduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgrammerRequest, stream rpc.ArduinoCoreService_UploadUsingProgrammerServer) error { - syncSend := NewSynchronizedSend(stream.Send) - outStream := feedStreamTo(func(data []byte) { - syncSend.Send(&rpc.UploadUsingProgrammerResponse{ - Message: &rpc.UploadUsingProgrammerResponse_OutStream{ - OutStream: data, - }, - }) - }) - errStream := feedStreamTo(func(data []byte) { - syncSend.Send(&rpc.UploadUsingProgrammerResponse{ - Message: &rpc.UploadUsingProgrammerResponse_ErrStream{ - ErrStream: data, - }, - }) - }) - err := UploadUsingProgrammer(stream.Context(), req, outStream, errStream) - outStream.Close() - errStream.Close() - if err != nil { - return err - } - return nil -} - // SupportedUserFields FIXMEDOC func (s *arduinoCoreServerImpl) SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsRequest) (*rpc.SupportedUserFieldsResponse, error) { return SupportedUserFields(ctx, req) } -// BurnBootloader FIXMEDOC -func (s *arduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, stream rpc.ArduinoCoreService_BurnBootloaderServer) error { - syncSend := NewSynchronizedSend(stream.Send) - outStream := feedStreamTo(func(data []byte) { - syncSend.Send(&rpc.BurnBootloaderResponse{ - Message: &rpc.BurnBootloaderResponse_OutStream{ - OutStream: data, - }, - }) - }) - errStream := feedStreamTo(func(data []byte) { - syncSend.Send(&rpc.BurnBootloaderResponse{ - Message: &rpc.BurnBootloaderResponse_ErrStream{ - ErrStream: data, - }, - }) - }) - resp, err := BurnBootloader(stream.Context(), req, outStream, errStream) - outStream.Close() - errStream.Close() - if err != nil { - return err - } - return syncSend.Send(resp) -} - // ListProgrammersAvailableForUpload FIXMEDOC func (s *arduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { return ListProgrammersAvailableForUpload(ctx, req) diff --git a/commands/service_upload.go b/commands/service_upload.go index a364f3f88f2..7990b8aaf79 100644 --- a/commands/service_upload.go +++ b/commands/service_upload.go @@ -120,8 +120,33 @@ func getUserFields(toolID string, platformRelease *cores.PlatformRelease) []*rpc return userFields } -// Upload FIXMEDOC -func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, errStream io.Writer) (*rpc.UploadResult, error) { +// UploadToServerStreams return a server stream that forwards the output and error streams to the provided writers. +// It also returns a function that can be used to retrieve the result of the upload. +func UploadToServerStreams(ctx context.Context, outStream io.Writer, errStream io.Writer) (rpc.ArduinoCoreService_UploadServer, func() *rpc.UploadResult) { + var result *rpc.UploadResult + stream := streamResponseToCallback(ctx, func(resp *rpc.UploadResponse) error { + if errData := resp.GetErrStream(); len(errData) > 0 { + _, err := errStream.Write(errData) + return err + } + if outData := resp.GetOutStream(); len(outData) > 0 { + _, err := outStream.Write(outData) + return err + } + if res := resp.GetResult(); res != nil { + result = res + } + return nil + }) + return stream, func() *rpc.UploadResult { + return result + } +} + +// Upload performs the upload of a sketch to a board. +func (s *arduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.ArduinoCoreService_UploadServer) error { + syncSend := NewSynchronizedSend(stream.Send) + logrus.Tracef("Upload %s on %s started", req.GetSketchPath(), req.GetFqbn()) // TODO: make a generic function to extract sketch from request @@ -129,12 +154,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, &cmderrors.CantOpenSketchError{Cause: err} + return &cmderrors.CantOpenSketchError{Cause: err} } pme, pmeRelease, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { - return nil, err + return err } defer pmeRelease() @@ -151,6 +176,20 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er programmer = sk.GetDefaultProgrammer() } + outStream := feedStreamTo(func(data []byte) { + syncSend.Send(&rpc.UploadResponse{ + Message: &rpc.UploadResponse_OutStream{OutStream: data}, + }) + }) + defer outStream.Close() + errStream := feedStreamTo(func(data []byte) { + syncSend.Send(&rpc.UploadResponse{ + Message: &rpc.UploadResponse_ErrStream{ErrStream: data}, + }) + }) + defer errStream.Close() + // TODO: inject context + // ctx := stream.Context() updatedPort, err := runProgramAction( pme, sk, @@ -168,22 +207,45 @@ func Upload(ctx context.Context, req *rpc.UploadRequest, outStream io.Writer, er req.GetUserFields(), ) if err != nil { - return nil, err + return err } - - return &rpc.UploadResult{ - UpdatedUploadPort: updatedPort, - }, nil + return syncSend.Send(&rpc.UploadResponse{ + Message: &rpc.UploadResponse_Result{ + Result: &rpc.UploadResult{ + UpdatedUploadPort: updatedPort, + }, + }, + }) } // UploadUsingProgrammer FIXMEDOC -func UploadUsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRequest, outStream io.Writer, errStream io.Writer) error { +func (s *arduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgrammerRequest, stream rpc.ArduinoCoreService_UploadUsingProgrammerServer) error { + syncSend := NewSynchronizedSend(stream.Send) + streamAdapter := streamResponseToCallback(stream.Context(), func(resp *rpc.UploadResponse) error { + if errData := resp.GetErrStream(); len(errData) > 0 { + syncSend.Send(&rpc.UploadUsingProgrammerResponse{ + Message: &rpc.UploadUsingProgrammerResponse_ErrStream{ + ErrStream: errData, + }, + }) + } + if outData := resp.GetOutStream(); len(outData) > 0 { + syncSend.Send(&rpc.UploadUsingProgrammerResponse{ + Message: &rpc.UploadUsingProgrammerResponse_OutStream{ + OutStream: outData, + }, + }) + } + // resp.GetResult() is ignored + return nil + }) + logrus.Tracef("Upload using programmer %s on %s started", req.GetSketchPath(), req.GetFqbn()) if req.GetProgrammer() == "" { return &cmderrors.MissingProgrammerError{} } - _, err := Upload(ctx, &rpc.UploadRequest{ + return s.Upload(&rpc.UploadRequest{ Instance: req.GetInstance(), SketchPath: req.GetSketchPath(), ImportFile: req.GetImportFile(), @@ -194,8 +256,7 @@ func UploadUsingProgrammer(ctx context.Context, req *rpc.UploadUsingProgrammerRe Verbose: req.GetVerbose(), Verify: req.GetVerify(), UserFields: req.GetUserFields(), - }, outStream, errStream) - return err + }, streamAdapter) } func runProgramAction(pme *packagemanager.Explorer, diff --git a/commands/service_upload_burnbootloader.go b/commands/service_upload_burnbootloader.go index 7d9c34cb7cc..96352e57fd5 100644 --- a/commands/service_upload_burnbootloader.go +++ b/commands/service_upload_burnbootloader.go @@ -24,8 +24,42 @@ import ( "github.com/sirupsen/logrus" ) -// BurnBootloader FIXMEDOC -func BurnBootloader(ctx context.Context, req *rpc.BurnBootloaderRequest, outStream io.Writer, errStream io.Writer) (*rpc.BurnBootloaderResponse, error) { +// BurnBootloaderToServerStreams return a server stream that forwards the output and error streams to the provided io.Writers +func BurnBootloaderToServerStreams(ctx context.Context, outStrem, errStream io.Writer) rpc.ArduinoCoreService_BurnBootloaderServer { + stream := streamResponseToCallback(ctx, func(resp *rpc.BurnBootloaderResponse) error { + if outData := resp.GetOutStream(); len(outData) > 0 { + _, err := outStrem.Write(outData) + return err + } + if errData := resp.GetErrStream(); len(errData) > 0 { + _, err := errStream.Write(errData) + return err + } + return nil + }) + return stream +} + +// BurnBootloader performs the burn bootloader action +func (s *arduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, stream rpc.ArduinoCoreService_BurnBootloaderServer) error { + syncSend := NewSynchronizedSend(stream.Send) + outStream := feedStreamTo(func(data []byte) { + syncSend.Send(&rpc.BurnBootloaderResponse{ + Message: &rpc.BurnBootloaderResponse_OutStream{ + OutStream: data, + }, + }) + }) + defer outStream.Close() + errStream := feedStreamTo(func(data []byte) { + syncSend.Send(&rpc.BurnBootloaderResponse{ + Message: &rpc.BurnBootloaderResponse_ErrStream{ + ErrStream: data, + }, + }) + }) + defer errStream.Close() + logrus. WithField("fqbn", req.GetFqbn()). WithField("port", req.GetPort()). @@ -34,7 +68,7 @@ func BurnBootloader(ctx context.Context, req *rpc.BurnBootloaderRequest, outStre pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { - return nil, err + return err } defer release() @@ -54,7 +88,7 @@ func BurnBootloader(ctx context.Context, req *rpc.BurnBootloaderRequest, outStre req.GetDryRun(), map[string]string{}, // User fields ); err != nil { - return nil, err + return err } - return &rpc.BurnBootloaderResponse{}, nil + return syncSend.Send(&rpc.BurnBootloaderResponse{}) } diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index 21ea22dbf3f..c17a822b3f4 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -78,7 +78,8 @@ func runBootloaderCommand(srv rpc.ArduinoCoreServiceServer) { } stdOut, stdErr, res := feedback.OutputStreams() - if _, err := commands.BurnBootloader(context.Background(), &rpc.BurnBootloaderRequest{ + stream := commands.BurnBootloaderToServerStreams(ctx, stdOut, stdErr) + if err := srv.BurnBootloader(&rpc.BurnBootloaderRequest{ Instance: instance, Fqbn: fqbn.String(), Port: discoveryPort, @@ -86,7 +87,7 @@ func runBootloaderCommand(srv rpc.ArduinoCoreServiceServer) { Verify: verify, Programmer: programmer.String(instance, srv, fqbn.String()), DryRun: dryRun, - }, stdOut, stdErr); err != nil { + }, stream); err != nil { errcode := feedback.ErrGeneric if errors.Is(err, &cmderrors.ProgrammerRequiredForUploadError{}) { errcode = feedback.ErrMissingProgrammer diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index d0cd6ca4c8b..e38ee620ac2 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -292,7 +292,8 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer UserFields: fields, } - if res, err := commands.Upload(context.Background(), uploadRequest, stdOut, stdErr); err != nil { + stream, streamRes := commands.UploadToServerStreams(ctx, stdOut, stdErr) + if err := srv.Upload(uploadRequest, stream); err != nil { errcode := feedback.ErrGeneric if errors.Is(err, &cmderrors.ProgrammerRequiredForUploadError{}) { errcode = feedback.ErrMissingProgrammer @@ -302,7 +303,7 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer } feedback.Fatal(tr("Error during Upload: %v", err), errcode) } else { - uploadRes = res + uploadRes = streamRes() } } diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index 751083aebd5..c7500adfe98 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -199,7 +199,8 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie DryRun: dryRun, UserFields: fields, } - if res, err := commands.Upload(context.Background(), req, stdOut, stdErr); err != nil { + stream, streamResp := commands.UploadToServerStreams(ctx, stdOut, stdErr) + if err := srv.Upload(req, stream); err != nil { errcode := feedback.ErrGeneric if errors.Is(err, &cmderrors.ProgrammerRequiredForUploadError{}) { errcode = feedback.ErrMissingProgrammer @@ -213,7 +214,7 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie feedback.PrintResult(&uploadResult{ Stdout: io.Stdout, Stderr: io.Stderr, - UpdatedUploadPort: result.NewPort(res.GetUpdatedUploadPort()), + UpdatedUploadPort: result.NewPort(streamResp().GetUpdatedUploadPort()), }) } } From 65ecbaf6e15b55c73795ad3f169d3b30763d2a3f Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 18 Mar 2024 19:16:42 +0100 Subject: [PATCH 24/56] Inlining methods in ArduinoCoreServiceImpl (part 15: SupportedUserFields, ListProgrammersAvailableForUpload, EnumerateMonitorPortSettings) --- commands/service.go | 17 +---------------- commands/service_monitor_settings.go | 2 +- commands/service_upload.go | 2 +- commands/service_upload_list_programmers.go | 2 +- internal/cli/arguments/completion.go | 3 +-- internal/cli/compile/compile.go | 2 +- internal/cli/monitor/monitor.go | 2 +- internal/cli/upload/upload.go | 2 +- 8 files changed, 8 insertions(+), 24 deletions(-) diff --git a/commands/service.go b/commands/service.go index cf2980f12b3..4c770c3113a 100644 --- a/commands/service.go +++ b/commands/service.go @@ -37,26 +37,11 @@ type arduinoCoreServerImpl struct { versionString string } -// Version FIXMEDOC +// Version returns the version of the Arduino CLI func (s *arduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionRequest) (*rpc.VersionResponse, error) { return &rpc.VersionResponse{Version: s.versionString}, nil } -// SupportedUserFields FIXMEDOC -func (s *arduinoCoreServerImpl) SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsRequest) (*rpc.SupportedUserFieldsResponse, error) { - return SupportedUserFields(ctx, req) -} - -// ListProgrammersAvailableForUpload FIXMEDOC -func (s *arduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { - return ListProgrammersAvailableForUpload(ctx, req) -} - -// EnumerateMonitorPortSettings FIXMEDOC -func (s *arduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { - return EnumerateMonitorPortSettings(ctx, req) -} - // CheckForArduinoCLIUpdates FIXMEDOC func (s *arduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, req *rpc.CheckForArduinoCLIUpdatesRequest) (*rpc.CheckForArduinoCLIUpdatesResponse, error) { return updatecheck.CheckForArduinoCLIUpdates(ctx, req) diff --git a/commands/service_monitor_settings.go b/commands/service_monitor_settings.go index d69164d281d..4eb71c7add9 100644 --- a/commands/service_monitor_settings.go +++ b/commands/service_monitor_settings.go @@ -25,7 +25,7 @@ import ( ) // EnumerateMonitorPortSettings returns a description of the configuration settings of a monitor port -func EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { +func (s *arduinoCoreServerImpl) EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitorPortSettingsRequest) (*rpc.EnumerateMonitorPortSettingsResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/commands/service_upload.go b/commands/service_upload.go index 7990b8aaf79..2c01f7edaef 100644 --- a/commands/service_upload.go +++ b/commands/service_upload.go @@ -41,7 +41,7 @@ import ( // SupportedUserFields returns a SupportedUserFieldsResponse containing all the UserFields supported // 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) { +func (s *arduinoCoreServerImpl) SupportedUserFields(ctx context.Context, req *rpc.SupportedUserFieldsRequest) (*rpc.SupportedUserFieldsResponse, error) { if req.GetProtocol() == "" { return nil, &cmderrors.MissingPortProtocolError{} } diff --git a/commands/service_upload_list_programmers.go b/commands/service_upload_list_programmers.go index 0e02d36c25a..f05142cf147 100644 --- a/commands/service_upload_list_programmers.go +++ b/commands/service_upload_list_programmers.go @@ -25,7 +25,7 @@ import ( ) // ListProgrammersAvailableForUpload FIXMEDOC -func ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { +func (s *arduinoCoreServerImpl) ListProgrammersAvailableForUpload(ctx context.Context, req *rpc.ListProgrammersAvailableForUploadRequest) (*rpc.ListProgrammersAvailableForUploadResponse, error) { pme, release, err := instances.GetPackageManagerExplorer(req.GetInstance()) if err != nil { return nil, err diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index ad0f9d1f1b8..c42e817cc0f 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -18,7 +18,6 @@ package arguments import ( "context" - "github.com/arduino/arduino-cli/commands" f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -58,7 +57,7 @@ func GetInstalledProgrammers(ctx context.Context, srv rpc.ArduinoCoreServiceServ installedProgrammers := make(map[string]string) for _, board := range list.GetBoards() { - programmers, _ := commands.ListProgrammersAvailableForUpload(context.Background(), &rpc.ListProgrammersAvailableForUploadRequest{ + programmers, _ := srv.ListProgrammersAvailableForUpload(ctx, &rpc.ListProgrammersAvailableForUploadRequest{ Instance: inst, Fqbn: board.GetFqbn(), }) diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index e38ee620ac2..219a5e0b3ea 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -253,7 +253,7 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer var uploadRes *rpc.UploadResult if compileError == nil && uploadAfterCompile { - userFieldRes, err := commands.SupportedUserFields(context.Background(), &rpc.SupportedUserFieldsRequest{ + userFieldRes, err := srv.SupportedUserFields(ctx, &rpc.SupportedUserFieldsRequest{ Instance: inst, Fqbn: fqbn, Protocol: port.GetProtocol(), diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 975f68ba1dd..1e9eddbde53 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -147,7 +147,7 @@ func runMonitorCmd( feedback.FatalError(err, feedback.ErrGeneric) } - enumerateResp, err := commands.EnumerateMonitorPortSettings(context.Background(), &rpc.EnumerateMonitorPortSettingsRequest{ + enumerateResp, err := srv.EnumerateMonitorPortSettings(ctx, &rpc.EnumerateMonitorPortSettingsRequest{ Instance: inst, PortProtocol: portProtocol, Fqbn: fqbn, diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index c7500adfe98..b3d89259817 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -118,7 +118,7 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie defaultProtocol := sketch.GetDefaultProtocol() fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, inst, srv, defaultFQBN, defaultAddress, defaultProtocol) - userFieldRes, err := commands.SupportedUserFields(context.Background(), &rpc.SupportedUserFieldsRequest{ + userFieldRes, err := srv.SupportedUserFields(ctx, &rpc.SupportedUserFieldsRequest{ Instance: inst, Fqbn: fqbn, Protocol: port.GetProtocol(), From 0bdc07ab1841c2ffd34d16973618048993ff18c4 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 25 Mar 2024 15:08:32 +0100 Subject: [PATCH 25/56] Inlining methods in ArduinoCoreServiceImpl (part 16: CleanDownloadCacheDirectory, CheckForArduinoCLIUpdates) --- commands/service.go | 12 ------------ commands/{cache/clean.go => service_cache_clean.go} | 6 +++--- ...k_for_updates.go => service_check_for_updates.go} | 4 ++-- internal/cli/cache/cache.go | 5 +++-- internal/cli/cache/clean.go | 11 ++++++----- internal/cli/cli.go | 7 +++---- internal/cli/version/version.go | 11 ++++++----- 7 files changed, 23 insertions(+), 33 deletions(-) rename commands/{cache/clean.go => service_cache_clean.go} (81%) rename commands/{updatecheck/check_for_updates.go => service_check_for_updates.go} (95%) diff --git a/commands/service.go b/commands/service.go index 4c770c3113a..e8bf689d59a 100644 --- a/commands/service.go +++ b/commands/service.go @@ -18,8 +18,6 @@ package commands import ( "context" - "github.com/arduino/arduino-cli/commands/cache" - "github.com/arduino/arduino-cli/commands/updatecheck" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) @@ -41,13 +39,3 @@ type arduinoCoreServerImpl struct { func (s *arduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionRequest) (*rpc.VersionResponse, error) { return &rpc.VersionResponse{Version: s.versionString}, nil } - -// CheckForArduinoCLIUpdates FIXMEDOC -func (s *arduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, req *rpc.CheckForArduinoCLIUpdatesRequest) (*rpc.CheckForArduinoCLIUpdatesResponse, error) { - return updatecheck.CheckForArduinoCLIUpdates(ctx, req) -} - -// CleanDownloadCacheDirectory FIXMEDOC -func (s *arduinoCoreServerImpl) CleanDownloadCacheDirectory(ctx context.Context, req *rpc.CleanDownloadCacheDirectoryRequest) (*rpc.CleanDownloadCacheDirectoryResponse, error) { - return cache.CleanDownloadCacheDirectory(ctx, req) -} diff --git a/commands/cache/clean.go b/commands/service_cache_clean.go similarity index 81% rename from commands/cache/clean.go rename to commands/service_cache_clean.go index f823b56fffa..3cbdd488b6c 100644 --- a/commands/cache/clean.go +++ b/commands/service_cache_clean.go @@ -1,6 +1,6 @@ // This file is part of arduino-cli. // -// Copyright 2024 ARDUINO SA (http://www.arduino.cc/) +// 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. @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package cache +package commands import ( "context" @@ -23,7 +23,7 @@ import ( ) // CleanDownloadCacheDirectory clean the download cache directory (where archives are downloaded). -func CleanDownloadCacheDirectory(ctx context.Context, req *rpc.CleanDownloadCacheDirectoryRequest) (*rpc.CleanDownloadCacheDirectoryResponse, error) { +func (s *arduinoCoreServerImpl) CleanDownloadCacheDirectory(ctx context.Context, req *rpc.CleanDownloadCacheDirectoryRequest) (*rpc.CleanDownloadCacheDirectoryResponse, error) { cachePath := configuration.DownloadsDir(configuration.Settings) err := cachePath.RemoveAll() if err != nil { diff --git a/commands/updatecheck/check_for_updates.go b/commands/service_check_for_updates.go similarity index 95% rename from commands/updatecheck/check_for_updates.go rename to commands/service_check_for_updates.go index e7cda71638d..a53005c6456 100644 --- a/commands/updatecheck/check_for_updates.go +++ b/commands/service_check_for_updates.go @@ -13,7 +13,7 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package updatecheck +package commands import ( "context" @@ -29,7 +29,7 @@ import ( semver "go.bug.st/relaxed-semver" ) -func CheckForArduinoCLIUpdates(ctx context.Context, req *rpc.CheckForArduinoCLIUpdatesRequest) (*rpc.CheckForArduinoCLIUpdatesResponse, error) { +func (s *arduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, req *rpc.CheckForArduinoCLIUpdatesRequest) (*rpc.CheckForArduinoCLIUpdatesResponse, error) { currentVersion, err := semver.Parse(version.VersionInfo.VersionString) if err != nil { return nil, err diff --git a/internal/cli/cache/cache.go b/internal/cli/cache/cache.go index 43c9d775234..e6b14ebe90d 100644 --- a/internal/cli/cache/cache.go +++ b/internal/cli/cache/cache.go @@ -19,13 +19,14 @@ import ( "os" "github.com/arduino/arduino-cli/internal/i18n" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) var tr = i18n.Tr // NewCommand created a new `cache` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cacheCommand := &cobra.Command{ Use: "cache", Short: tr("Arduino cache commands."), @@ -34,7 +35,7 @@ func NewCommand() *cobra.Command { " " + os.Args[0] + " cache clean\n\n", } - cacheCommand.AddCommand(initCleanCommand()) + cacheCommand.AddCommand(initCleanCommand(srv)) return cacheCommand } diff --git a/internal/cli/cache/clean.go b/internal/cli/cache/clean.go index 32f788e87ed..4859676ae1c 100644 --- a/internal/cli/cache/clean.go +++ b/internal/cli/cache/clean.go @@ -19,29 +19,30 @@ import ( "context" "os" - "github.com/arduino/arduino-cli/commands/cache" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) -func initCleanCommand() *cobra.Command { +func initCleanCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cleanCommand := &cobra.Command{ Use: "clean", Short: tr("Delete Boards/Library Manager download cache."), Long: tr("Delete contents of the `directories.downloads` folder, where archive files are staged during installation of libraries and boards platforms."), Example: " " + os.Args[0] + " cache clean", Args: cobra.NoArgs, - Run: runCleanCommand, + Run: func(cmd *cobra.Command, args []string) { + runCleanCommand(srv) + }, } return cleanCommand } -func runCleanCommand(cmd *cobra.Command, args []string) { +func runCleanCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli cache clean`") - _, err := cache.CleanDownloadCacheDirectory(context.Background(), &rpc.CleanDownloadCacheDirectoryRequest{}) + _, err := srv.CleanDownloadCacheDirectory(context.Background(), &rpc.CleanDownloadCacheDirectoryRequest{}) if err != nil { feedback.Fatal(tr("Error cleaning caches: %v", err), feedback.ErrGeneric) } diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 851ced7ddc5..d2bb82305f6 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -22,7 +22,6 @@ import ( "os" "strings" - "github.com/arduino/arduino-cli/commands/updatecheck" "github.com/arduino/arduino-cli/internal/cli/board" "github.com/arduino/arduino-cli/internal/cli/burnbootloader" "github.com/arduino/arduino-cli/internal/cli/cache" @@ -85,7 +84,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { if cmd.Name() != "version" { updaterMessageChan = make(chan *semver.Version) go func() { - res, err := updatecheck.CheckForArduinoCLIUpdates(context.Background(), &rpc.CheckForArduinoCLIUpdatesRequest{}) + res, err := srv.CheckForArduinoCLIUpdates(context.Background(), &rpc.CheckForArduinoCLIUpdatesRequest{}) if err != nil { logrus.Warnf("Error checking for updates: %v", err) updaterMessageChan <- nil @@ -115,7 +114,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cmd.SetUsageTemplate(getUsageTemplate()) cmd.AddCommand(board.NewCommand(srv)) - cmd.AddCommand(cache.NewCommand()) + cmd.AddCommand(cache.NewCommand(srv)) cmd.AddCommand(compile.NewCommand(srv)) cmd.AddCommand(completion.NewCommand()) cmd.AddCommand(config.NewCommand()) @@ -131,7 +130,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cmd.AddCommand(upload.NewCommand(srv)) cmd.AddCommand(debug.NewCommand(srv)) cmd.AddCommand(burnbootloader.NewCommand(srv)) - cmd.AddCommand(version.NewCommand()) + cmd.AddCommand(version.NewCommand(srv)) cmd.AddCommand(feedback.NewCommand()) cmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, tr("Print the logs on the standard output.")) cmd.Flag("verbose").Hidden = true diff --git a/internal/cli/version/version.go b/internal/cli/version/version.go index 0f0c85872e0..9c8633aeee1 100644 --- a/internal/cli/version/version.go +++ b/internal/cli/version/version.go @@ -20,7 +20,6 @@ import ( "os" "strings" - "github.com/arduino/arduino-cli/commands/updatecheck" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/updater" "github.com/arduino/arduino-cli/internal/i18n" @@ -33,19 +32,21 @@ import ( var tr = i18n.Tr // NewCommand created a new `version` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { versionCommand := &cobra.Command{ Use: "version", Short: tr("Shows version number of Arduino CLI."), Long: tr("Shows the version number of Arduino CLI which is installed on your system."), Example: " " + os.Args[0] + " version", Args: cobra.NoArgs, - Run: runVersionCommand, + Run: func(cmd *cobra.Command, args []string) { + runVersionCommand(srv) + }, } return versionCommand } -func runVersionCommand(cmd *cobra.Command, args []string) { +func runVersionCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli version`") info := version.VersionInfo @@ -57,7 +58,7 @@ func runVersionCommand(cmd *cobra.Command, args []string) { } latestVersion := "" - res, err := updatecheck.CheckForArduinoCLIUpdates(context.Background(), &rpc.CheckForArduinoCLIUpdatesRequest{}) + res, err := srv.CheckForArduinoCLIUpdates(context.Background(), &rpc.CheckForArduinoCLIUpdatesRequest{}) if err != nil { feedback.Warning("Failed to check for updates: " + err.Error()) } else { From 3193b7c4bd8e256a36c15aefb64d104c69765aa8 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 18 Mar 2024 19:20:01 +0100 Subject: [PATCH 26/56] Made utility functions private and put them in their own file --- commands/service_board_listall.go | 4 ++-- commands/service_board_search.go | 8 ++++---- commands/service_library_download.go | 2 +- commands/service_library_install.go | 2 +- commands/service_library_resolve_deps.go | 2 +- commands/service_library_uninstall.go | 2 +- commands/service_platform_download.go | 2 +- commands/service_platform_install.go | 2 +- commands/service_platform_search.go | 4 ++-- commands/service_platform_upgrade.go | 4 ++-- commands/{core.go => utility_core.go} | 8 ++++---- ...rpc_streaming_helpers.go => utility_grpc_streaming.go} | 0 ...tcher.go => utility_libraries_index_search_matcher.go} | 0 commands/{version.go => utility_version.go} | 4 ++-- 14 files changed, 22 insertions(+), 22 deletions(-) rename commands/{core.go => utility_core.go} (91%) rename commands/{grpc_streaming_helpers.go => utility_grpc_streaming.go} (100%) rename commands/{libraries_index_search_matcher.go => utility_libraries_index_search_matcher.go} (100%) rename commands/{version.go => utility_version.go} (89%) diff --git a/commands/service_board_listall.go b/commands/service_board_listall.go index 5c9a8664ab3..93df1f4e338 100644 --- a/commands/service_board_listall.go +++ b/commands/service_board_listall.go @@ -46,8 +46,8 @@ func (s *arduinoCoreServerImpl) BoardListAll(ctx context.Context, req *rpc.Board } rpcPlatform := &rpc.Platform{ - Metadata: PlatformToRPCPlatformMetadata(platform), - Release: PlatformReleaseToRPC(installedPlatformRelease), + Metadata: platformToRPCPlatformMetadata(platform), + Release: platformReleaseToRPC(installedPlatformRelease), } toTest := []string{ diff --git a/commands/service_board_search.go b/commands/service_board_search.go index a3714b669c2..bbe4ca22529 100644 --- a/commands/service_board_search.go +++ b/commands/service_board_search.go @@ -67,8 +67,8 @@ func (s *arduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardS Fqbn: board.FQBN(), IsHidden: board.IsHidden(), Platform: &rpc.Platform{ - Metadata: PlatformToRPCPlatformMetadata(platform), - Release: PlatformReleaseToRPC(installedPlatformRelease), + Metadata: platformToRPCPlatformMetadata(platform), + Release: platformReleaseToRPC(installedPlatformRelease), }, }) } @@ -82,8 +82,8 @@ func (s *arduinoCoreServerImpl) BoardSearch(ctx context.Context, req *rpc.BoardS foundBoards = append(foundBoards, &rpc.BoardListItem{ Name: strings.Trim(board.Name, " \n"), Platform: &rpc.Platform{ - Metadata: PlatformToRPCPlatformMetadata(platform), - Release: PlatformReleaseToRPC(latestPlatformRelease), + Metadata: platformToRPCPlatformMetadata(platform), + Release: platformReleaseToRPC(latestPlatformRelease), }, }) } diff --git a/commands/service_library_download.go b/commands/service_library_download.go index 152afa466ba..37b4ecbb53e 100644 --- a/commands/service_library_download.go +++ b/commands/service_library_download.go @@ -56,7 +56,7 @@ func (s *arduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, return err } - version, err := ParseVersion(req.GetVersion()) + version, err := parseVersion(req.GetVersion()) if err != nil { return err } diff --git a/commands/service_library_install.go b/commands/service_library_install.go index c2b9aa7ad1e..d4440d3d2ae 100644 --- a/commands/service_library_install.go +++ b/commands/service_library_install.go @@ -109,7 +109,7 @@ func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s libReleasesToInstall := map[*librariesindex.Release]*librariesmanager.LibraryInstallPlan{} installLocation := libraries.FromRPCLibraryInstallLocation(req.GetInstallLocation()) for _, lib := range toInstall { - version, err := ParseVersion(lib.GetVersionRequired()) + version, err := parseVersion(lib.GetVersionRequired()) if err != nil { return err } diff --git a/commands/service_library_resolve_deps.go b/commands/service_library_resolve_deps.go index 013199dbe29..c50cc2d9f6a 100644 --- a/commands/service_library_resolve_deps.go +++ b/commands/service_library_resolve_deps.go @@ -47,7 +47,7 @@ func (s *arduinoCoreServerImpl) LibraryResolveDependencies(ctx context.Context, func libraryResolveDependencies(lme *librariesmanager.Explorer, li *librariesindex.Index, reqName, reqVersion string, noOverwrite bool) (*rpc.LibraryResolveDependenciesResponse, error) { - version, err := ParseVersion(reqVersion) + version, err := parseVersion(reqVersion) if err != nil { return nil, err } diff --git a/commands/service_library_uninstall.go b/commands/service_library_uninstall.go index e436cbe15a9..8164427f139 100644 --- a/commands/service_library_uninstall.go +++ b/commands/service_library_uninstall.go @@ -47,7 +47,7 @@ func (s *arduinoCoreServerImpl) LibraryUninstall(req *rpc.LibraryUninstallReques return err } - version, err := ParseVersion(req.GetVersion()) + version, err := parseVersion(req.GetVersion()) if err != nil { return err } diff --git a/commands/service_platform_download.go b/commands/service_platform_download.go index a4227fa30b9..23a8096120d 100644 --- a/commands/service_platform_download.go +++ b/commands/service_platform_download.go @@ -48,7 +48,7 @@ func (s *arduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadReques } defer release() - version, err := ParseVersion(req.GetVersion()) + version, err := parseVersion(req.GetVersion()) if err != nil { return &cmderrors.InvalidVersionError{Cause: err} } diff --git a/commands/service_platform_install.go b/commands/service_platform_install.go index 06c8891fcc3..caa351a6ec6 100644 --- a/commands/service_platform_install.go +++ b/commands/service_platform_install.go @@ -53,7 +53,7 @@ func (s *arduinoCoreServerImpl) PlatformInstall(req *rpc.PlatformInstallRequest, } defer release() - version, err := ParseVersion(req.GetVersion()) + version, err := parseVersion(req.GetVersion()) if err != nil { return &cmderrors.InvalidVersionError{Cause: err} } diff --git a/commands/service_platform_search.go b/commands/service_platform_search.go index dfa0d33ffd8..4117bf7be18 100644 --- a/commands/service_platform_search.go +++ b/commands/service_platform_search.go @@ -82,7 +82,7 @@ func (s *arduinoCoreServerImpl) PlatformSearch(_ context.Context, req *rpc.Platf out := []*rpc.PlatformSummary{} for _, platform := range res { rpcPlatformSummary := &rpc.PlatformSummary{ - Metadata: PlatformToRPCPlatformMetadata(platform), + Metadata: platformToRPCPlatformMetadata(platform), Releases: map[string]*rpc.PlatformRelease{}, } if installed := pme.GetInstalledPlatformRelease(platform); installed != nil { @@ -92,7 +92,7 @@ func (s *arduinoCoreServerImpl) PlatformSearch(_ context.Context, req *rpc.Platf rpcPlatformSummary.LatestVersion = latestCompatible.Version.String() } for _, platformRelease := range platform.GetAllReleases() { - rpcPlatformRelease := PlatformReleaseToRPC(platformRelease) + rpcPlatformRelease := platformReleaseToRPC(platformRelease) rpcPlatformSummary.Releases[rpcPlatformRelease.GetVersion()] = rpcPlatformRelease } out = append(out, rpcPlatformSummary) diff --git a/commands/service_platform_upgrade.go b/commands/service_platform_upgrade.go index a9b65fe5bfa..2737eac4f37 100644 --- a/commands/service_platform_upgrade.go +++ b/commands/service_platform_upgrade.go @@ -76,8 +76,8 @@ func (s *arduinoCoreServerImpl) PlatformUpgrade(req *rpc.PlatformUpgradeRequest, if platformRelease != nil { syncSend.Send(&rpc.PlatformUpgradeResponse{ Platform: &rpc.Platform{ - Metadata: PlatformToRPCPlatformMetadata(platformRelease.Platform), - Release: PlatformReleaseToRPC(platformRelease), + Metadata: platformToRPCPlatformMetadata(platformRelease.Platform), + Release: platformReleaseToRPC(platformRelease), }, }) } diff --git a/commands/core.go b/commands/utility_core.go similarity index 91% rename from commands/core.go rename to commands/utility_core.go index e61078da1b2..b5a57ad509d 100644 --- a/commands/core.go +++ b/commands/utility_core.go @@ -20,8 +20,8 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) -// PlatformToRPCPlatformMetadata converts our internal structure to the RPC structure. -func PlatformToRPCPlatformMetadata(platform *cores.Platform) *rpc.PlatformMetadata { +// platformToRPCPlatformMetadata converts our internal structure to the RPC structure. +func platformToRPCPlatformMetadata(platform *cores.Platform) *rpc.PlatformMetadata { return &rpc.PlatformMetadata{ Id: platform.String(), Maintainer: platform.Package.Maintainer, @@ -33,10 +33,10 @@ func PlatformToRPCPlatformMetadata(platform *cores.Platform) *rpc.PlatformMetada } } -// PlatformReleaseToRPC converts our internal structure to the RPC structure. +// platformReleaseToRPC converts our internal structure to the RPC structure. // Note: this function does not touch the "Installed" field of rpc.Platform as it's not always clear that the // platformRelease we're currently converting is actually installed. -func PlatformReleaseToRPC(platformRelease *cores.PlatformRelease) *rpc.PlatformRelease { +func platformReleaseToRPC(platformRelease *cores.PlatformRelease) *rpc.PlatformRelease { // If the boards are not installed yet, the `platformRelease.Boards` will be a zero length slice. // In such case, we have to use the `platformRelease.BoardsManifest` instead. // So that we can retrieve the name of the boards at least. diff --git a/commands/grpc_streaming_helpers.go b/commands/utility_grpc_streaming.go similarity index 100% rename from commands/grpc_streaming_helpers.go rename to commands/utility_grpc_streaming.go diff --git a/commands/libraries_index_search_matcher.go b/commands/utility_libraries_index_search_matcher.go similarity index 100% rename from commands/libraries_index_search_matcher.go rename to commands/utility_libraries_index_search_matcher.go diff --git a/commands/version.go b/commands/utility_version.go similarity index 89% rename from commands/version.go rename to commands/utility_version.go index 2fd87215a2f..a7232d6fdc4 100644 --- a/commands/version.go +++ b/commands/utility_version.go @@ -20,10 +20,10 @@ import ( semver "go.bug.st/relaxed-semver" ) -// ParseVersion returns the parsed version or nil if the version is +// parseVersion returns the parsed version or nil if the version is // the empty string. An error is returned if the version is not valid // semver. -func ParseVersion(version string) (*semver.Version, error) { +func parseVersion(version string) (*semver.Version, error) { if version == "" { return nil, nil } From c08c59eec1997587f32d0ddd8c6e9ece383fdf37 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 20 Mar 2024 17:07:09 +0100 Subject: [PATCH 27/56] Run tests forcing the english language --- Taskfile.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index 2a9b20fd9ca..d5cbf0131a0 100755 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -95,7 +95,7 @@ tasks: dir: '{{default "./" .GO_MODULE_PATH}}' cmds: - | - go test \ + LANG=en go test \ -v \ -short \ -run '{{default ".*" .GO_TEST_REGEX}}' \ @@ -115,7 +115,7 @@ tasks: - | rm -fr coverage_data mkdir coverage_data - INTEGRATION_GOCOVERDIR={{ .ROOT_DIR }}/coverage_data go test \ + LANG=en INTEGRATION_GOCOVERDIR={{ .ROOT_DIR }}/coverage_data go test \ -v \ -short \ {{ .GO_TEST_PACKAGE }} \ From e8e15743bc52e49ee95d4fd54f3231448fb21c71 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Apr 2024 11:52:12 +0200 Subject: [PATCH 28/56] Use correct env var to force configuration in integration test ARDUINO_DATA_DIR, ARDUINO_DOWNLOADS_DIR, and ARDUINO_SKETCHBOOK_DIR are old variables kept just for backward compatibility. --- internal/integrationtest/arduino-cli.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/integrationtest/arduino-cli.go b/internal/integrationtest/arduino-cli.go index 3ec6f44f1ea..7e2ff315f98 100644 --- a/internal/integrationtest/arduino-cli.go +++ b/internal/integrationtest/arduino-cli.go @@ -109,10 +109,10 @@ func NewArduinoCliWithinEnvironment(env *Environment, config *ArduinoCLIConfig) } cli.cliEnvVars = map[string]string{ - "LANG": "en", - "ARDUINO_DATA_DIR": cli.dataDir.String(), - "ARDUINO_DOWNLOADS_DIR": cli.stagingDir.String(), - "ARDUINO_SKETCHBOOK_DIR": cli.sketchbookDir.String(), + "LANG": "en", + "ARDUINO_DIRECTORIES_DATA": cli.dataDir.String(), + "ARDUINO_DIRECTORIES_DOWNLOADS": cli.stagingDir.String(), + "ARDUINO_DIRECTORIES_USER": cli.sketchbookDir.String(), "ARDUINO_BUILD_CACHE_COMPILATIONS_BEFORE_PURGE": "0", } env.RegisterCleanUpCallback(cli.CleanUp) From 9bab3c51ecca76cde3679d3e1ad2286e477596b9 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Apr 2024 12:00:41 +0200 Subject: [PATCH 29/56] Fixed markdown link --- internal/i18n/data/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/i18n/data/README.md b/internal/i18n/data/README.md index d52ec1782ae..5d8d773c26d 100644 --- a/internal/i18n/data/README.md +++ b/internal/i18n/data/README.md @@ -6,7 +6,7 @@ This folder contains the [localization](https://wikipedia.org/wiki/Language_loca at the source: - **en.po** - edit the string in the source code file indicated by the comment above it
e.g., a comment - `#: commands/upload/upload.go:615` indicates the source string is at line 615 of the file - [`commands/upload/upload.go`](../../../commands/upload/upload.go) + `#: internal/cli/lib/check_deps.go:102` indicates the source string is at line 102 of the file + [`internal/cli/lib/check_deps.go`](../../../internal/cli/lib/check_deps.go) - **All other files** - the localization is done on **Transifex**:
https://explore.transifex.com/arduino-1/arduino-cli/ From 6320f6eb09522de618b3997efb7513ff2ebf325f Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Apr 2024 09:29:39 +0200 Subject: [PATCH 30/56] Always use arduino-cli in user-agent string --- version/version.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/version/version.go b/version/version.go index 576b48d1b66..abb0f75cc20 100644 --- a/version/version.go +++ b/version/version.go @@ -16,9 +16,6 @@ package version import ( - "os" - "path/filepath" - "github.com/arduino/arduino-cli/internal/i18n" ) @@ -70,5 +67,5 @@ func init() { versionString = defaultVersionString } - VersionInfo = NewInfo(filepath.Base(os.Args[0])) + VersionInfo = NewInfo("arduino-cli") } From 1fddba76a15360b083f457c1028065f764747b10 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 20 Mar 2024 17:23:27 +0100 Subject: [PATCH 31/56] Removed global *viper.Viper settings instance Now the configuration is kept inside the arduinoCoreServiceImpl struct. No more direct access to the configuration, the required config values are passed as arguments or available trough struct fields. Viper object is now embedded into a new configuration.Setting object. This would allow to make better getters and setters methods in the next commits. HTTP downloader configuration is generated using the configuration. --- commands/instances.go | 79 ++++++++++++------- commands/internal/instances/instances.go | 9 ++- commands/service.go | 7 +- commands/service_board_list.go | 25 +++--- commands/service_board_list_test.go | 32 +++----- commands/service_cache_clean.go | 2 +- commands/service_check_for_updates.go | 14 ++-- commands/service_compile.go | 19 ++--- commands/service_debug_test.go | 3 +- commands/service_library_download.go | 8 +- commands/service_library_install.go | 2 +- commands/service_platform_download.go | 4 +- commands/service_platform_search_test.go | 10 +-- commands/service_settings.go | 22 +++--- commands/service_settings_test.go | 76 ++++++++++-------- commands/service_sketch_load_test.go | 3 +- commands/service_sketch_new.go | 3 +- commands/service_sketch_new_test.go | 11 +-- commands/service_upload_test.go | 3 +- .../arduino/cores/packagemanager/download.go | 9 +-- .../cores/packagemanager/install_uninstall.go | 4 +- .../arduino/cores/packagemanager/loader.go | 4 +- .../cores/packagemanager/loader_test.go | 3 +- .../cores/packagemanager/package_manager.go | 11 ++- .../packagemanager/package_manager_test.go | 34 ++++---- .../arduino/cores/packagemanager/profiles.go | 22 +++--- internal/arduino/httpclient/httpclient.go | 64 +-------------- internal/arduino/resources/download.go | 2 +- internal/arduino/resources/helpers_test.go | 21 +++-- internal/arduino/resources/index.go | 6 +- internal/arduino/resources/resources_test.go | 8 +- internal/cli/arguments/reference_test.go | 8 +- internal/cli/cli.go | 30 +++---- internal/cli/compile/compile.go | 4 +- internal/cli/config/add.go | 16 ++-- internal/cli/config/config.go | 23 +++--- internal/cli/config/delete.go | 23 +++--- internal/cli/config/dump.go | 12 ++- internal/cli/config/get.go | 16 ++-- internal/cli/config/init.go | 26 +++--- internal/cli/config/remove.go | 16 ++-- internal/cli/config/set.go | 14 ++-- internal/cli/configuration/configuration.go | 22 ++++-- internal/cli/configuration/defaults.go | 4 +- internal/cli/configuration/directories.go | 19 +++-- internal/cli/configuration/network.go | 47 ++++++++++- .../configuration/network_test.go} | 21 +++-- internal/cli/daemon/daemon.go | 54 ++++++------- internal/cli/lib/install.go | 9 ++- internal/cli/lib/lib.go | 5 +- internal/docsgen/main.go | 4 +- main.go | 8 +- 52 files changed, 460 insertions(+), 441 deletions(-) rename internal/{arduino/httpclient/httpclient_test.go => cli/configuration/network_test.go} (79%) diff --git a/commands/instances.go b/commands/instances.go index 1b51231c657..7d461be1fc8 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -49,8 +49,9 @@ import ( func installTool(pm *packagemanager.PackageManager, tool *cores.ToolRelease, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { pme, release := pm.NewExplorer() defer release() + taskCB(&rpc.TaskProgress{Name: tr("Downloading missing tool %s", tool)}) - if err := pme.DownloadToolRelease(tool, nil, downloadCB); err != nil { + if err := pme.DownloadToolRelease(tool, downloadCB); err != nil { return fmt.Errorf(tr("downloading %[1]s tool: %[2]s"), tool, err) } taskCB(&rpc.TaskProgress{Completed: true}) @@ -62,16 +63,16 @@ func installTool(pm *packagemanager.PackageManager, tool *cores.ToolRelease, dow // Create a new Instance ready to be initialized, supporting directories are also created. func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateRequest) (*rpc.CreateResponse, error) { - var userAgent []string + var userAgent string if md, ok := metadata.FromIncomingContext(ctx); ok { - userAgent = md.Get("user-agent") + userAgent = strings.Join(md.Get("user-agent"), " ") } - if len(userAgent) == 0 { - userAgent = []string{"gRPCClientUnknown/0.0.0"} + if userAgent == "" { + userAgent = "gRPCClientUnknown/0.0.0" } // Setup downloads directory - downloadsDir := configuration.DownloadsDir(configuration.Settings) + downloadsDir := configuration.DownloadsDir(s.settings) if downloadsDir.NotExist() { err := downloadsDir.MkdirAll() if err != nil { @@ -80,8 +81,8 @@ func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque } // Setup data directory - dataDir := configuration.DataDir(configuration.Settings) - packagesDir := configuration.PackagesDir(configuration.Settings) + dataDir := configuration.DataDir(s.settings) + packagesDir := configuration.PackagesDir(s.settings) if packagesDir.NotExist() { err := packagesDir.MkdirAll() if err != nil { @@ -89,7 +90,11 @@ func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque } } - inst, err := instances.Create(dataDir, packagesDir, downloadsDir, userAgent...) + config, err := s.settings.DownloaderConfig() + if err != nil { + return nil, err + } + inst, err := instances.Create(dataDir, packagesDir, downloadsDir, userAgent, config) if err != nil { return nil, err } @@ -108,6 +113,8 @@ func InitStreamResponseToCallbackFunction(ctx context.Context, cb func(r *rpc.In // 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 (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { + ctx := stream.Context() + instance := req.GetInstance() if !instances.IsValid(instance) { return &cmderrors.InvalidInstanceError{} @@ -170,7 +177,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor defaultIndexURL, _ := utils.URLParse(globals.DefaultIndexURL) allPackageIndexUrls := []*url.URL{defaultIndexURL} if profile == nil { - for _, u := range configuration.Settings.GetStringSlice("board_manager.additional_urls") { + for _, u := range s.settings.GetStringSlice("board_manager.additional_urls") { URL, err := utils.URLParse(u) if err != nil { e := &cmderrors.InitFailedError{ @@ -185,7 +192,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor } } - if err := firstUpdate(context.Background(), s, req.GetInstance(), downloadCallback, allPackageIndexUrls); err != nil { + if err := firstUpdate(ctx, s, req.GetInstance(), configuration.DataDir(s.settings), downloadCallback, allPackageIndexUrls); err != nil { e := &cmderrors.InitFailedError{ Code: codes.InvalidArgument, Cause: err, @@ -238,15 +245,13 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor // Load Platforms if profile == nil { - for _, err := range pmb.LoadHardware() { + for _, err := range pmb.LoadHardware(s.settings) { s := &cmderrors.PlatformLoadingError{Cause: err} responseError(s.GRPCStatus()) } } else { // Load platforms from profile - errs := pmb.LoadHardwareForProfile( - profile, true, downloadCallback, taskCallback, - ) + errs := pmb.LoadHardwareForProfile(profile, true, downloadCallback, taskCallback, s.settings) for _, err := range errs { s := &cmderrors.PlatformLoadingError{Cause: err} responseError(s.GRPCStatus()) @@ -344,7 +349,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor if profile == nil { // Add directories of libraries bundled with IDE - if bundledLibsDir := configuration.IDEBuiltinLibrariesDir(configuration.Settings); bundledLibsDir != nil { + if bundledLibsDir := configuration.IDEBuiltinLibrariesDir(s.settings); bundledLibsDir != nil { lmb.AddLibrariesDir(librariesmanager.LibrariesDir{ Path: bundledLibsDir, Location: libraries.IDEBuiltIn, @@ -353,14 +358,14 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor // Add libraries directory from config file lmb.AddLibrariesDir(librariesmanager.LibrariesDir{ - Path: configuration.LibrariesDir(configuration.Settings), + Path: configuration.LibrariesDir(s.settings), Location: libraries.User, }) } else { // Load libraries required for profile for _, libraryRef := range profile.Libraries { uid := libraryRef.InternalUniqueIdentifier() - libRoot := configuration.ProfilesCacheDir(configuration.Settings).Join(uid) + libRoot := configuration.ProfilesCacheDir(s.settings).Join(uid) libDir := libRoot.Join(libraryRef.Library) if !libDir.IsDir() { @@ -373,7 +378,14 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor responseError(err.GRPCStatus()) continue } - if err := libRelease.Resource.Download(pme.DownloadDir, nil, libRelease.String(), downloadCallback, ""); err != nil { + config, err := s.settings.DownloaderConfig() + if err != nil { + taskCallback(&rpc.TaskProgress{Name: tr("Error downloading library %s", libraryRef)}) + e := &cmderrors.FailedLibraryInstallError{Cause: err} + responseError(e.GRPCStatus()) + continue + } + if err := libRelease.Resource.Download(pme.DownloadDir, config, libRelease.String(), downloadCallback, ""); err != nil { taskCallback(&rpc.TaskProgress{Name: tr("Error downloading library %s", libraryRef)}) e := &cmderrors.FailedLibraryInstallError{Cause: err} responseError(e.GRPCStatus()) @@ -409,7 +421,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor // Refreshes the locale used, this will change the // language of the CLI if the locale is different // after started. - i18n.Init(configuration.Settings.GetString("locale")) + i18n.Init(s.settings.GetString("locale")) return nil } @@ -487,7 +499,11 @@ func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd // Perform index update // TODO: pass context // ctx := stream.Context() - if err := globals.LibrariesIndexResource.Download(indexDir, downloadCB); err != nil { + config, err := s.settings.DownloaderConfig() + if err != nil { + return err + } + if err := globals.LibrariesIndexResource.Download(indexDir, downloadCB, config); err != nil { resultCB(rpc.IndexUpdateReport_STATUS_FAILED) return err } @@ -532,11 +548,11 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream Message: &rpc.UpdateIndexResponse_DownloadProgress{DownloadProgress: p}, }) } - indexpath := configuration.DataDir(configuration.Settings) + indexpath := configuration.DataDir(s.settings) urls := []string{globals.DefaultIndexURL} if !req.GetIgnoreCustomPackageIndexes() { - urls = append(urls, configuration.Settings.GetStringSlice("board_manager.additional_urls")...) + urls = append(urls, s.settings.GetStringSlice("board_manager.additional_urls")...) } failed := false @@ -593,11 +609,18 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream } } + config, err := s.settings.DownloaderConfig() + if err != nil { + downloadCB.Start(u, tr("Downloading index: %s", filepath.Base(URL.Path))) + downloadCB.End(false, tr("Invalid network configuration: %s", err)) + failed = true + } + if strings.HasSuffix(URL.Host, "arduino.cc") && strings.HasSuffix(URL.Path, ".json") { indexResource.SignatureURL, _ = url.Parse(u) // should not fail because we already parsed it indexResource.SignatureURL.Path += ".sig" } - if err := indexResource.Download(indexpath, downloadCB); err != nil { + if err := indexResource.Download(indexpath, downloadCB, config); err != nil { failed = true result.UpdatedIndexes = append(result.GetUpdatedIndexes(), report(URL, rpc.IndexUpdateReport_STATUS_FAILED)) } else { @@ -615,10 +638,8 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream // 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(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, downloadCb func(msg *rpc.DownloadProgress), externalPackageIndexes []*url.URL) error { - // Gets the data directory to verify if library_index.json and package_index.json exist - dataDir := configuration.DataDir(configuration.Settings) - libraryIndex := dataDir.Join("library_index.json") +func firstUpdate(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance *rpc.Instance, indexDir *paths.Path, downloadCb func(msg *rpc.DownloadProgress), externalPackageIndexes []*url.URL) error { + libraryIndex := indexDir.Join("library_index.json") if libraryIndex.NotExist() { // The library_index.json file doesn't exists, that means the CLI is run for the first time @@ -640,7 +661,7 @@ func firstUpdate(ctx context.Context, srv rpc.ArduinoCoreServiceServer, instance Message: tr("Error downloading index '%s'", URL), Cause: &cmderrors.InvalidURLError{}} } - packageIndexFile := dataDir.Join(packageIndexFileName) + packageIndexFile := indexDir.Join(packageIndexFileName) if packageIndexFile.NotExist() { // The index file doesn't exists, that means the CLI is run for the first time, // or the 3rd party package index URL has just been added. Similarly to the diff --git a/commands/internal/instances/instances.go b/commands/internal/instances/instances.go index 019927a4967..b5cd63a3287 100644 --- a/commands/internal/instances/instances.go +++ b/commands/internal/instances/instances.go @@ -25,6 +25,7 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/arduino-cli/version" "github.com/arduino/go-paths-helper" + "go.bug.st/downloader/v2" ) // coreInstance is an instance of the Arduino Core Services. The user can @@ -133,15 +134,15 @@ func SetLibraryManager(inst *rpc.Instance, lm *librariesmanager.LibrariesManager } // Create a new *rpc.Instance ready to be initialized -func Create(dataDir, packagesDir, downloadsDir *paths.Path, extraUserAgent ...string) (*rpc.Instance, error) { +func Create(dataDir, packagesDir, downloadsDir *paths.Path, extraUserAgent string, downloaderConfig downloader.Config) (*rpc.Instance, error) { // Create package manager userAgent := "arduino-cli/" + version.VersionInfo.VersionString - for _, ua := range extraUserAgent { - userAgent += " " + ua + if extraUserAgent != "" { + userAgent += " " + extraUserAgent } tempDir := dataDir.Join("tmp") - pm := packagemanager.NewBuilder(dataDir, packagesDir, downloadsDir, tempDir, userAgent).Build() + pm := packagemanager.NewBuilder(dataDir, packagesDir, downloadsDir, tempDir, userAgent, downloaderConfig).Build() lm, _ := librariesmanager.NewBuilder().Build() instance := &coreInstance{ diff --git a/commands/service.go b/commands/service.go index e8bf689d59a..03da5135b29 100644 --- a/commands/service.go +++ b/commands/service.go @@ -18,14 +18,16 @@ package commands import ( "context" + "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) // NewArduinoCoreServer returns an implementation of the ArduinoCoreService gRPC service // that uses the provided version string. -func NewArduinoCoreServer(version string) rpc.ArduinoCoreServiceServer { +func NewArduinoCoreServer(version string, settings *configuration.Settings) rpc.ArduinoCoreServiceServer { return &arduinoCoreServerImpl{ versionString: version, + settings: settings, } } @@ -33,6 +35,9 @@ type arduinoCoreServerImpl struct { rpc.UnsafeArduinoCoreServiceServer // Force compile error for unimplemented methods versionString string + + // Settings holds configurations of the CLI and the gRPC consumers + settings *configuration.Settings } // Version returns the version of the Arduino CLI diff --git a/commands/service_board_list.go b/commands/service_board_list.go index ba6cd3c727f..aff1085c9c2 100644 --- a/commands/service_board_list.go +++ b/commands/service_board_list.go @@ -32,7 +32,7 @@ import ( f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/arduino/cores" "github.com/arduino/arduino-cli/internal/arduino/cores/packagemanager" - "github.com/arduino/arduino-cli/internal/arduino/httpclient" + "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/inventory" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-properties-orderedmap" @@ -45,7 +45,7 @@ var ( validVidPid = regexp.MustCompile(`0[xX][a-fA-F\d]{4}`) ) -func cachedAPIByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) { +func cachedAPIByVidPid(vid, pid string, settings *configuration.Settings) ([]*rpc.BoardListItem, error) { var resp []*rpc.BoardListItem cacheKey := fmt.Sprintf("cache.builder-api.v3/boards/byvid/pid/%s/%s", vid, pid) @@ -59,7 +59,7 @@ func cachedAPIByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) { } } - resp, err := apiByVidPid(vid, pid) // Perform API requrest + resp, err := apiByVidPid(vid, pid, settings) // Perform API requrest if err == nil { if cachedResp, err := json.Marshal(resp); err == nil { @@ -71,7 +71,7 @@ func cachedAPIByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) { return resp, err } -func apiByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) { +func apiByVidPid(vid, pid string, settings *configuration.Settings) ([]*rpc.BoardListItem, error) { // ensure vid and pid are valid before hitting the API if !validVidPid.MatchString(vid) { return nil, errors.New(tr("Invalid vid value: '%s'", vid)) @@ -84,10 +84,7 @@ func apiByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) { req, _ := http.NewRequest("GET", url, nil) req.Header.Set("Content-Type", "application/json") - // TODO: use proxy if set - - httpClient, err := httpclient.New() - + httpClient, err := settings.NewHttpClient() if err != nil { return nil, fmt.Errorf("%s: %w", tr("failed to initialize http client"), err) } @@ -130,18 +127,18 @@ func apiByVidPid(vid, pid string) ([]*rpc.BoardListItem, error) { }, nil } -func identifyViaCloudAPI(props *properties.Map) ([]*rpc.BoardListItem, error) { +func identifyViaCloudAPI(props *properties.Map, settings *configuration.Settings) ([]*rpc.BoardListItem, error) { // If the port is not USB do not try identification via cloud if !props.ContainsKey("vid") || !props.ContainsKey("pid") { return nil, nil } logrus.Debug("Querying builder API for board identification...") - return cachedAPIByVidPid(props.Get("vid"), props.Get("pid")) + return cachedAPIByVidPid(props.Get("vid"), props.Get("pid"), settings) } // identify returns a list of boards checking first the installed platforms or the Cloud API -func identify(pme *packagemanager.Explorer, port *discovery.Port) ([]*rpc.BoardListItem, error) { +func identify(pme *packagemanager.Explorer, port *discovery.Port, settings *configuration.Settings) ([]*rpc.BoardListItem, error) { boards := []*rpc.BoardListItem{} if port.Properties == nil { return boards, nil @@ -173,7 +170,7 @@ func identify(pme *packagemanager.Explorer, port *discovery.Port) ([]*rpc.BoardL // if installed cores didn't recognize the board, try querying // the builder API if the board is a USB device port if len(boards) == 0 { - items, err := identifyViaCloudAPI(port.Properties) + items, err := identifyViaCloudAPI(port.Properties, settings) if err != nil { // this is bad, but keep going logrus.WithError(err).Debug("Error querying builder API") @@ -227,7 +224,7 @@ func (s *arduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardLis ports := []*rpc.DetectedPort{} for _, port := range dm.List() { - boards, err := identify(pme, port) + boards, err := identify(pme, port, s.settings) if err != nil { warnings = append(warnings, err.Error()) } @@ -306,7 +303,7 @@ func (s *arduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, s boardsError := "" if event.Type == "add" { - boards, err := identify(pme, event.Port) + boards, err := identify(pme, event.Port, s.settings) if err != nil { boardsError = err.Error() } diff --git a/commands/service_board_list_test.go b/commands/service_board_list_test.go index 2db649e4554..e9132a50949 100644 --- a/commands/service_board_list_test.go +++ b/commands/service_board_list_test.go @@ -27,12 +27,11 @@ import ( "github.com/arduino/go-properties-orderedmap" discovery "github.com/arduino/pluggable-discovery-protocol-handler/v2" "github.com/stretchr/testify/require" + "go.bug.st/downloader/v2" semver "go.bug.st/relaxed-semver" ) func TestGetByVidPid(t *testing.T) { - configuration.Settings = configuration.Init("") - configuration.Settings.Set("locale", "en") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, ` { @@ -49,34 +48,31 @@ func TestGetByVidPid(t *testing.T) { defer ts.Close() vidPidURL = ts.URL - res, err := apiByVidPid("0xf420", "0XF069") + res, err := apiByVidPid("0xf420", "0XF069", configuration.Init("")) require.Nil(t, err) require.Len(t, res, 1) require.Equal(t, "Arduino/Genuino MKR1000", res[0].GetName()) require.Equal(t, "arduino:samd:mkr1000", res[0].GetFqbn()) // wrong vid (too long), wrong pid (not an hex value) - _, err = apiByVidPid("0xfffff", "0xDEFG") + + _, err = apiByVidPid("0xfffff", "0xDEFG", configuration.Init("")) require.NotNil(t, err) } func TestGetByVidPidNotFound(t *testing.T) { - configuration.Settings = configuration.Init("") - configuration.Settings.Set("locale", "en") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) })) defer ts.Close() vidPidURL = ts.URL - res, err := apiByVidPid("0x0420", "0x0069") + res, err := apiByVidPid("0x0420", "0x0069", configuration.Init("")) require.NoError(t, err) require.Empty(t, res) } func TestGetByVidPid5xx(t *testing.T) { - configuration.Settings = configuration.Init("") - configuration.Settings.Set("locale", "en") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("500 - Ooooops!")) @@ -84,46 +80,39 @@ func TestGetByVidPid5xx(t *testing.T) { defer ts.Close() vidPidURL = ts.URL - res, err := apiByVidPid("0x0420", "0x0069") + res, err := apiByVidPid("0x0420", "0x0069", configuration.Init("")) require.NotNil(t, err) require.Equal(t, "the server responded with status 500 Internal Server Error", err.Error()) require.Len(t, res, 0) } func TestGetByVidPidMalformedResponse(t *testing.T) { - configuration.Settings = configuration.Init("") - configuration.Settings.Set("locale", "en") ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "{}") })) defer ts.Close() vidPidURL = ts.URL - res, err := apiByVidPid("0x0420", "0x0069") + res, err := apiByVidPid("0x0420", "0x0069", configuration.Init("")) require.NotNil(t, err) require.Equal(t, "wrong format in server response", err.Error()) require.Len(t, res, 0) } func TestBoardDetectionViaAPIWithNonUSBPort(t *testing.T) { - configuration.Settings = configuration.Init("") - configuration.Settings.Set("locale", "en") - items, err := identifyViaCloudAPI(properties.NewMap()) + items, err := identifyViaCloudAPI(properties.NewMap(), configuration.Init("")) require.NoError(t, err) require.Empty(t, items) } func TestBoardIdentifySorting(t *testing.T) { - configuration.Settings = configuration.Init("") - configuration.Settings.Set("locale", "en") - dataDir := paths.TempDir().Join("test", "data_dir") t.Setenv("ARDUINO_DATA_DIR", dataDir.String()) dataDir.MkdirAll() defer paths.TempDir().Join("test").RemoveAll() // We don't really care about the paths in this case - pmb := packagemanager.NewBuilder(dataDir, dataDir, dataDir, dataDir, "test") + pmb := packagemanager.NewBuilder(dataDir, dataDir, dataDir, dataDir, "test", downloader.GetDefaultConfig()) // Create some boards with identical VID:PID combination pack := pmb.GetOrCreatePackage("packager") @@ -159,7 +148,8 @@ func TestBoardIdentifySorting(t *testing.T) { pme, release := pm.NewExplorer() defer release() - res, err := identify(pme, &discovery.Port{Properties: idPrefs}) + settings := configuration.Init("") + res, err := identify(pme, &discovery.Port{Properties: idPrefs}, settings) require.NoError(t, err) require.NotNil(t, res) require.Len(t, res, 4) diff --git a/commands/service_cache_clean.go b/commands/service_cache_clean.go index 3cbdd488b6c..df7a091f635 100644 --- a/commands/service_cache_clean.go +++ b/commands/service_cache_clean.go @@ -24,7 +24,7 @@ import ( // CleanDownloadCacheDirectory clean the download cache directory (where archives are downloaded). func (s *arduinoCoreServerImpl) CleanDownloadCacheDirectory(ctx context.Context, req *rpc.CleanDownloadCacheDirectoryRequest) (*rpc.CleanDownloadCacheDirectoryResponse, error) { - cachePath := configuration.DownloadsDir(configuration.Settings) + cachePath := configuration.DownloadsDir(s.settings) err := cachePath.RemoveAll() if err != nil { return nil, err diff --git a/commands/service_check_for_updates.go b/commands/service_check_for_updates.go index a53005c6456..15221905d56 100644 --- a/commands/service_check_for_updates.go +++ b/commands/service_check_for_updates.go @@ -20,8 +20,6 @@ import ( "strings" "time" - "github.com/arduino/arduino-cli/internal/arduino/httpclient" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/inventory" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -35,7 +33,7 @@ func (s *arduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, r return nil, err } - if !shouldCheckForUpdate(currentVersion) && !req.GetForceCheck() { + if !s.shouldCheckForUpdate(currentVersion) && !req.GetForceCheck() { return &rpc.CheckForArduinoCLIUpdatesResponse{}, nil } @@ -45,7 +43,7 @@ func (s *arduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, r inventory.WriteStore() }() - latestVersion, err := semver.Parse(getLatestRelease()) + latestVersion, err := semver.Parse(s.getLatestRelease()) if err != nil { return nil, err } @@ -62,13 +60,13 @@ func (s *arduinoCoreServerImpl) CheckForArduinoCLIUpdates(ctx context.Context, r // shouldCheckForUpdate return true if it actually makes sense to check for new updates, // false in all other cases. -func shouldCheckForUpdate(currentVersion *semver.Version) bool { +func (s *arduinoCoreServerImpl) shouldCheckForUpdate(currentVersion *semver.Version) bool { if strings.Contains(currentVersion.String(), "git-snapshot") || strings.Contains(currentVersion.String(), "nightly") { // This is a dev build, no need to check for updates return false } - if !configuration.Settings.GetBool("updater.enable_notification") { + if !s.settings.GetBool("updater.enable_notification") { // Don't check if the user disabled the notification return false } @@ -84,8 +82,8 @@ func shouldCheckForUpdate(currentVersion *semver.Version) bool { // getLatestRelease queries the official Arduino download server for the latest release, // if there are no errors or issues a version string is returned, in all other case an empty string. -func getLatestRelease() string { - client, err := httpclient.New() +func (s *arduinoCoreServerImpl) getLatestRelease() string { + client, err := s.settings.NewHttpClient() if err != nil { return "" } diff --git a/commands/service_compile.go b/commands/service_compile.go index 512ca766249..d7320caeed2 100644 --- a/commands/service_compile.go +++ b/commands/service_compile.go @@ -22,6 +22,7 @@ import ( "io" "sort" "strings" + "time" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" @@ -66,7 +67,7 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu ctx := stream.Context() syncSend := NewSynchronizedSend(stream.Send) - exportBinaries := configuration.Settings.GetBool("sketch.always_export_binaries") + exportBinaries := s.settings.GetBool("sketch.always_export_binaries") if e := req.ExportBinaries; e != nil { exportBinaries = *e } @@ -172,7 +173,10 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu } buildcache.New(buildPath.Parent()).GetOrCreate(buildPath.Base()) // cache is purged after compilation to not remove entries that might be required - defer maybePurgeBuildCache() + + defer maybePurgeBuildCache( + s.settings.GetUint("build_cache.compilations_before_purge"), + s.settings.GetDuration("build_cache.ttl").Abs()) var coreBuildCachePath *paths.Path if req.GetBuildCachePath() == "" { @@ -194,7 +198,7 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu actualPlatform := buildPlatform otherLibrariesDirs := paths.NewPathList(req.GetLibraries()...) - otherLibrariesDirs.Add(configuration.LibrariesDir(configuration.Settings)) + otherLibrariesDirs.Add(configuration.LibrariesDir(s.settings)) var libsManager *librariesmanager.LibrariesManager if pme.GetProfile() != nil { @@ -227,9 +231,9 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu coreBuildCachePath, int(req.GetJobs()), req.GetBuildProperties(), - configuration.HardwareDirectories(configuration.Settings), + configuration.HardwareDirectories(s.settings), otherLibrariesDirs, - configuration.IDEBuiltinLibrariesDir(configuration.Settings), + configuration.IDEBuiltinLibrariesDir(s.settings), fqbn, req.GetClean(), req.GetSourceOverride(), @@ -394,9 +398,7 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu } // maybePurgeBuildCache runs the build files cache purge if the policy conditions are met. -func maybePurgeBuildCache() { - - compilationsBeforePurge := configuration.Settings.GetUint("build_cache.compilations_before_purge") +func maybePurgeBuildCache(compilationsBeforePurge uint, cacheTTL time.Duration) { // 0 means never purge if compilationsBeforePurge == 0 { return @@ -409,7 +411,6 @@ func maybePurgeBuildCache() { return } inventory.Store.Set("build_cache.compilation_count_since_last_purge", 0) - cacheTTL := configuration.Settings.GetDuration("build_cache.ttl").Abs() buildcache.New(paths.TempDir().Join("arduino", "cores")).Purge(cacheTTL) buildcache.New(paths.TempDir().Join("arduino", "sketches")).Purge(cacheTTL) } diff --git a/commands/service_debug_test.go b/commands/service_debug_test.go index e3bb45b0fd8..8e627c44b76 100644 --- a/commands/service_debug_test.go +++ b/commands/service_debug_test.go @@ -27,6 +27,7 @@ import ( "github.com/arduino/go-properties-orderedmap" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.bug.st/downloader/v2" ) func TestGetCommandLine(t *testing.T) { @@ -36,7 +37,7 @@ func TestGetCommandLine(t *testing.T) { sketchPath := paths.New("testdata", "debug", sketch) require.NoError(t, sketchPath.ToAbs()) - pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test") + pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pmb.LoadHardwareFromDirectory(dataDir) diff --git a/commands/service_library_download.go b/commands/service_library_download.go index 37b4ecbb53e..8543e8cdea6 100644 --- a/commands/service_library_download.go +++ b/commands/service_library_download.go @@ -20,8 +20,8 @@ import ( "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/commands/internal/instances" - "github.com/arduino/arduino-cli/internal/arduino/httpclient" "github.com/arduino/arduino-cli/internal/arduino/libraries/librariesindex" + "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" ) @@ -66,7 +66,7 @@ func (s *arduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, return err } - if err := downloadLibrary(ctx, downloadsDir, lib, downloadCB, func(*rpc.TaskProgress) {}, "download"); err != nil { + if err := downloadLibrary(ctx, downloadsDir, lib, downloadCB, func(*rpc.TaskProgress) {}, "download", s.settings); err != nil { return err } @@ -74,10 +74,10 @@ func (s *arduinoCoreServerImpl) LibraryDownload(req *rpc.LibraryDownloadRequest, } func downloadLibrary(_ context.Context, downloadsDir *paths.Path, libRelease *librariesindex.Release, - downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, queryParameter string) error { + downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, queryParameter string, settings *configuration.Settings) error { taskCB(&rpc.TaskProgress{Name: tr("Downloading %s", libRelease)}) - config, err := httpclient.GetDownloaderConfig() + config, err := settings.DownloaderConfig() if err != nil { return &cmderrors.FailedDownloadError{Message: tr("Can't download library"), Cause: err} } diff --git a/commands/service_library_install.go b/commands/service_library_install.go index d4440d3d2ae..20b98695de2 100644 --- a/commands/service_library_install.go +++ b/commands/service_library_install.go @@ -147,7 +147,7 @@ func (s *arduinoCoreServerImpl) LibraryInstall(req *rpc.LibraryInstallRequest, s downloadReason += "-builtin" } } - if err := downloadLibrary(ctx, downloadsDir, libRelease, downloadCB, taskCB, downloadReason); err != nil { + if err := downloadLibrary(ctx, downloadsDir, libRelease, downloadCB, taskCB, downloadReason, s.settings); err != nil { return err } if err := installLibrary(lmi, downloadsDir, libRelease, installTask, taskCB); err != nil { diff --git a/commands/service_platform_download.go b/commands/service_platform_download.go index 23a8096120d..09f49a2d76b 100644 --- a/commands/service_platform_download.go +++ b/commands/service_platform_download.go @@ -67,13 +67,13 @@ func (s *arduinoCoreServerImpl) PlatformDownload(req *rpc.PlatformDownloadReques // TODO: pass context // ctx := stream.Context() - if err := pme.DownloadPlatformRelease(platform, nil, downloadCB); err != nil { + if err := pme.DownloadPlatformRelease(platform, downloadCB); err != nil { return err } for _, tool := range tools { // TODO: pass context - if err := pme.DownloadToolRelease(tool, nil, downloadCB); err != nil { + if err := pme.DownloadToolRelease(tool, downloadCB); err != nil { return err } } diff --git a/commands/service_platform_search_test.go b/commands/service_platform_search_test.go index 63dc02c5265..3b7b87cf30d 100644 --- a/commands/service_platform_search_test.go +++ b/commands/service_platform_search_test.go @@ -36,9 +36,8 @@ func TestPlatformSearch(t *testing.T) { err := paths.New("testdata", "platform", "package_index.json").CopyTo(dataDir.Join("package_index.json")) require.Nil(t, err) - configuration.Settings = configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) - - srv := NewArduinoCoreServer("") + settings := configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) + srv := NewArduinoCoreServer("", settings) ctx := context.Background() createResp, err := srv.Create(ctx, &rpc.CreateRequest{}) require.NoError(t, err) @@ -338,9 +337,8 @@ func TestPlatformSearchSorting(t *testing.T) { err := paths.New("testdata", "platform", "package_index.json").CopyTo(dataDir.Join("package_index.json")) require.Nil(t, err) - configuration.Settings = configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) - - srv := NewArduinoCoreServer("") + settings := configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) + srv := NewArduinoCoreServer("", settings) ctx := context.Background() createResp, err := srv.Create(ctx, &rpc.CreateRequest{}) diff --git a/commands/service_settings.go b/commands/service_settings.go index f4675e0467e..177d0819178 100644 --- a/commands/service_settings.go +++ b/commands/service_settings.go @@ -29,7 +29,7 @@ import ( // SettingsGetAll returns a message with a string field containing all the settings // currently in use, marshalled in JSON format. func (s *arduinoCoreServerImpl) SettingsGetAll(ctx context.Context, req *rpc.SettingsGetAllRequest) (*rpc.SettingsGetAllResponse, error) { - b, err := json.Marshal(configuration.Settings.AllSettings()) + b, err := json.Marshal(s.settings.AllSettings()) if err == nil { return &rpc.SettingsGetAllResponse{ JsonData: string(b), @@ -83,9 +83,9 @@ func (s *arduinoCoreServerImpl) SettingsMerge(ctx context.Context, req *rpc.Sett for k, v := range mapped { updatedSettings.Set(k, v) } - configPath := configuration.Settings.ConfigFileUsed() + configPath := s.settings.ConfigFileUsed() updatedSettings.SetConfigFile(configPath) - configuration.Settings = updatedSettings + s.settings = updatedSettings return &rpc.SettingsMergeResponse{}, nil } @@ -100,7 +100,7 @@ func (s *arduinoCoreServerImpl) SettingsGetValue(ctx context.Context, req *rpc.S // since that doesn't check for keys formatted like daemon.port or those set // with Viper.Set(). This way we check for all existing settings for sure. keyExists := false - for _, k := range configuration.Settings.AllKeys() { + for _, k := range s.settings.AllKeys() { if k == key || strings.HasPrefix(k, key) { keyExists = true break @@ -110,7 +110,7 @@ func (s *arduinoCoreServerImpl) SettingsGetValue(ctx context.Context, req *rpc.S return nil, errors.New(tr("key not found in settings")) } - b, err := json.Marshal(configuration.Settings.Get(key)) + b, err := json.Marshal(s.settings.Get(key)) value := &rpc.SettingsGetValueResponse{} if err == nil { value.Key = key @@ -127,7 +127,7 @@ func (s *arduinoCoreServerImpl) SettingsSetValue(ctx context.Context, val *rpc.S err := json.Unmarshal([]byte(val.GetJsonData()), &value) if err == nil { - configuration.Settings.Set(key, value) + s.settings.Set(key, value) } return &rpc.SettingsSetValueResponse{}, err @@ -138,7 +138,7 @@ func (s *arduinoCoreServerImpl) SettingsSetValue(ctx context.Context, val *rpc.S // and that's picked up when the CLI is run as daemon, either using the default path or a custom one // set with the --config-file flag. func (s *arduinoCoreServerImpl) SettingsWrite(ctx context.Context, req *rpc.SettingsWriteRequest) (*rpc.SettingsWriteResponse, error) { - if err := configuration.Settings.WriteConfigAs(req.GetFilePath()); err != nil { + if err := s.settings.WriteConfigAs(req.GetFilePath()); err != nil { return nil, err } return &rpc.SettingsWriteResponse{}, nil @@ -153,7 +153,7 @@ func (s *arduinoCoreServerImpl) SettingsDelete(ctx context.Context, req *rpc.Set // with Viper.Set(). This way we check for all existing settings for sure. keyExists := false keys := []string{} - for _, k := range configuration.Settings.AllKeys() { + for _, k := range s.settings.AllKeys() { if !strings.HasPrefix(k, toDelete) { keys = append(keys, k) continue @@ -168,11 +168,11 @@ func (s *arduinoCoreServerImpl) SettingsDelete(ctx context.Context, req *rpc.Set // Override current settings to delete the key updatedSettings := configuration.Init("") for _, k := range keys { - updatedSettings.Set(k, configuration.Settings.Get(k)) + updatedSettings.Set(k, s.settings.Get(k)) } - configPath := configuration.Settings.ConfigFileUsed() + configPath := s.settings.ConfigFileUsed() updatedSettings.SetConfigFile(configPath) - configuration.Settings = updatedSettings + s.settings = updatedSettings return &rpc.SettingsDeleteResponse{}, nil } diff --git a/commands/service_settings_test.go b/commands/service_settings_test.go index 226a2663990..e1d67fb0fad 100644 --- a/commands/service_settings_test.go +++ b/commands/service_settings_test.go @@ -27,71 +27,68 @@ import ( "github.com/stretchr/testify/require" ) -var svc = NewArduinoCoreServer("") - -func init() { - configuration.Settings = configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) -} - -func reset() { - configuration.Settings = configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) -} - func TestGetAll(t *testing.T) { + settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) + svc := NewArduinoCoreServer("", settings) resp, err := svc.SettingsGetAll(context.Background(), &rpc.SettingsGetAllRequest{}) require.Nil(t, err) - content, err := json.Marshal(configuration.Settings.AllSettings()) + content, err := json.Marshal(settings.AllSettings()) require.Nil(t, err) require.Equal(t, string(content), resp.GetJsonData()) } func TestMerge(t *testing.T) { + initialSettings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) + svc := NewArduinoCoreServer("", initialSettings).(*arduinoCoreServerImpl) + ctx := context.Background() + // Verify defaults - require.Equal(t, "50051", configuration.Settings.GetString("daemon.port")) - require.Equal(t, "", configuration.Settings.GetString("foo")) - require.Equal(t, false, configuration.Settings.GetBool("sketch.always_export_binaries")) + require.Equal(t, "50051", svc.settings.GetString("daemon.port")) + require.Equal(t, "", svc.settings.GetString("foo")) + require.Equal(t, false, svc.settings.GetBool("sketch.always_export_binaries")) bulkSettings := `{"foo": "bar", "daemon":{"port":"420"}, "sketch": {"always_export_binaries": "true"}}` - res, err := svc.SettingsMerge(context.Background(), &rpc.SettingsMergeRequest{JsonData: bulkSettings}) + res, err := svc.SettingsMerge(ctx, &rpc.SettingsMergeRequest{JsonData: bulkSettings}) require.NotNil(t, res) require.NoError(t, err) - require.Equal(t, "420", configuration.Settings.GetString("daemon.port")) - require.Equal(t, "bar", configuration.Settings.GetString("foo")) - require.Equal(t, true, configuration.Settings.GetBool("sketch.always_export_binaries")) + require.Equal(t, "420", svc.settings.GetString("daemon.port")) + require.Equal(t, "bar", svc.settings.GetString("foo")) + require.Equal(t, true, svc.settings.GetBool("sketch.always_export_binaries")) bulkSettings = `{"foo":"", "daemon": {}, "sketch": {"always_export_binaries": "false"}}` - res, err = svc.SettingsMerge(context.Background(), &rpc.SettingsMergeRequest{JsonData: bulkSettings}) + res, err = svc.SettingsMerge(ctx, &rpc.SettingsMergeRequest{JsonData: bulkSettings}) require.NotNil(t, res) require.NoError(t, err) - require.Equal(t, "50051", configuration.Settings.GetString("daemon.port")) - require.Equal(t, "", configuration.Settings.GetString("foo")) - require.Equal(t, false, configuration.Settings.GetBool("sketch.always_export_binaries")) + require.Equal(t, "50051", svc.settings.GetString("daemon.port")) + require.Equal(t, "", svc.settings.GetString("foo")) + require.Equal(t, false, svc.settings.GetBool("sketch.always_export_binaries")) bulkSettings = `{"daemon": {"port":""}}` - res, err = svc.SettingsMerge(context.Background(), &rpc.SettingsMergeRequest{JsonData: bulkSettings}) + res, err = svc.SettingsMerge(ctx, &rpc.SettingsMergeRequest{JsonData: bulkSettings}) require.NotNil(t, res) require.NoError(t, err) - require.Equal(t, "", configuration.Settings.GetString("daemon.port")) + require.Equal(t, "", svc.settings.GetString("daemon.port")) // Verifies other values are not changed - require.Equal(t, "", configuration.Settings.GetString("foo")) - require.Equal(t, false, configuration.Settings.GetBool("sketch.always_export_binaries")) + require.Equal(t, "", svc.settings.GetString("foo")) + require.Equal(t, false, svc.settings.GetBool("sketch.always_export_binaries")) bulkSettings = `{"network": {}}` - res, err = svc.SettingsMerge(context.Background(), &rpc.SettingsMergeRequest{JsonData: bulkSettings}) + res, err = svc.SettingsMerge(ctx, &rpc.SettingsMergeRequest{JsonData: bulkSettings}) require.NotNil(t, res) require.NoError(t, err) - require.Equal(t, "", configuration.Settings.GetString("proxy")) - - reset() + require.Equal(t, "", svc.settings.GetString("proxy")) } func TestGetValue(t *testing.T) { + settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) + svc := NewArduinoCoreServer("", settings) + key := &rpc.SettingsGetValueRequest{Key: "daemon"} resp, err := svc.SettingsGetValue(context.Background(), key) require.NoError(t, err) @@ -104,6 +101,9 @@ func TestGetValue(t *testing.T) { } func TestGetMergedValue(t *testing.T) { + settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) + svc := NewArduinoCoreServer("", settings) + // Verifies value is not set key := &rpc.SettingsGetValueRequest{Key: "foo"} res, err := svc.SettingsGetValue(context.Background(), key) @@ -120,27 +120,34 @@ func TestGetMergedValue(t *testing.T) { res, err = svc.SettingsGetValue(context.Background(), key) require.NoError(t, err) require.Equal(t, `"bar"`, res.GetJsonData()) - - reset() } func TestGetValueNotFound(t *testing.T) { + settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) + svc := NewArduinoCoreServer("", settings) + key := &rpc.SettingsGetValueRequest{Key: "DOESNTEXIST"} _, err := svc.SettingsGetValue(context.Background(), key) require.Error(t, err) } func TestSetValue(t *testing.T) { + settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) + svc := NewArduinoCoreServer("", settings) + val := &rpc.SettingsSetValueRequest{ Key: "foo", JsonData: `"bar"`, } _, err := svc.SettingsSetValue(context.Background(), val) require.Nil(t, err) - require.Equal(t, "bar", configuration.Settings.GetString("foo")) + require.Equal(t, "bar", settings.GetString("foo")) } func TestWrite(t *testing.T) { + settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) + svc := NewArduinoCoreServer("", settings) + // Writes some settings val := &rpc.SettingsSetValueRequest{ Key: "foo", @@ -169,6 +176,9 @@ func TestWrite(t *testing.T) { } func TestDelete(t *testing.T) { + settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) + svc := NewArduinoCoreServer("", settings) + _, err := svc.SettingsDelete(context.Background(), &rpc.SettingsDeleteRequest{ Key: "doesnotexist", }) diff --git a/commands/service_sketch_load_test.go b/commands/service_sketch_load_test.go index 36bb58ea351..822dfea7c5d 100644 --- a/commands/service_sketch_load_test.go +++ b/commands/service_sketch_load_test.go @@ -19,12 +19,13 @@ import ( "context" "testing" + "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/stretchr/testify/require" ) func TestLoadSketchProfiles(t *testing.T) { - srv := NewArduinoCoreServer("") + srv := NewArduinoCoreServer("", configuration.Init("")) loadResp, err := srv.LoadSketch(context.Background(), &commands.LoadSketchRequest{ SketchPath: "./testdata/sketch_with_profile", }) diff --git a/commands/service_sketch_new.go b/commands/service_sketch_new.go index a8eb518a815..b0c9c079f73 100644 --- a/commands/service_sketch_new.go +++ b/commands/service_sketch_new.go @@ -22,7 +22,6 @@ import ( "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/internal/arduino/globals" - "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" ) @@ -48,7 +47,7 @@ func (s *arduinoCoreServerImpl) NewSketch(ctx context.Context, req *rpc.NewSketc if len(req.GetSketchDir()) > 0 { sketchesDir = req.GetSketchDir() } else { - sketchesDir = configuration.Settings.GetString("directories.User") + sketchesDir = s.settings.GetString("directories.User") } if err := validateSketchName(req.GetSketchName()); err != nil { diff --git a/commands/service_sketch_new_test.go b/commands/service_sketch_new_test.go index 0d0b3e05aa6..353dec17a05 100644 --- a/commands/service_sketch_new_test.go +++ b/commands/service_sketch_new_test.go @@ -20,6 +20,7 @@ import ( "fmt" "testing" + "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/stretchr/testify/require" ) @@ -35,7 +36,7 @@ func Test_SketchNameWrongPattern(t *testing.T) { ",`hack[}attempt{];", } - srv := NewArduinoCoreServer("") + srv := NewArduinoCoreServer("", configuration.Init("")) for _, name := range invalidNames { _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, @@ -48,7 +49,7 @@ func Test_SketchNameWrongPattern(t *testing.T) { } func Test_SketchNameEmpty(t *testing.T) { - srv := NewArduinoCoreServer("") + srv := NewArduinoCoreServer("", configuration.Init("")) _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: "", SketchDir: t.TempDir(), @@ -62,7 +63,7 @@ func Test_SketchNameTooLong(t *testing.T) { for i := range tooLongName { tooLongName[i] = 'a' } - srv := NewArduinoCoreServer("") + srv := NewArduinoCoreServer("", configuration.Init("")) _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: string(tooLongName), SketchDir: t.TempDir(), @@ -86,7 +87,7 @@ func Test_SketchNameOk(t *testing.T) { "_hello_world", string(lengthLimitName), } - srv := NewArduinoCoreServer("") + srv := NewArduinoCoreServer("", configuration.Init("")) for _, name := range validNames { _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, @@ -99,7 +100,7 @@ func Test_SketchNameOk(t *testing.T) { func Test_SketchNameReserved(t *testing.T) { invalidNames := []string{"CON", "PRN", "AUX", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"} - srv := NewArduinoCoreServer("") + srv := NewArduinoCoreServer("", configuration.Init("")) for _, name := range invalidNames { _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, diff --git a/commands/service_upload_test.go b/commands/service_upload_test.go index cf2f4ff3306..e8d70e19c4d 100644 --- a/commands/service_upload_test.go +++ b/commands/service_upload_test.go @@ -29,6 +29,7 @@ import ( properties "github.com/arduino/go-properties-orderedmap" "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" + "go.bug.st/downloader/v2" ) func TestDetectSketchNameFromBuildPath(t *testing.T) { @@ -127,7 +128,7 @@ func TestDetermineBuildPathAndSketchName(t *testing.T) { } func TestUploadPropertiesComposition(t *testing.T) { - pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test") + pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) errs := pmb.LoadHardwareFromDirectory(paths.New("testdata", "upload", "hardware")) require.Len(t, errs, 0) buildPath1 := paths.New("testdata", "upload", "build_path_1") diff --git a/internal/arduino/cores/packagemanager/download.go b/internal/arduino/cores/packagemanager/download.go index c4a7cb62d59..4ac06cf19f8 100644 --- a/internal/arduino/cores/packagemanager/download.go +++ b/internal/arduino/cores/packagemanager/download.go @@ -22,7 +22,6 @@ import ( "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/internal/arduino/cores" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "go.bug.st/downloader/v2" semver "go.bug.st/relaxed-semver" ) @@ -120,21 +119,21 @@ func (pme *Explorer) FindPlatformReleaseDependencies(item *PlatformReference) (* // DownloadToolRelease downloads a ToolRelease. If the tool is already downloaded a nil Downloader // is returned. Uses the given downloader configuration for download, or the default config if nil. -func (pme *Explorer) DownloadToolRelease(tool *cores.ToolRelease, config *downloader.Config, progressCB rpc.DownloadProgressCB) error { +func (pme *Explorer) DownloadToolRelease(tool *cores.ToolRelease, progressCB rpc.DownloadProgressCB) error { resource := tool.GetCompatibleFlavour() if resource == nil { return &cmderrors.FailedDownloadError{ Message: tr("Error downloading tool %s", tool), Cause: errors.New(tr("no versions available for the current OS, try contacting %s", tool.Tool.Package.Email))} } - return resource.Download(pme.DownloadDir, config, tool.String(), progressCB, "") + return resource.Download(pme.DownloadDir, pme.downloaderConfig, tool.String(), progressCB, "") } // DownloadPlatformRelease downloads a PlatformRelease. If the platform is already downloaded a // nil Downloader is returned. -func (pme *Explorer) DownloadPlatformRelease(platform *cores.PlatformRelease, config *downloader.Config, progressCB rpc.DownloadProgressCB) error { +func (pme *Explorer) DownloadPlatformRelease(platform *cores.PlatformRelease, progressCB rpc.DownloadProgressCB) error { if platform.Resource == nil { return &cmderrors.PlatformNotFoundError{Platform: platform.String()} } - return platform.Resource.Download(pme.DownloadDir, config, platform.String(), progressCB, "") + return platform.Resource.Download(pme.DownloadDir, pme.downloaderConfig, platform.String(), progressCB, "") } diff --git a/internal/arduino/cores/packagemanager/install_uninstall.go b/internal/arduino/cores/packagemanager/install_uninstall.go index bc29f08fa43..4b8c1cba9b4 100644 --- a/internal/arduino/cores/packagemanager/install_uninstall.go +++ b/internal/arduino/cores/packagemanager/install_uninstall.go @@ -92,11 +92,11 @@ func (pme *Explorer) DownloadAndInstallPlatformAndTools( // Package download taskCB(&rpc.TaskProgress{Name: tr("Downloading packages")}) for _, tool := range toolsToInstall { - if err := pme.DownloadToolRelease(tool, nil, downloadCB); err != nil { + if err := pme.DownloadToolRelease(tool, downloadCB); err != nil { return err } } - if err := pme.DownloadPlatformRelease(platformRelease, nil, downloadCB); err != nil { + if err := pme.DownloadPlatformRelease(platformRelease, downloadCB); err != nil { return err } taskCB(&rpc.TaskProgress{Completed: true}) diff --git a/internal/arduino/cores/packagemanager/loader.go b/internal/arduino/cores/packagemanager/loader.go index 68c603044e5..29e8fb511a4 100644 --- a/internal/arduino/cores/packagemanager/loader.go +++ b/internal/arduino/cores/packagemanager/loader.go @@ -31,8 +31,8 @@ import ( ) // LoadHardware read all plaforms from the configured paths -func (pm *Builder) LoadHardware() []error { - hardwareDirs := configuration.HardwareDirectories(configuration.Settings) +func (pm *Builder) LoadHardware(settings *configuration.Settings) []error { + hardwareDirs := configuration.HardwareDirectories(settings) return pm.LoadHardwareFromDirectories(hardwareDirs) } diff --git a/internal/arduino/cores/packagemanager/loader_test.go b/internal/arduino/cores/packagemanager/loader_test.go index d0d41992179..a9ee015c86d 100644 --- a/internal/arduino/cores/packagemanager/loader_test.go +++ b/internal/arduino/cores/packagemanager/loader_test.go @@ -21,6 +21,7 @@ import ( "github.com/arduino/go-paths-helper" "github.com/arduino/go-properties-orderedmap" "github.com/stretchr/testify/require" + "go.bug.st/downloader/v2" semver "go.bug.st/relaxed-semver" ) @@ -174,7 +175,7 @@ func TestLoadDiscoveries(t *testing.T) { defer fakePath.RemoveAll() createTestPackageManager := func() *PackageManager { - pmb := NewBuilder(fakePath, fakePath, fakePath, fakePath, "test") + pmb := NewBuilder(fakePath, fakePath, fakePath, fakePath, "test", downloader.GetDefaultConfig()) pack := pmb.packages.GetOrCreatePackage("arduino") // ble-discovery tool tool := pack.GetOrCreateTool("ble-discovery") diff --git a/internal/arduino/cores/packagemanager/package_manager.go b/internal/arduino/cores/packagemanager/package_manager.go index cea5e799d1b..d9a5f79a2ac 100644 --- a/internal/arduino/cores/packagemanager/package_manager.go +++ b/internal/arduino/cores/packagemanager/package_manager.go @@ -33,12 +33,12 @@ import ( "github.com/arduino/arduino-cli/internal/arduino/cores/packageindex" "github.com/arduino/arduino-cli/internal/arduino/discovery/discoverymanager" "github.com/arduino/arduino-cli/internal/arduino/sketch" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/i18n" paths "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" "github.com/arduino/go-timeutils" "github.com/sirupsen/logrus" + "go.bug.st/downloader/v2" semver "go.bug.st/relaxed-semver" ) @@ -60,6 +60,7 @@ type PackageManager struct { profile *sketch.Profile discoveryManager *discoverymanager.DiscoveryManager userAgent string + downloaderConfig downloader.Config } // Builder is used to create a new PackageManager. The builder @@ -75,7 +76,7 @@ type Explorer PackageManager var tr = i18n.Tr // NewBuilder returns a new Builder -func NewBuilder(indexDir, packagesDir, downloadDir, tempDir *paths.Path, userAgent string) *Builder { +func NewBuilder(indexDir, packagesDir, downloadDir, tempDir *paths.Path, userAgent string, downloaderConfig downloader.Config) *Builder { return &Builder{ log: logrus.StandardLogger(), packages: cores.NewPackages(), @@ -84,8 +85,9 @@ func NewBuilder(indexDir, packagesDir, downloadDir, tempDir *paths.Path, userAge DownloadDir: downloadDir, tempDir: tempDir, packagesCustomGlobalProperties: properties.NewMap(), - discoveryManager: discoverymanager.New(configuration.UserAgent(configuration.Settings)), + discoveryManager: discoverymanager.New(userAgent), userAgent: userAgent, + downloaderConfig: downloaderConfig, } } @@ -164,7 +166,7 @@ func (pmb *Builder) calculateCompatibleReleases() { // this function will make the builder write the new configuration into this // PackageManager. func (pm *PackageManager) NewBuilder() (builder *Builder, commit func()) { - pmb := NewBuilder(pm.IndexDir, pm.PackagesDir, pm.DownloadDir, pm.tempDir, pm.userAgent) + pmb := NewBuilder(pm.IndexDir, pm.PackagesDir, pm.DownloadDir, pm.tempDir, pm.userAgent, pm.downloaderConfig) return pmb, func() { pmb.calculateCompatibleReleases() pmb.BuildIntoExistingPackageManager(pm) @@ -188,6 +190,7 @@ func (pm *PackageManager) NewExplorer() (explorer *Explorer, release func()) { profile: pm.profile, discoveryManager: pm.discoveryManager, userAgent: pm.userAgent, + downloaderConfig: pm.downloaderConfig, }, pm.packagesLock.RUnlock } diff --git a/internal/arduino/cores/packagemanager/package_manager_test.go b/internal/arduino/cores/packagemanager/package_manager_test.go index 055a6d332d0..fb215816d0c 100644 --- a/internal/arduino/cores/packagemanager/package_manager_test.go +++ b/internal/arduino/cores/packagemanager/package_manager_test.go @@ -28,6 +28,7 @@ import ( "github.com/arduino/go-paths-helper" "github.com/arduino/go-properties-orderedmap" "github.com/stretchr/testify/require" + "go.bug.st/downloader/v2" semver "go.bug.st/relaxed-semver" ) @@ -38,7 +39,7 @@ var dataDir1 = paths.New("testdata", "data_dir_1") var extraHardware = paths.New("testdata", "extra_hardware") func TestFindBoardWithFQBN(t *testing.T) { - pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test") + pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pm := pmb.Build() pme, release := pm.NewExplorer() @@ -56,7 +57,7 @@ func TestFindBoardWithFQBN(t *testing.T) { func TestResolveFQBN(t *testing.T) { // Pass nil, since these paths are only used for installing - pmb := NewBuilder(nil, nil, nil, nil, "test") + pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) // Hardware from main packages directory pmb.LoadHardwareFromDirectory(dataDir1.Join("packages")) // This contains the arduino:avr core @@ -341,7 +342,7 @@ func TestResolveFQBN(t *testing.T) { } func TestBoardOptionsFunctions(t *testing.T) { - pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test") + pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pm := pmb.Build() pme, release := pm.NewExplorer() @@ -381,7 +382,7 @@ func TestBoardOptionsFunctions(t *testing.T) { } func TestBoardOrdering(t *testing.T) { - pmb := NewBuilder(dataDir1, dataDir1.Join("packages"), nil, nil, "") + pmb := NewBuilder(dataDir1, dataDir1.Join("packages"), nil, nil, "", downloader.GetDefaultConfig()) _ = pmb.LoadHardwareFromDirectories(paths.NewPathList(dataDir1.Join("packages").String())) pm := pmb.Build() pme, release := pm.NewExplorer() @@ -432,13 +433,14 @@ func TestBoardOrdering(t *testing.T) { func TestFindToolsRequiredForBoard(t *testing.T) { t.Setenv("ARDUINO_DATA_DIR", dataDir1.String()) - configuration.Settings = configuration.Init("") + settings := configuration.Init("") pmb := NewBuilder( dataDir1, - configuration.PackagesDir(configuration.Settings), - configuration.DownloadsDir(configuration.Settings), + configuration.PackagesDir(settings), + configuration.DownloadsDir(settings), dataDir1, "test", + downloader.GetDefaultConfig(), ) loadIndex := func(addr string) { @@ -454,7 +456,7 @@ func TestFindToolsRequiredForBoard(t *testing.T) { // We ignore the errors returned since they might not be necessarily blocking // but just warnings for the user, like in the case a board is not loaded // because of malformed menus - pmb.LoadHardware() + pmb.LoadHardware(settings) pm := pmb.Build() pme, release := pm.NewExplorer() defer release() @@ -567,7 +569,7 @@ func TestFindToolsRequiredForBoard(t *testing.T) { } func TestIdentifyBoard(t *testing.T) { - pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test") + pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pm := pmb.Build() pme, release := pm.NewExplorer() @@ -594,12 +596,12 @@ func TestIdentifyBoard(t *testing.T) { func TestPackageManagerClear(t *testing.T) { // Create a PackageManager and load the harware - pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test") + pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pm := pmb.Build() // Creates another PackageManager but don't load the hardware - emptyPmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test") + emptyPmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) emptyPm := emptyPmb.Build() // Verifies they're not equal @@ -621,7 +623,7 @@ func TestFindToolsRequiredFromPlatformRelease(t *testing.T) { require.NoError(t, err) defer fakePath.RemoveAll() - pmb := NewBuilder(fakePath, fakePath, fakePath, fakePath, "test") + pmb := NewBuilder(fakePath, fakePath, fakePath, fakePath, "test", downloader.GetDefaultConfig()) pack := pmb.GetOrCreatePackage("arduino") { @@ -742,7 +744,7 @@ func TestFindToolsRequiredFromPlatformRelease(t *testing.T) { } func TestFindPlatformReleaseDependencies(t *testing.T) { - pmb := NewBuilder(nil, nil, nil, nil, "test") + pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) pmb.LoadPackageIndexFromFile(paths.New("testdata", "package_tooltest_index.json")) pmb.calculateCompatibleReleases() pm := pmb.Build() @@ -758,7 +760,7 @@ func TestFindPlatformReleaseDependencies(t *testing.T) { func TestLegacyPackageConversionToPluggableDiscovery(t *testing.T) { // Pass nil, since these paths are only used for installing - pmb := NewBuilder(nil, nil, nil, nil, "test") + pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) // Hardware from main packages directory pmb.LoadHardwareFromDirectory(dataDir1.Join("packages")) pm := pmb.Build() @@ -828,7 +830,7 @@ func TestLegacyPackageConversionToPluggableDiscovery(t *testing.T) { func TestVariantAndCoreSelection(t *testing.T) { // Pass nil, since these paths are only used for installing - pmb := NewBuilder(nil, nil, nil, nil, "test") + pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) // Hardware from main packages directory pmb.LoadHardwareFromDirectory(dataDir1.Join("packages")) pm := pmb.Build() @@ -923,7 +925,7 @@ func TestVariantAndCoreSelection(t *testing.T) { } func TestRunScript(t *testing.T) { - pmb := NewBuilder(nil, nil, nil, nil, "test") + pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) pm := pmb.Build() pme, release := pm.NewExplorer() defer release() diff --git a/internal/arduino/cores/packagemanager/profiles.go b/internal/arduino/cores/packagemanager/profiles.go index 2422766e899..6cd6f3578d2 100644 --- a/internal/arduino/cores/packagemanager/profiles.go +++ b/internal/arduino/cores/packagemanager/profiles.go @@ -32,7 +32,7 @@ import ( // LoadHardwareForProfile load the hardware platforms for the given profile. // If installMissing is true then possibly missing tools and platforms will be downloaded and installed. -func (pmb *Builder) LoadHardwareForProfile(p *sketch.Profile, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) []error { +func (pmb *Builder) LoadHardwareForProfile(p *sketch.Profile, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, settings *configuration.Settings) []error { pmb.profile = p // Load required platforms @@ -40,7 +40,7 @@ func (pmb *Builder) LoadHardwareForProfile(p *sketch.Profile, installMissing boo var platformReleases []*cores.PlatformRelease indexURLs := map[string]*url.URL{} for _, platformRef := range p.Platforms { - if platformRelease, err := pmb.loadProfilePlatform(platformRef, installMissing, downloadCB, taskCB); err != nil { + if platformRelease, err := pmb.loadProfilePlatform(platformRef, installMissing, downloadCB, taskCB, settings); err != nil { merr = append(merr, fmt.Errorf("%s: %w", tr("loading required platform %s", platformRef), err)) logrus.WithField("platform", platformRef).WithError(err).Debugf("Error loading platform for profile") } else { @@ -56,7 +56,7 @@ func (pmb *Builder) LoadHardwareForProfile(p *sketch.Profile, installMissing boo for _, toolDep := range platformRelease.ToolDependencies { indexURL := indexURLs[toolDep.ToolPackager] - if err := pmb.loadProfileTool(toolDep, indexURL, installMissing, downloadCB, taskCB); err != nil { + if err := pmb.loadProfileTool(toolDep, indexURL, installMissing, downloadCB, taskCB, settings); err != nil { merr = append(merr, fmt.Errorf("%s: %w", tr("loading required tool %s", toolDep), err)) logrus.WithField("tool", toolDep).WithField("index_url", indexURL).WithError(err).Debugf("Error loading tool for profile") } else { @@ -68,13 +68,13 @@ func (pmb *Builder) LoadHardwareForProfile(p *sketch.Profile, installMissing boo return merr } -func (pmb *Builder) loadProfilePlatform(platformRef *sketch.ProfilePlatformReference, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) (*cores.PlatformRelease, error) { +func (pmb *Builder) loadProfilePlatform(platformRef *sketch.ProfilePlatformReference, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, settings *configuration.Settings) (*cores.PlatformRelease, error) { targetPackage := pmb.packages.GetOrCreatePackage(platformRef.Packager) platform := targetPackage.GetOrCreatePlatform(platformRef.Architecture) release := platform.GetOrCreateRelease(platformRef.Version) uid := platformRef.InternalUniqueIdentifier() - destDir := configuration.ProfilesCacheDir(configuration.Settings).Join(uid) + destDir := configuration.ProfilesCacheDir(settings).Join(uid) if !destDir.IsDir() && installMissing { // Try installing the missing platform if err := pmb.installMissingProfilePlatform(platformRef, destDir, downloadCB, taskCB); err != nil { @@ -91,7 +91,7 @@ func (pmb *Builder) installMissingProfilePlatform(platformRef *sketch.ProfilePla if err != nil { return fmt.Errorf("installing missing platform: could not create temp dir %s", err) } - tmpPmb := NewBuilder(tmp, tmp, pmb.DownloadDir, tmp, pmb.userAgent) + tmpPmb := NewBuilder(tmp, tmp, pmb.DownloadDir, tmp, pmb.userAgent, pmb.downloaderConfig) defer tmp.RemoveAll() // Download the main index and parse it @@ -103,7 +103,7 @@ func (pmb *Builder) installMissingProfilePlatform(platformRef *sketch.ProfilePla } for _, indexURL := range indexesToDownload { indexResource := resources.IndexResource{URL: indexURL} - if err := indexResource.Download(tmpPmb.IndexDir, downloadCB); err != nil { + if err := indexResource.Download(tmpPmb.IndexDir, downloadCB, pmb.downloaderConfig); err != nil { taskCB(&rpc.TaskProgress{Name: tr("Error downloading %s", indexURL)}) return &cmderrors.FailedDownloadError{Message: tr("Error downloading %s", indexURL), Cause: err} } @@ -121,7 +121,7 @@ func (pmb *Builder) installMissingProfilePlatform(platformRef *sketch.ProfilePla tmpPme, tmpRelease := tmpPm.NewExplorer() defer tmpRelease() - if err := tmpPme.DownloadPlatformRelease(tmpPlatformRelease, nil, downloadCB); err != nil { + if err := tmpPme.DownloadPlatformRelease(tmpPlatformRelease, downloadCB); err != nil { taskCB(&rpc.TaskProgress{Name: tr("Error downloading platform %s", tmpPlatformRelease)}) return &cmderrors.FailedInstallError{Message: tr("Error downloading platform %s", tmpPlatformRelease), Cause: err} } @@ -137,12 +137,12 @@ func (pmb *Builder) installMissingProfilePlatform(platformRef *sketch.ProfilePla return nil } -func (pmb *Builder) loadProfileTool(toolRef *cores.ToolDependency, indexURL *url.URL, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func (pmb *Builder) loadProfileTool(toolRef *cores.ToolDependency, indexURL *url.URL, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, settings *configuration.Settings) error { targetPackage := pmb.packages.GetOrCreatePackage(toolRef.ToolPackager) tool := targetPackage.GetOrCreateTool(toolRef.ToolName) uid := toolRef.InternalUniqueIdentifier(indexURL) - destDir := configuration.ProfilesCacheDir(configuration.Settings).Join(uid) + destDir := configuration.ProfilesCacheDir(settings).Join(uid) if !destDir.IsDir() && installMissing { // Try installing the missing tool @@ -172,7 +172,7 @@ func (pmb *Builder) installMissingProfileTool(toolRelease *cores.ToolRelease, de return &cmderrors.InvalidVersionError{Cause: fmt.Errorf(tr("version %s not available for this operating system", toolRelease))} } taskCB(&rpc.TaskProgress{Name: tr("Downloading tool %s", toolRelease)}) - if err := toolResource.Download(pmb.DownloadDir, nil, toolRelease.String(), downloadCB, ""); err != nil { + if err := toolResource.Download(pmb.DownloadDir, pmb.downloaderConfig, toolRelease.String(), downloadCB, ""); err != nil { taskCB(&rpc.TaskProgress{Name: tr("Error downloading tool %s", toolRelease)}) return &cmderrors.FailedInstallError{Message: tr("Error installing tool %s", toolRelease), Cause: err} } diff --git a/internal/arduino/httpclient/httpclient.go b/internal/arduino/httpclient/httpclient.go index ec4b4acc4a6..0e904dddf8f 100644 --- a/internal/arduino/httpclient/httpclient.go +++ b/internal/arduino/httpclient/httpclient.go @@ -16,12 +16,9 @@ package httpclient import ( - "net/http" - "net/url" "time" "github.com/arduino/arduino-cli/commands/cmderrors" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" @@ -34,7 +31,7 @@ var tr = i18n.Tr // DownloadFile downloads a file from a URL into the specified path. An optional config and options may be passed (or nil to use the defaults). // A DownloadProgressCB callback function must be passed to monitor download progress. // If a not empty queryParameter is passed, it is appended to the URL for analysis purposes. -func DownloadFile(path *paths.Path, URL string, queryParameter string, label string, downloadCB rpc.DownloadProgressCB, config *downloader.Config, options ...downloader.DownloadOptions) (returnedError error) { +func DownloadFile(path *paths.Path, URL string, queryParameter string, label string, downloadCB rpc.DownloadProgressCB, config downloader.Config, options ...downloader.DownloadOptions) (returnedError error) { if queryParameter != "" { URL = URL + "?query=" + queryParameter } @@ -48,15 +45,7 @@ func DownloadFile(path *paths.Path, URL string, queryParameter string, label str } }() - if config == nil { - c, err := GetDownloaderConfig() - if err != nil { - return err - } - config = c - } - - d, err := downloader.DownloadWithConfig(path.String(), URL, *config, options...) + d, err := downloader.DownloadWithConfig(path.String(), URL, config, options...) if err != nil { return err } @@ -76,52 +65,3 @@ func DownloadFile(path *paths.Path, URL string, queryParameter string, label str return nil } - -// Config is the configuration of the http client -type Config struct { - UserAgent string - Proxy *url.URL -} - -// New returns a default http client for use in the arduino-cli -func New() (*http.Client, error) { - userAgent := configuration.UserAgent(configuration.Settings) - proxy, err := configuration.NetworkProxy(configuration.Settings) - if err != nil { - return nil, err - } - return NewWithConfig(&Config{UserAgent: userAgent, Proxy: proxy}), nil -} - -// NewWithConfig creates a http client for use in the arduino-cli, with a given configuration -func NewWithConfig(config *Config) *http.Client { - return &http.Client{ - Transport: &httpClientRoundTripper{ - transport: &http.Transport{ - Proxy: http.ProxyURL(config.Proxy), - }, - userAgent: config.UserAgent, - }, - } -} - -// GetDownloaderConfig returns the downloader configuration based on current settings. -func GetDownloaderConfig() (*downloader.Config, error) { - httpClient, err := New() - if err != nil { - return nil, &cmderrors.InvalidArgumentError{Message: tr("Could not connect via HTTP"), Cause: err} - } - return &downloader.Config{ - HttpClient: *httpClient, - }, nil -} - -type httpClientRoundTripper struct { - transport http.RoundTripper - userAgent string -} - -func (h *httpClientRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { - req.Header.Add("User-Agent", h.userAgent) - return h.transport.RoundTrip(req) -} diff --git a/internal/arduino/resources/download.go b/internal/arduino/resources/download.go index 4f1df1ad5b3..19b37df48ac 100644 --- a/internal/arduino/resources/download.go +++ b/internal/arduino/resources/download.go @@ -28,7 +28,7 @@ import ( // Download performs a download loop using the provided downloader.Config. // Messages are passed back to the DownloadProgressCB using label as text for the File field. // queryParameter is passed for analysis purposes. -func (r *DownloadResource) Download(downloadDir *paths.Path, config *downloader.Config, label string, downloadCB rpc.DownloadProgressCB, queryParameter string) error { +func (r *DownloadResource) Download(downloadDir *paths.Path, config downloader.Config, label string, downloadCB rpc.DownloadProgressCB, queryParameter string) error { path, err := r.ArchivePath(downloadDir) if err != nil { return fmt.Errorf(tr("getting archive path: %s"), err) diff --git a/internal/arduino/resources/helpers_test.go b/internal/arduino/resources/helpers_test.go index e56747d8b40..72c595f6c89 100644 --- a/internal/arduino/resources/helpers_test.go +++ b/internal/arduino/resources/helpers_test.go @@ -22,11 +22,10 @@ import ( "strings" "testing" - "github.com/arduino/arduino-cli/internal/arduino/httpclient" + "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" - "go.bug.st/downloader/v2" ) type EchoHandler struct{} @@ -37,8 +36,7 @@ func (h *EchoHandler) ServeHTTP(writer http.ResponseWriter, request *http.Reques } func TestDownloadApplyUserAgentHeaderUsingConfig(t *testing.T) { - goldUserAgentValue := "arduino-cli/0.0.0-test.preview (amd64; linux; go1.12.4) Commit:deadbeef/Build:2019-06-12 11:11:11.111" - goldUserAgentString := "User-Agent: " + goldUserAgentValue + goldUserAgentValue := "arduino-cli/0.0.0-test.preview" tmp, err := paths.MkTempDir("", "") require.NoError(t, err) @@ -54,9 +52,11 @@ func TestDownloadApplyUserAgentHeaderUsingConfig(t *testing.T) { URL: srv.URL, } - httpClient := httpclient.NewWithConfig(&httpclient.Config{UserAgent: goldUserAgentValue}) - - err = r.Download(tmp, &downloader.Config{HttpClient: *httpClient}, "", func(progress *rpc.DownloadProgress) {}, "") + settings := configuration.Init("") + settings.Set("network.user_agent_ext", goldUserAgentValue) + config, err := settings.DownloaderConfig() + require.NoError(t, err) + err = r.Download(tmp, config, "", func(progress *rpc.DownloadProgress) {}, "") require.NoError(t, err) // leverage the download helper to download the echo for the request made by the downloader itself @@ -71,12 +71,11 @@ func TestDownloadApplyUserAgentHeaderUsingConfig(t *testing.T) { require.NoError(t, err) requestLines := strings.Split(string(b), "\r\n") - userAgentHeaderString := "" + userAgentHeader := "" for _, line := range requestLines { if strings.Contains(line, "User-Agent: ") { - userAgentHeaderString = line + userAgentHeader = line } } - require.Equal(t, goldUserAgentString, userAgentHeaderString) - + require.Contains(t, userAgentHeader, goldUserAgentValue) } diff --git a/internal/arduino/resources/index.go b/internal/arduino/resources/index.go index 4740c6f12f0..fb05f55d776 100644 --- a/internal/arduino/resources/index.go +++ b/internal/arduino/resources/index.go @@ -58,7 +58,7 @@ func (res *IndexResource) IndexFileName() (string, error) { // Download will download the index and possibly check the signature using the Arduino's public key. // If the file is in .gz format it will be unpacked first. -func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadProgressCB) error { +func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadProgressCB, config downloader.Config) error { // Create destination directory if err := destDir.MkdirAll(); err != nil { return &cmderrors.PermissionDeniedError{Message: tr("Can't create data directory %s", destDir), Cause: err} @@ -78,7 +78,7 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP return err } tmpIndexPath := tmp.Join(downloadFileName) - if err := httpclient.DownloadFile(tmpIndexPath, res.URL.String(), "", tr("Downloading index: %s", downloadFileName), downloadCB, nil, downloader.NoResume); err != nil { + if err := httpclient.DownloadFile(tmpIndexPath, res.URL.String(), "", tr("Downloading index: %s", downloadFileName), downloadCB, config, downloader.NoResume); err != nil { return &cmderrors.FailedDownloadError{Message: tr("Error downloading index '%s'", res.URL), Cause: err} } @@ -133,7 +133,7 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP // Download signature signaturePath = destDir.Join(signatureFileName) tmpSignaturePath = tmp.Join(signatureFileName) - if err := httpclient.DownloadFile(tmpSignaturePath, res.SignatureURL.String(), "", tr("Downloading index signature: %s", signatureFileName), downloadCB, nil, downloader.NoResume); err != nil { + if err := httpclient.DownloadFile(tmpSignaturePath, res.SignatureURL.String(), "", tr("Downloading index signature: %s", signatureFileName), downloadCB, config, downloader.NoResume); err != nil { return &cmderrors.FailedDownloadError{Message: tr("Error downloading index signature '%s'", res.SignatureURL), Cause: err} } diff --git a/internal/arduino/resources/resources_test.go b/internal/arduino/resources/resources_test.go index 9cf8ae54509..ee987ddcea6 100644 --- a/internal/arduino/resources/resources_test.go +++ b/internal/arduino/resources/resources_test.go @@ -49,7 +49,7 @@ func TestDownloadAndChecksums(t *testing.T) { require.NoError(t, err) downloadAndTestChecksum := func() { - err := r.Download(tmp, &downloader.Config{}, "", func(*rpc.DownloadProgress) {}, "") + err := r.Download(tmp, downloader.Config{}, "", func(*rpc.DownloadProgress) {}, "") require.NoError(t, err) data, err := testFile.ReadFile() @@ -63,7 +63,7 @@ func TestDownloadAndChecksums(t *testing.T) { downloadAndTestChecksum() // Download with cached file - err = r.Download(tmp, &downloader.Config{}, "", func(*rpc.DownloadProgress) {}, "") + err = r.Download(tmp, downloader.Config{}, "", func(*rpc.DownloadProgress) {}, "") require.NoError(t, err) // Download if cached file has data in excess (redownload) @@ -132,7 +132,7 @@ func TestIndexDownloadAndSignatureWithinArchive(t *testing.T) { destDir, err := paths.MkTempDir("", "") require.NoError(t, err) defer destDir.RemoveAll() - err = idxResource.Download(destDir, func(curr *rpc.DownloadProgress) {}) + err = idxResource.Download(destDir, func(curr *rpc.DownloadProgress) {}, downloader.GetDefaultConfig()) require.NoError(t, err) require.True(t, destDir.Join("package_index.json").Exist()) require.True(t, destDir.Join("package_index.json.sig").Exist()) @@ -143,7 +143,7 @@ func TestIndexDownloadAndSignatureWithinArchive(t *testing.T) { invDestDir, err := paths.MkTempDir("", "") require.NoError(t, err) defer invDestDir.RemoveAll() - err = invIdxResource.Download(invDestDir, func(curr *rpc.DownloadProgress) {}) + err = invIdxResource.Download(invDestDir, func(curr *rpc.DownloadProgress) {}, downloader.GetDefaultConfig()) require.Error(t, err) require.Contains(t, err.Error(), "invalid signature") require.False(t, invDestDir.Join("package_index.json").Exist()) diff --git a/internal/cli/arguments/reference_test.go b/internal/cli/arguments/reference_test.go index b4176dc4e5e..f91109f8de6 100644 --- a/internal/cli/arguments/reference_test.go +++ b/internal/cli/arguments/reference_test.go @@ -48,10 +48,6 @@ var badCores = []struct { {"", nil}, } -func init() { - configuration.Settings = configuration.Init("") -} - func TestArgsStringify(t *testing.T) { for _, core := range goodCores { require.Equal(t, core.in, core.expected.String()) @@ -59,7 +55,7 @@ func TestArgsStringify(t *testing.T) { } func TestParseReferenceCores(t *testing.T) { - srv := commands.NewArduinoCoreServer("") + srv := commands.NewArduinoCoreServer("", configuration.Init("")) ctx := context.Background() for _, tt := range goodCores { actual, err := arguments.ParseReference(ctx, srv, tt.in) @@ -80,7 +76,7 @@ func TestParseArgs(t *testing.T) { input = append(input, tt.in) } - srv := commands.NewArduinoCoreServer("") + srv := commands.NewArduinoCoreServer("", configuration.Init("")) refs, err := arguments.ParseReferences(context.Background(), srv, input) assert.Nil(t, err) assert.Equal(t, len(goodCores), len(refs)) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index d2bb82305f6..ef6c54e806e 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -63,7 +63,7 @@ var ( ) // NewCommand creates a new ArduinoCli command root -func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { cobra.AddTemplateFunc("tr", i18n.Tr) var updaterMessageChan chan *semver.Version @@ -79,7 +79,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { outputFormat = "json" } - preRun(cmd, args) + preRun(cmd, defaultSettings) if cmd.Name() != "version" { updaterMessageChan = make(chan *semver.Version) @@ -115,13 +115,13 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cmd.AddCommand(board.NewCommand(srv)) cmd.AddCommand(cache.NewCommand(srv)) - cmd.AddCommand(compile.NewCommand(srv)) + cmd.AddCommand(compile.NewCommand(srv, defaultSettings)) cmd.AddCommand(completion.NewCommand()) - cmd.AddCommand(config.NewCommand()) + cmd.AddCommand(config.NewCommand(srv, defaultSettings)) cmd.AddCommand(core.NewCommand(srv)) - cmd.AddCommand(daemon.NewCommand()) + cmd.AddCommand(daemon.NewCommand(srv, defaultSettings)) cmd.AddCommand(generatedocs.NewCommand()) - cmd.AddCommand(lib.NewCommand(srv)) + cmd.AddCommand(lib.NewCommand(srv, defaultSettings)) cmd.AddCommand(monitor.NewCommand(srv)) cmd.AddCommand(outdated.NewCommand(srv)) cmd.AddCommand(sketch.NewCommand(srv)) @@ -156,7 +156,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cmd.PersistentFlags().StringVar(&configFile, "config-file", "", tr("The custom config file (if not specified the default will be used).")) cmd.PersistentFlags().StringSlice("additional-urls", []string{}, tr("Comma-separated list of additional URLs for the Boards Manager.")) cmd.PersistentFlags().Bool("no-color", false, "Disable colored output.") - configuration.BindFlags(cmd, configuration.Settings) + configuration.BindFlags(cmd, defaultSettings) return cmd } @@ -177,17 +177,17 @@ func toLogLevel(s string) (t logrus.Level, found bool) { return } -func preRun(cmd *cobra.Command, args []string) { - configFile := configuration.Settings.ConfigFileUsed() +func preRun(cmd *cobra.Command, defaultSettings *configuration.Settings) { + configFile := defaultSettings.ConfigFileUsed() // initialize inventory - err := inventory.Init(configuration.DataDir(configuration.Settings).String()) + err := inventory.Init(configuration.DataDir(defaultSettings).String()) if err != nil { feedback.Fatal(fmt.Sprintf("Error: %v", err), feedback.ErrInitializingInventory) } // https://no-color.org/ - color.NoColor = configuration.Settings.GetBool("output.no_color") || os.Getenv("NO_COLOR") != "" + color.NoColor = defaultSettings.GetBool("output.no_color") || os.Getenv("NO_COLOR") != "" // Set default feedback output to colorable feedback.SetOut(colorable.NewColorableStdout()) @@ -210,13 +210,13 @@ func preRun(cmd *cobra.Command, args []string) { } // set the Logger format - logFormat := strings.ToLower(configuration.Settings.GetString("logging.format")) + logFormat := strings.ToLower(defaultSettings.GetString("logging.format")) if logFormat == "json" { logrus.SetFormatter(&logrus.JSONFormatter{}) } // should we log to file? - logFile := configuration.Settings.GetString("logging.file") + logFile := defaultSettings.GetString("logging.file") if logFile != "" { file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { @@ -232,8 +232,8 @@ func preRun(cmd *cobra.Command, args []string) { } // configure logging filter - if lvl, found := toLogLevel(configuration.Settings.GetString("logging.level")); !found { - feedback.Fatal(tr("Invalid option for --log-level: %s", configuration.Settings.GetString("logging.level")), feedback.ErrBadArgument) + if lvl, found := toLogLevel(defaultSettings.GetString("logging.level")); !found { + feedback.Fatal(tr("Invalid option for --log-level: %s", defaultSettings.GetString("logging.level")), feedback.ErrBadArgument) } else { logrus.SetLevel(lvl) } diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 219a5e0b3ea..290b5a4c649 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -77,7 +77,7 @@ var ( ) // NewCommand created a new `compile` command -func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { compileCommand := &cobra.Command{ Use: "compile", Short: tr("Compiles Arduino sketches."), @@ -133,7 +133,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { compileCommand.Flags().BoolVar(&skipLibrariesDiscovery, "skip-libraries-discovery", false, "Skip libraries discovery. This flag is provided only for use in language server and other, very specific, use cases. Do not use for normal compiles") compileCommand.Flag("skip-libraries-discovery").Hidden = true compileCommand.Flags().Int32VarP(&jobs, "jobs", "j", 0, tr("Max number of parallel compiles. If set to 0 the number of available CPUs cores will be used.")) - configuration.Settings.BindPFlag("sketch.always_export_binaries", compileCommand.Flags().Lookup("export-binaries")) + defaultSettings.BindPFlag("sketch.always_export_binaries", compileCommand.Flags().Lookup("export-binaries")) compileCommand.Flags().MarkDeprecated("build-properties", tr("please use --build-property instead.")) diff --git a/internal/cli/config/add.go b/internal/cli/config/add.go index 5018b0440de..5678e52e470 100644 --- a/internal/cli/config/add.go +++ b/internal/cli/config/add.go @@ -44,7 +44,7 @@ func uniquify[T comparable](s []T) []T { return result } -func initAddCommand() *cobra.Command { +func initAddCommand(defaultSettings *configuration.Settings) *cobra.Command { addCommand := &cobra.Command{ Use: "add", Short: tr("Adds one or more values to a setting."), @@ -53,15 +53,17 @@ func initAddCommand() *cobra.Command { " " + os.Args[0] + " config add board_manager.additional_urls https://example.com/package_example_index.json\n" + " " + os.Args[0] + " config add board_manager.additional_urls https://example.com/package_example_index.json https://another-url.com/package_another_index.json\n", Args: cobra.MinimumNArgs(2), - Run: runAddCommand, + Run: func(cmd *cobra.Command, args []string) { + runAddCommand(args, defaultSettings) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetConfigurationKeys(), cobra.ShellCompDirectiveDefault + return GetSlicesConfigurationKeys(defaultSettings), cobra.ShellCompDirectiveDefault }, } return addCommand } -func runAddCommand(cmd *cobra.Command, args []string) { +func runAddCommand(args []string, defaultSettings *configuration.Settings) { logrus.Info("Executing `arduino-cli config add`") key := args[0] kind := validateKey(key) @@ -71,12 +73,12 @@ func runAddCommand(cmd *cobra.Command, args []string) { feedback.Fatal(msg, feedback.ErrGeneric) } - v := configuration.Settings.GetStringSlice(key) + v := defaultSettings.GetStringSlice(key) v = append(v, args[1:]...) v = uniquify(v) - configuration.Settings.Set(key, v) + defaultSettings.Set(key, v) - if err := configuration.Settings.WriteConfig(); err != nil { + if err := defaultSettings.WriteConfig(); err != nil { feedback.Fatal(tr("Can't write config file: %v", err), feedback.ErrGeneric) } } diff --git a/internal/cli/config/config.go b/internal/cli/config/config.go index c59714478d3..d8d4cbf5e46 100644 --- a/internal/cli/config/config.go +++ b/internal/cli/config/config.go @@ -21,35 +21,36 @@ import ( "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/i18n" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) var tr = i18n.Tr // NewCommand created a new `config` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { configCommand := &cobra.Command{ Use: "config", Short: tr("Arduino configuration commands."), Example: " " + os.Args[0] + " config init", } - configCommand.AddCommand(initAddCommand()) - configCommand.AddCommand(initDeleteCommand()) - configCommand.AddCommand(initDumpCommand()) - configCommand.AddCommand(initGetCommand()) - configCommand.AddCommand(initInitCommand()) - configCommand.AddCommand(initRemoveCommand()) - configCommand.AddCommand(initSetCommand()) + configCommand.AddCommand(initAddCommand(defaultSettings)) + configCommand.AddCommand(initDeleteCommand(srv, defaultSettings)) + configCommand.AddCommand(initDumpCommand(defaultSettings)) + configCommand.AddCommand(initGetCommand(srv, defaultSettings)) + configCommand.AddCommand(initInitCommand(defaultSettings)) + configCommand.AddCommand(initRemoveCommand(defaultSettings)) + configCommand.AddCommand(initSetCommand(defaultSettings)) return configCommand } -// GetConfigurationKeys is an helper function useful to autocomplete. +// GetSlicesConfigurationKeys is an helper function useful to autocomplete. // It returns a list of configuration keys which can be changed -func GetConfigurationKeys() []string { +func GetSlicesConfigurationKeys(settings *configuration.Settings) []string { var res []string - keys := configuration.Settings.AllKeys() + keys := settings.AllKeys() for _, key := range keys { kind, _ := typeOf(key) if kind == reflect.Slice { diff --git a/internal/cli/config/delete.go b/internal/cli/config/delete.go index e5889a12952..75b81563aed 100644 --- a/internal/cli/config/delete.go +++ b/internal/cli/config/delete.go @@ -16,9 +16,9 @@ package config import ( + "context" "os" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -26,7 +26,8 @@ import ( "github.com/spf13/cobra" ) -func initDeleteCommand() *cobra.Command { +func initDeleteCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { + configFile := defaultSettings.ConfigFileUsed() deleteCommand := &cobra.Command{ Use: "delete", Short: tr("Deletes a settings key and all its sub keys."), @@ -35,25 +36,27 @@ func initDeleteCommand() *cobra.Command { " " + os.Args[0] + " config delete board_manager\n" + " " + os.Args[0] + " config delete board_manager.additional_urls", Args: cobra.ExactArgs(1), - Run: runDeleteCommand, + Run: func(cmd *cobra.Command, args []string) { + runDeleteCommand(srv, args, configFile) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return configuration.Settings.AllKeys(), cobra.ShellCompDirectiveDefault + return defaultSettings.AllKeys(), cobra.ShellCompDirectiveDefault }, } return deleteCommand } -func runDeleteCommand(cmd *cobra.Command, args []string) { +func runDeleteCommand(srv rpc.ArduinoCoreServiceServer, args []string, configFile string) { logrus.Info("Executing `arduino-cli config delete`") - toDelete := args[0] + ctx := context.Background() - svc := commands.NewArduinoCoreServer("") - _, err := svc.SettingsDelete(cmd.Context(), &rpc.SettingsDeleteRequest{Key: toDelete}) + toDelete := args[0] + _, err := srv.SettingsDelete(ctx, &rpc.SettingsDeleteRequest{Key: toDelete}) if err != nil { feedback.Fatal(tr("Cannot delete the key %[1]s: %[2]v", toDelete, err), feedback.ErrGeneric) } - _, err = svc.SettingsWrite(cmd.Context(), &rpc.SettingsWriteRequest{FilePath: configuration.Settings.ConfigFileUsed()}) + _, err = srv.SettingsWrite(ctx, &rpc.SettingsWriteRequest{FilePath: configFile}) if err != nil { - feedback.Fatal(tr("Cannot write the file %[1]s: %[2]v", configuration.Settings.ConfigFileUsed(), err), feedback.ErrGeneric) + feedback.Fatal(tr("Cannot write the file %[1]s: %[2]v", configFile, err), feedback.ErrGeneric) } } diff --git a/internal/cli/config/dump.go b/internal/cli/config/dump.go index 9e10bf34f9b..695e5b11ce8 100644 --- a/internal/cli/config/dump.go +++ b/internal/cli/config/dump.go @@ -25,23 +25,21 @@ import ( "gopkg.in/yaml.v3" ) -func initDumpCommand() *cobra.Command { +func initDumpCommand(defaultSettings *configuration.Settings) *cobra.Command { var dumpCommand = &cobra.Command{ Use: "dump", Short: tr("Prints the current configuration"), Long: tr("Prints the current configuration."), Example: " " + os.Args[0] + " config dump", Args: cobra.NoArgs, - Run: runDumpCommand, + Run: func(cmd *cobra.Command, args []string) { + logrus.Info("Executing `arduino-cli config dump`") + feedback.PrintResult(dumpResult{defaultSettings.AllSettings()}) + }, } return dumpCommand } -func runDumpCommand(cmd *cobra.Command, args []string) { - logrus.Info("Executing `arduino-cli config dump`") - feedback.PrintResult(dumpResult{configuration.Settings.AllSettings()}) -} - // output from this command requires special formatting, let's create a dedicated // feedback.Result implementation type dumpResult struct { diff --git a/internal/cli/config/get.go b/internal/cli/config/get.go index 68b8afd0d4a..dec61be03a7 100644 --- a/internal/cli/config/get.go +++ b/internal/cli/config/get.go @@ -16,11 +16,11 @@ package config import ( + "context" "encoding/json" "fmt" "os" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -29,7 +29,7 @@ import ( "gopkg.in/yaml.v3" ) -func initGetCommand() *cobra.Command { +func initGetCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { getCommand := &cobra.Command{ Use: "get", Short: tr("Gets a settings key value."), @@ -39,20 +39,22 @@ func initGetCommand() *cobra.Command { " " + os.Args[0] + " config get daemon.port\n" + " " + os.Args[0] + " config get board_manager.additional_urls", Args: cobra.MinimumNArgs(1), - Run: runGetCommand, + Run: func(cmd *cobra.Command, args []string) { + runGetCommand(srv, args) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return configuration.Settings.AllKeys(), cobra.ShellCompDirectiveDefault + return defaultSettings.AllKeys(), cobra.ShellCompDirectiveDefault }, } return getCommand } -func runGetCommand(cmd *cobra.Command, args []string) { +func runGetCommand(srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli config get`") + ctx := context.Background() - svc := commands.NewArduinoCoreServer("") for _, toGet := range args { - resp, err := svc.SettingsGetValue(cmd.Context(), &rpc.SettingsGetValueRequest{Key: toGet}) + resp, err := srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: toGet}) if err != nil { feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", toGet, err), feedback.ErrGeneric) } diff --git a/internal/cli/config/init.go b/internal/cli/config/init.go index afb05f74279..5bbc753b153 100644 --- a/internal/cli/config/init.go +++ b/internal/cli/config/init.go @@ -25,7 +25,6 @@ import ( "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "github.com/spf13/viper" ) var ( @@ -36,7 +35,7 @@ var ( const defaultFileName = "arduino-cli.yaml" -func initInitCommand() *cobra.Command { +func initInitCommand(defaultSettings *configuration.Settings) *cobra.Command { initCommand := &cobra.Command{ Use: "init", Short: tr("Writes current configuration to a configuration file."), @@ -50,7 +49,9 @@ func initInitCommand() *cobra.Command { PreRun: func(cmd *cobra.Command, args []string) { arguments.CheckFlagsConflicts(cmd, "dest-file", "dest-dir") }, - Run: runInitCommand, + Run: func(cmd *cobra.Command, args []string) { + runInitCommand(cmd, defaultSettings) + }, } initCommand.Flags().StringVar(&destDir, "dest-dir", "", tr("Sets where to save the configuration file.")) initCommand.Flags().StringVar(&destFile, "dest-file", "", tr("Sets where to save the configuration file.")) @@ -58,11 +59,11 @@ func initInitCommand() *cobra.Command { return initCommand } -func runInitCommand(cmd *cobra.Command, args []string) { +func runInitCommand(cmd *cobra.Command, defaultSettings *configuration.Settings) { logrus.Info("Executing `arduino-cli config init`") var configFileAbsPath *paths.Path - var absPath *paths.Path + var configFileDir *paths.Path var err error switch { @@ -72,30 +73,29 @@ func runInitCommand(cmd *cobra.Command, args []string) { feedback.Fatal(tr("Cannot find absolute path: %v", err), feedback.ErrGeneric) } - absPath = configFileAbsPath.Parent() + configFileDir = configFileAbsPath.Parent() case destDir == "": - destDir = configuration.Settings.GetString("directories.Data") + destDir = defaultSettings.GetString("directories.Data") fallthrough default: - absPath, err = paths.New(destDir).Abs() + configFileDir, err = paths.New(destDir).Abs() if err != nil { feedback.Fatal(tr("Cannot find absolute path: %v", err), feedback.ErrGeneric) } - configFileAbsPath = absPath.Join(defaultFileName) + configFileAbsPath = configFileDir.Join(defaultFileName) } if !overwrite && configFileAbsPath.Exist() { feedback.Fatal(tr("Config file already exists, use --overwrite to discard the existing one."), feedback.ErrGeneric) } - logrus.Infof("Writing config file to: %s", absPath) + logrus.Infof("Writing config file to: %s", configFileDir) - if err := absPath.MkdirAll(); err != nil { + if err := configFileDir.MkdirAll(); err != nil { feedback.Fatal(tr("Cannot create config file directory: %v", err), feedback.ErrGeneric) } - newSettings := viper.New() - configuration.SetDefaults(newSettings) + newSettings := configuration.NewSettings() configuration.BindFlags(cmd, newSettings) for _, url := range newSettings.GetStringSlice("board_manager.additional_urls") { diff --git a/internal/cli/config/remove.go b/internal/cli/config/remove.go index d7870172b0c..efbd416913a 100644 --- a/internal/cli/config/remove.go +++ b/internal/cli/config/remove.go @@ -25,7 +25,7 @@ import ( "github.com/spf13/cobra" ) -func initRemoveCommand() *cobra.Command { +func initRemoveCommand(defaultSettings *configuration.Settings) *cobra.Command { removeCommand := &cobra.Command{ Use: "remove", Short: tr("Removes one or more values from a setting."), @@ -34,15 +34,17 @@ func initRemoveCommand() *cobra.Command { " " + os.Args[0] + " config remove board_manager.additional_urls https://example.com/package_example_index.json\n" + " " + os.Args[0] + " config remove board_manager.additional_urls https://example.com/package_example_index.json https://another-url.com/package_another_index.json\n", Args: cobra.MinimumNArgs(2), - Run: runRemoveCommand, + Run: func(cmd *cobra.Command, args []string) { + runRemoveCommand(args, defaultSettings) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetConfigurationKeys(), cobra.ShellCompDirectiveDefault + return GetSlicesConfigurationKeys(defaultSettings), cobra.ShellCompDirectiveDefault }, } return removeCommand } -func runRemoveCommand(cmd *cobra.Command, args []string) { +func runRemoveCommand(args []string, defaultSettings *configuration.Settings) { logrus.Info("Executing `arduino-cli config remove`") key := args[0] kind := validateKey(key) @@ -53,7 +55,7 @@ func runRemoveCommand(cmd *cobra.Command, args []string) { } mappedValues := map[string]bool{} - for _, v := range configuration.Settings.GetStringSlice(key) { + for _, v := range defaultSettings.GetStringSlice(key) { mappedValues[v] = true } for _, arg := range args[1:] { @@ -63,9 +65,9 @@ func runRemoveCommand(cmd *cobra.Command, args []string) { for k := range mappedValues { values = append(values, k) } - configuration.Settings.Set(key, values) + defaultSettings.Set(key, values) - if err := configuration.Settings.WriteConfig(); err != nil { + if err := defaultSettings.WriteConfig(); err != nil { feedback.Fatal(tr("Can't write config file: %v", err), feedback.ErrGeneric) } } diff --git a/internal/cli/config/set.go b/internal/cli/config/set.go index 8fd002277da..10fb9e6f239 100644 --- a/internal/cli/config/set.go +++ b/internal/cli/config/set.go @@ -26,7 +26,7 @@ import ( "github.com/spf13/cobra" ) -func initSetCommand() *cobra.Command { +func initSetCommand(defaultSettings *configuration.Settings) *cobra.Command { setCommand := &cobra.Command{ Use: "set", Short: tr("Sets a setting value."), @@ -37,15 +37,17 @@ func initSetCommand() *cobra.Command { " " + os.Args[0] + " config set sketch.always_export_binaries true\n" + " " + os.Args[0] + " config set board_manager.additional_urls https://example.com/package_example_index.json https://another-url.com/package_another_index.json", Args: cobra.MinimumNArgs(2), - Run: runSetCommand, + Run: func(cmd *cobra.Command, args []string) { + runSetCommand(defaultSettings, args) + }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return configuration.Settings.AllKeys(), cobra.ShellCompDirectiveDefault + return defaultSettings.AllKeys(), cobra.ShellCompDirectiveDefault }, } return setCommand } -func runSetCommand(cmd *cobra.Command, args []string) { +func runSetCommand(defaultSettings *configuration.Settings, args []string) { logrus.Info("Executing `arduino-cli config set`") key := args[0] kind := validateKey(key) @@ -68,9 +70,9 @@ func runSetCommand(cmd *cobra.Command, args []string) { } } - configuration.Settings.Set(key, value) + defaultSettings.Set(key, value) - if err := configuration.Settings.WriteConfig(); err != nil { + if err := defaultSettings.WriteConfig(); err != nil { feedback.Fatal(tr("Writing config file: %v", err), feedback.ErrGeneric) } } diff --git a/internal/cli/configuration/configuration.go b/internal/cli/configuration/configuration.go index e251b80c514..996a1b1cbfc 100644 --- a/internal/cli/configuration/configuration.go +++ b/internal/cli/configuration/configuration.go @@ -29,18 +29,26 @@ import ( "github.com/spf13/viper" ) -// Settings is a global instance of viper holding configurations for the CLI and the gRPC consumers -var Settings *viper.Viper - var tr = i18n.Tr +// Settings contains the configuration of the Arduino CLI core service +type Settings struct { + *viper.Viper +} + +// NewSettings creates a new instance of Settings with the default values set +func NewSettings() *Settings { + res := &Settings{viper.New()} + SetDefaults(res) + return res +} + // Init initialize defaults and read the configuration file. // Please note the logging system hasn't been configured yet, // so logging shouldn't be used here. -func Init(configFile string) *viper.Viper { +func Init(configFile string) *Settings { // Create a new viper instance with default values for all the settings - settings := viper.New() - SetDefaults(settings) + settings := NewSettings() // Set config name and config path if configFilePath := paths.New(configFile); configFilePath != nil { @@ -70,7 +78,7 @@ func Init(configFile string) *viper.Viper { } // BindFlags creates all the flags binding between the cobra Command and the instance of viper -func BindFlags(cmd *cobra.Command, settings *viper.Viper) { +func BindFlags(cmd *cobra.Command, settings *Settings) { settings.BindPFlag("logging.level", cmd.Flag("log-level")) settings.BindPFlag("logging.file", cmd.Flag("log-file")) settings.BindPFlag("logging.format", cmd.Flag("log-format")) diff --git a/internal/cli/configuration/defaults.go b/internal/cli/configuration/defaults.go index be1a0088a62..c983310a746 100644 --- a/internal/cli/configuration/defaults.go +++ b/internal/cli/configuration/defaults.go @@ -19,12 +19,10 @@ import ( "path/filepath" "strings" "time" - - "github.com/spf13/viper" ) // SetDefaults sets the default values for certain keys -func SetDefaults(settings *viper.Viper) { +func SetDefaults(settings *Settings) { // logging settings.SetDefault("logging.level", "info") settings.SetDefault("logging.format", "text") diff --git a/internal/cli/configuration/directories.go b/internal/cli/configuration/directories.go index 27669e9017c..0fb9a9d19e5 100644 --- a/internal/cli/configuration/directories.go +++ b/internal/cli/configuration/directories.go @@ -17,15 +17,14 @@ package configuration import ( "github.com/arduino/go-paths-helper" - "github.com/spf13/viper" ) // HardwareDirectories returns all paths that may contains hardware packages. -func HardwareDirectories(settings *viper.Viper) paths.PathList { +func HardwareDirectories(settings *Settings) paths.PathList { res := paths.PathList{} if settings.IsSet("directories.Data") { - packagesDir := PackagesDir(Settings) + packagesDir := PackagesDir(settings) if packagesDir.IsDir() { res.Add(packagesDir) } @@ -44,34 +43,34 @@ func HardwareDirectories(settings *viper.Viper) paths.PathList { // IDEBuiltinLibrariesDir returns the IDE-bundled libraries path. Usually // this directory is present in the Arduino IDE. -func IDEBuiltinLibrariesDir(settings *viper.Viper) *paths.Path { - return paths.New(Settings.GetString("directories.builtin.Libraries")) +func IDEBuiltinLibrariesDir(settings *Settings) *paths.Path { + return paths.New(settings.GetString("directories.builtin.Libraries")) } // LibrariesDir returns the full path to the user directory containing // custom libraries -func LibrariesDir(settings *viper.Viper) *paths.Path { +func LibrariesDir(settings *Settings) *paths.Path { return paths.New(settings.GetString("directories.User")).Join("libraries") } // PackagesDir returns the full path to the packages folder -func PackagesDir(settings *viper.Viper) *paths.Path { +func PackagesDir(settings *Settings) *paths.Path { return DataDir(settings).Join("packages") } // ProfilesCacheDir returns the full path to the profiles cache directory // (it contains all the platforms and libraries used to compile a sketch // using profiles) -func ProfilesCacheDir(settings *viper.Viper) *paths.Path { +func ProfilesCacheDir(settings *Settings) *paths.Path { return DataDir(settings).Join("internal") } // DataDir returns the full path to the data directory -func DataDir(settings *viper.Viper) *paths.Path { +func DataDir(settings *Settings) *paths.Path { return paths.New(settings.GetString("directories.Data")) } // DownloadsDir returns the full path to the download cache directory -func DownloadsDir(settings *viper.Viper) *paths.Path { +func DownloadsDir(settings *Settings) *paths.Path { return paths.New(settings.GetString("directories.Downloads")) } diff --git a/internal/cli/configuration/network.go b/internal/cli/configuration/network.go index 793c67de155..c88b974c10d 100644 --- a/internal/cli/configuration/network.go +++ b/internal/cli/configuration/network.go @@ -17,16 +17,18 @@ package configuration import ( "fmt" + "net/http" "net/url" "os" "runtime" + "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/version" - "github.com/spf13/viper" + "go.bug.st/downloader/v2" ) // UserAgent returns the user agent (mainly used by HTTP clients) -func UserAgent(settings *viper.Viper) string { +func UserAgent(settings *Settings) string { subComponent := "" if settings != nil { subComponent = settings.GetString("network.user_agent_ext") @@ -50,7 +52,7 @@ func UserAgent(settings *viper.Viper) string { } // NetworkProxy returns the proxy configuration (mainly used by HTTP clients) -func NetworkProxy(settings *viper.Viper) (*url.URL, error) { +func NetworkProxy(settings *Settings) (*url.URL, error) { if settings == nil || !settings.IsSet("network.proxy") { return nil, nil } @@ -65,3 +67,42 @@ func NetworkProxy(settings *viper.Viper) (*url.URL, error) { return proxy, nil } } + +// NewHttpClient returns a new http client for use in the arduino-cli +func (settings *Settings) NewHttpClient() (*http.Client, error) { + proxy, err := NetworkProxy(settings) + if err != nil { + return nil, err + } + return &http.Client{ + Transport: &httpClientRoundTripper{ + transport: &http.Transport{ + Proxy: http.ProxyURL(proxy), + }, + userAgent: UserAgent(settings), + }, + }, nil +} + +type httpClientRoundTripper struct { + transport http.RoundTripper + userAgent string +} + +func (h *httpClientRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Add("User-Agent", h.userAgent) + return h.transport.RoundTrip(req) +} + +// DownloaderConfig returns the downloader configuration based on current settings. +func (settings *Settings) DownloaderConfig() (downloader.Config, error) { + httpClient, err := settings.NewHttpClient() + if err != nil { + return downloader.Config{}, &cmderrors.InvalidArgumentError{ + Message: tr("Could not connect via HTTP"), + Cause: err} + } + return downloader.Config{ + HttpClient: *httpClient, + }, nil +} diff --git a/internal/arduino/httpclient/httpclient_test.go b/internal/cli/configuration/network_test.go similarity index 79% rename from internal/arduino/httpclient/httpclient_test.go rename to internal/cli/configuration/network_test.go index a2dbc61c291..6d6218c8f5d 100644 --- a/internal/arduino/httpclient/httpclient_test.go +++ b/internal/cli/configuration/network_test.go @@ -13,16 +13,16 @@ // Arduino software without disclosing the source code of your own applications. // To purchase a commercial license, send an email to license@arduino.cc. -package httpclient +package configuration_test import ( "fmt" "io" "net/http" "net/http/httptest" - "net/url" "testing" + "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/stretchr/testify/require" ) @@ -32,9 +32,10 @@ func TestUserAgentHeader(t *testing.T) { })) defer ts.Close() - client := NewWithConfig(&Config{ - UserAgent: "test-user-agent", - }) + settings := configuration.Init("") + settings.Set("network.user_agent_ext", "test-user-agent") + client, err := settings.NewHttpClient() + require.NoError(t, err) request, err := http.NewRequest("GET", ts.URL, nil) require.NoError(t, err) @@ -45,7 +46,7 @@ func TestUserAgentHeader(t *testing.T) { b, err := io.ReadAll(response.Body) require.NoError(t, err) - require.Equal(t, "test-user-agent", string(b)) + require.Contains(t, string(b), "test-user-agent") } func TestProxy(t *testing.T) { @@ -54,13 +55,11 @@ func TestProxy(t *testing.T) { })) defer ts.Close() - proxyURL, err := url.Parse(ts.URL) + settings := configuration.Init("") + settings.Set("network.proxy", ts.URL) + client, err := settings.NewHttpClient() require.NoError(t, err) - client := NewWithConfig(&Config{ - Proxy: proxyURL, - }) - request, err := http.NewRequest("GET", "http://arduino.cc", nil) require.NoError(t, err) diff --git a/internal/cli/daemon/daemon.go b/internal/cli/daemon/daemon.go index 2422a03c2c2..8e719400eaf 100644 --- a/internal/cli/daemon/daemon.go +++ b/internal/cli/daemon/daemon.go @@ -24,12 +24,10 @@ import ( "strings" "syscall" - "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/i18n" - srv_commands "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" - "github.com/arduino/arduino-cli/version" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -45,17 +43,24 @@ var ( ) // NewCommand created a new `daemon` command -func NewCommand() *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { + var daemonPort string daemonCommand := &cobra.Command{ Use: "daemon", - Short: tr("Run as a daemon on port: %s", configuration.Settings.GetString("daemon.port")), - Long: tr("Running as a daemon the initialization of cores and libraries is done only once."), + Short: tr("Run the Arduino CLI as a gRPC daemon."), Example: " " + os.Args[0] + " daemon", Args: cobra.NoArgs, - Run: runDaemonCommand, + PreRun: func(cmd *cobra.Command, args []string) { + // Bundled libraries support is enabled by default when running as a daemon + defaultSettings.SetDefault( + "directories.builtin.Libraries", + configuration.GetDefaultBuiltinLibrariesDir()) + }, + Run: func(cmd *cobra.Command, args []string) { + runDaemonCommand(srv, daemonPort) + }, } - daemonCommand.PersistentFlags().String("port", "", tr("The TCP port the daemon will listen to")) - configuration.Settings.BindPFlag("daemon.port", daemonCommand.PersistentFlags().Lookup("port")) + daemonCommand.Flags().StringVar(&daemonPort, "port", defaultSettings.GetString("daemon.port"), tr("The TCP port the daemon will listen to")) daemonCommand.Flags().BoolVar(&daemonize, "daemonize", false, tr("Do not terminate daemon process if the parent process dies")) daemonCommand.Flags().BoolVar(&debug, "debug", false, tr("Enable debug logging of gRPC calls")) daemonCommand.Flags().StringVar(&debugFile, "debug-file", "", tr("Append debug logging to the specified file")) @@ -63,13 +68,9 @@ func NewCommand() *cobra.Command { return daemonCommand } -func runDaemonCommand(cmd *cobra.Command, args []string) { +func runDaemonCommand(srv rpc.ArduinoCoreServiceServer, daemonPort string) { logrus.Info("Executing `arduino-cli daemon`") - // Bundled libraries support is enabled by default when running as a daemon - configuration.Settings.SetDefault("directories.builtin.Libraries", configuration.GetDefaultBuiltinLibrariesDir()) - - port := configuration.Settings.GetString("daemon.port") gRPCOptions := []grpc.ServerOption{} if debugFile != "" { if !debug { @@ -98,43 +99,40 @@ func runDaemonCommand(cmd *cobra.Command, args []string) { ) } s := grpc.NewServer(gRPCOptions...) - // Set specific user-agent for the daemon - configuration.Settings.Set("network.user_agent_ext", "daemon") // register the commands service - srv_commands.RegisterArduinoCoreServiceServer(s, - commands.NewArduinoCoreServer(version.VersionInfo.VersionString)) + rpc.RegisterArduinoCoreServiceServer(s, srv) if !daemonize { // When parent process ends terminate also the daemon go feedback.ExitWhenParentProcessEnds() } - ip := "127.0.0.1" - lis, err := net.Listen("tcp", fmt.Sprintf("%s:%s", ip, port)) + daemonIP := "127.0.0.1" + lis, err := net.Listen("tcp", fmt.Sprintf("%s:%s", daemonIP, daemonPort)) if err != nil { // Invalid port, such as "Foo" var dnsError *net.DNSError if errors.As(err, &dnsError) { - feedback.Fatal(tr("Failed to listen on TCP port: %[1]s. %[2]s is unknown name.", port, dnsError.Name), feedback.ErrBadTCPPortArgument) + feedback.Fatal(tr("Failed to listen on TCP port: %[1]s. %[2]s is unknown name.", daemonPort, dnsError.Name), feedback.ErrBadTCPPortArgument) } // Invalid port number, such as -1 var addrError *net.AddrError if errors.As(err, &addrError) { - feedback.Fatal(tr("Failed to listen on TCP port: %[1]s. %[2]s is an invalid port.", port, addrError.Addr), feedback.ErrBadTCPPortArgument) + feedback.Fatal(tr("Failed to listen on TCP port: %[1]s. %[2]s is an invalid port.", daemonPort, addrError.Addr), feedback.ErrBadTCPPortArgument) } // Port is already in use var syscallErr *os.SyscallError if errors.As(err, &syscallErr) && errors.Is(syscallErr.Err, syscall.EADDRINUSE) { - feedback.Fatal(tr("Failed to listen on TCP port: %s. Address already in use.", port), feedback.ErrFailedToListenToTCPPort) + feedback.Fatal(tr("Failed to listen on TCP port: %s. Address already in use.", daemonPort), feedback.ErrFailedToListenToTCPPort) } - feedback.Fatal(tr("Failed to listen on TCP port: %[1]s. Unexpected error: %[2]v", port, err), feedback.ErrFailedToListenToTCPPort) + feedback.Fatal(tr("Failed to listen on TCP port: %[1]s. Unexpected error: %[2]v", daemonPort, err), feedback.ErrFailedToListenToTCPPort) } // We need to retrieve the port used only if the user did not specify it // and let the OS choose it randomly, in all other cases we already know // which port is used. - if port == "0" { + if daemonPort == "0" { address := lis.Addr() split := strings.Split(address.String(), ":") @@ -142,12 +140,12 @@ func runDaemonCommand(cmd *cobra.Command, args []string) { feedback.Fatal(tr("Invalid TCP address: port is missing"), feedback.ErrBadTCPPortArgument) } - port = split[1] + daemonPort = split[1] } feedback.PrintResult(daemonResult{ - IP: ip, - Port: port, + IP: daemonIP, + Port: daemonPort, }) if err := s.Serve(lis); err != nil { diff --git a/internal/cli/lib/install.go b/internal/cli/lib/install.go index dce521eb6d3..d8aafc8bd1a 100644 --- a/internal/cli/lib/install.go +++ b/internal/cli/lib/install.go @@ -34,12 +34,13 @@ import ( semver "go.bug.st/relaxed-semver" ) -func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { +func initInstallCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { var noDeps bool var noOverwrite bool var gitURL bool var zipPath bool var useBuiltinLibrariesDir bool + enableUnsafeInstall := defaultSettings.GetBool("library.enable_unsafe_install") installCommand := &cobra.Command{ Use: fmt.Sprintf("install %s[@%s]...", tr("LIBRARY"), tr("VERSION_NUMBER")), Short: tr("Installs one or more specified libraries into the system."), @@ -52,7 +53,7 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " lib install --zip-path /path/to/WiFi101.zip /path/to/ArduinoBLE.zip\n", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runInstallCommand(srv, args, noDeps, noOverwrite, gitURL, zipPath, useBuiltinLibrariesDir) + runInstallCommand(srv, args, noDeps, noOverwrite, gitURL, zipPath, useBuiltinLibrariesDir, enableUnsafeInstall) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return arguments.GetInstallableLibs(context.Background(), srv), cobra.ShellCompDirectiveDefault @@ -66,13 +67,13 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return installCommand } -func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps bool, noOverwrite bool, gitURL bool, zipPath bool, useBuiltinLibrariesDir bool) { +func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps bool, noOverwrite bool, gitURL bool, zipPath bool, useBuiltinLibrariesDir bool, enableUnsafeInstall bool) { ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib install`") if zipPath || gitURL { - if !configuration.Settings.GetBool("library.enable_unsafe_install") { + if !enableUnsafeInstall { documentationURL := "https://arduino.github.io/arduino-cli/latest/configuration/#configuration-keys" _, err := semver.Parse(version.VersionInfo.VersionString) if err == nil { diff --git a/internal/cli/lib/lib.go b/internal/cli/lib/lib.go index deab795b9f5..d26c8678f08 100644 --- a/internal/cli/lib/lib.go +++ b/internal/cli/lib/lib.go @@ -18,6 +18,7 @@ package lib import ( "os" + "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" @@ -26,7 +27,7 @@ import ( var tr = i18n.Tr // NewCommand created a new `lib` command -func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { libCommand := &cobra.Command{ Use: "lib", Short: tr("Arduino commands about libraries."), @@ -37,7 +38,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } libCommand.AddCommand(initDownloadCommand(srv)) - libCommand.AddCommand(initInstallCommand(srv)) + libCommand.AddCommand(initInstallCommand(srv, defaultSettings)) libCommand.AddCommand(initListCommand(srv)) libCommand.AddCommand(initExamplesCommand(srv)) libCommand.AddCommand(initSearchCommand(srv)) diff --git a/internal/docsgen/main.go b/internal/docsgen/main.go index eb8903507e1..69ac4983de9 100644 --- a/internal/docsgen/main.go +++ b/internal/docsgen/main.go @@ -31,8 +31,8 @@ func main() { os.MkdirAll(os.Args[1], 0755) // Create the output folder if it doesn't already exist - configuration.Settings = configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args)) - cli := cli.NewCommand(nil) + settings := configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args)) + cli := cli.NewCommand(nil, settings) cli.DisableAutoGenTag = true // Disable addition of auto-generated date stamp err := doc.GenMarkdownTree(cli, os.Args[1]) if err != nil { diff --git a/main.go b/main.go index 8587037fbf1..2255ae626b4 100644 --- a/main.go +++ b/main.go @@ -27,12 +27,12 @@ import ( ) func main() { - configuration.Settings = configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args)) - i18n.Init(configuration.Settings.GetString("locale")) + defaultSettings := configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args)) + i18n.Init(defaultSettings.GetString("locale")) - srv := commands.NewArduinoCoreServer(version.VersionInfo.VersionString) + srv := commands.NewArduinoCoreServer(version.VersionInfo.VersionString, defaultSettings) - arduinoCmd := cli.NewCommand(srv) + arduinoCmd := cli.NewCommand(srv, defaultSettings) if err := arduinoCmd.Execute(); err != nil { feedback.FatalError(err, feedback.ErrGeneric) } From 4c50868a2ad1733a280479acb3b5f1a3f3bbccbc Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 17 Apr 2024 23:38:42 +0200 Subject: [PATCH 32/56] Implementation of Viper replacement library - Using configmap allows better handling of config types - The CLI "instances" now caches all the configuration at Create-time - Setting are now only accessible via gRPC calls - Helper methods have been implemented to access all key/value pairs --- commands/instances.go | 25 +- commands/internal/instances/instances.go | 4 +- commands/service.go | 18 +- commands/service_board_list_test.go | 24 +- commands/service_cache_clean.go | 3 +- commands/service_compile.go | 13 +- commands/service_debug_test.go | 2 +- commands/service_platform_search_test.go | 24 +- commands/service_settings.go | 279 +-- commands/service_settings_test.go | 240 ++- commands/service_sketch_load_test.go | 3 +- commands/service_sketch_new_test.go | 11 +- commands/service_upload_test.go | 2 +- .../arduino/cores/packagemanager/loader.go | 11 +- .../cores/packagemanager/loader_test.go | 2 +- .../cores/packagemanager/package_manager.go | 8 +- .../packagemanager/package_manager_test.go | 33 +- .../arduino/cores/packagemanager/profiles.go | 6 +- internal/arduino/resources/helpers_test.go | 2 +- internal/cli/arguments/reference_test.go | 5 +- internal/cli/cache/clean.go | 2 +- internal/cli/cli.go | 135 +- internal/cli/compile/compile.go | 12 +- internal/cli/config/add.go | 62 +- internal/cli/config/config.go | 60 +- internal/cli/config/delete.go | 26 +- internal/cli/config/dump.go | 46 +- internal/cli/config/get.go | 9 +- internal/cli/config/init.go | 41 +- internal/cli/config/remove.go | 43 +- internal/cli/config/set.go | 50 +- internal/cli/config/validate.go | 61 - internal/cli/configuration/board_manager.go | 23 + internal/cli/configuration/build_cache.go | 34 + internal/cli/configuration/configuration.go | 66 +- .../cli/configuration/configuration_test.go | 41 +- internal/cli/configuration/daemon.go | 23 + internal/cli/configuration/defaults.go | 65 +- internal/cli/configuration/directories.go | 56 +- internal/cli/configuration/libraries.go | 20 + internal/cli/configuration/locale.go | 20 + internal/cli/configuration/logging.go | 42 + internal/cli/configuration/network.go | 23 +- internal/cli/configuration/network_test.go | 4 +- internal/cli/configuration/output.go | 20 + internal/cli/configuration/sketch.go | 25 + internal/cli/configuration/updater.go | 23 + internal/cli/daemon/daemon.go | 41 +- internal/cli/lib/install.go | 5 +- internal/cli/lib/lib.go | 3 +- internal/cli/lib/search.go | 1 + internal/docsgen/main.go | 9 +- internal/go-configmap/cli.go | 111 ++ internal/go-configmap/configuration.go | 212 +++ internal/go-configmap/configuration_test.go | 168 ++ internal/go-configmap/json.go | 52 + internal/go-configmap/json_test.go | 48 + internal/go-configmap/types.go | 215 +++ internal/go-configmap/yaml.go | 38 + internal/go-configmap/yaml_test.go | 48 + internal/integrationtest/arduino-cli.go | 6 +- .../integrationtest/compile_1/compile_test.go | 2 +- main.go | 42 +- rpc/cc/arduino/cli/commands/v1/commands.pb.go | 152 +- rpc/cc/arduino/cli/commands/v1/commands.proto | 27 +- .../cli/commands/v1/commands_grpc.pb.go | 186 +- rpc/cc/arduino/cli/commands/v1/settings.pb.go | 1615 ++++++++++++++--- rpc/cc/arduino/cli/commands/v1/settings.proto | 152 +- rpc/internal/client_example/main.go | 103 +- 69 files changed, 3724 insertions(+), 1259 deletions(-) delete mode 100644 internal/cli/config/validate.go create mode 100644 internal/cli/configuration/board_manager.go create mode 100644 internal/cli/configuration/build_cache.go create mode 100644 internal/cli/configuration/daemon.go create mode 100644 internal/cli/configuration/libraries.go create mode 100644 internal/cli/configuration/locale.go create mode 100644 internal/cli/configuration/logging.go create mode 100644 internal/cli/configuration/output.go create mode 100644 internal/cli/configuration/sketch.go create mode 100644 internal/cli/configuration/updater.go create mode 100644 internal/go-configmap/cli.go create mode 100644 internal/go-configmap/configuration.go create mode 100644 internal/go-configmap/configuration_test.go create mode 100644 internal/go-configmap/json.go create mode 100644 internal/go-configmap/json_test.go create mode 100644 internal/go-configmap/types.go create mode 100644 internal/go-configmap/yaml.go create mode 100644 internal/go-configmap/yaml_test.go diff --git a/commands/instances.go b/commands/instances.go index 7d461be1fc8..58156465322 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -36,7 +36,6 @@ import ( "github.com/arduino/arduino-cli/internal/arduino/resources" "github.com/arduino/arduino-cli/internal/arduino/sketch" "github.com/arduino/arduino-cli/internal/arduino/utils" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" @@ -72,7 +71,7 @@ func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque } // Setup downloads directory - downloadsDir := configuration.DownloadsDir(s.settings) + downloadsDir := s.settings.DownloadsDir() if downloadsDir.NotExist() { err := downloadsDir.MkdirAll() if err != nil { @@ -81,8 +80,9 @@ func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque } // Setup data directory - dataDir := configuration.DataDir(s.settings) - packagesDir := configuration.PackagesDir(s.settings) + dataDir := s.settings.DataDir() + userPackagesDir := s.settings.UserDir().Join("hardware") + packagesDir := s.settings.PackagesDir() if packagesDir.NotExist() { err := packagesDir.MkdirAll() if err != nil { @@ -94,7 +94,7 @@ func (s *arduinoCoreServerImpl) Create(ctx context.Context, req *rpc.CreateReque if err != nil { return nil, err } - inst, err := instances.Create(dataDir, packagesDir, downloadsDir, userAgent, config) + inst, err := instances.Create(dataDir, packagesDir, userPackagesDir, downloadsDir, userAgent, config) if err != nil { return nil, err } @@ -177,7 +177,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor defaultIndexURL, _ := utils.URLParse(globals.DefaultIndexURL) allPackageIndexUrls := []*url.URL{defaultIndexURL} if profile == nil { - for _, u := range s.settings.GetStringSlice("board_manager.additional_urls") { + for _, u := range s.settings.BoardManagerAdditionalUrls() { URL, err := utils.URLParse(u) if err != nil { e := &cmderrors.InitFailedError{ @@ -192,7 +192,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor } } - if err := firstUpdate(ctx, s, req.GetInstance(), configuration.DataDir(s.settings), downloadCallback, allPackageIndexUrls); err != nil { + if err := firstUpdate(ctx, s, req.GetInstance(), s.settings.DataDir(), downloadCallback, allPackageIndexUrls); err != nil { e := &cmderrors.InitFailedError{ Code: codes.InvalidArgument, Cause: err, @@ -245,7 +245,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor // Load Platforms if profile == nil { - for _, err := range pmb.LoadHardware(s.settings) { + for _, err := range pmb.LoadHardware() { s := &cmderrors.PlatformLoadingError{Cause: err} responseError(s.GRPCStatus()) } @@ -349,7 +349,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor if profile == nil { // Add directories of libraries bundled with IDE - if bundledLibsDir := configuration.IDEBuiltinLibrariesDir(s.settings); bundledLibsDir != nil { + if bundledLibsDir := s.settings.IDEBuiltinLibrariesDir(); bundledLibsDir != nil { lmb.AddLibrariesDir(librariesmanager.LibrariesDir{ Path: bundledLibsDir, Location: libraries.IDEBuiltIn, @@ -358,14 +358,14 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor // Add libraries directory from config file lmb.AddLibrariesDir(librariesmanager.LibrariesDir{ - Path: configuration.LibrariesDir(s.settings), + Path: s.settings.LibrariesDir(), Location: libraries.User, }) } else { // Load libraries required for profile for _, libraryRef := range profile.Libraries { uid := libraryRef.InternalUniqueIdentifier() - libRoot := configuration.ProfilesCacheDir(s.settings).Join(uid) + libRoot := s.settings.ProfilesCacheDir().Join(uid) libDir := libRoot.Join(libraryRef.Library) if !libDir.IsDir() { @@ -548,7 +548,7 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream Message: &rpc.UpdateIndexResponse_DownloadProgress{DownloadProgress: p}, }) } - indexpath := configuration.DataDir(s.settings) + indexpath := s.settings.DataDir() urls := []string{globals.DefaultIndexURL} if !req.GetIgnoreCustomPackageIndexes() { @@ -614,6 +614,7 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream downloadCB.Start(u, tr("Downloading index: %s", filepath.Base(URL.Path))) downloadCB.End(false, tr("Invalid network configuration: %s", err)) failed = true + continue } if strings.HasSuffix(URL.Host, "arduino.cc") && strings.HasSuffix(URL.Path, ".json") { diff --git a/commands/internal/instances/instances.go b/commands/internal/instances/instances.go index b5cd63a3287..272eaaaafdb 100644 --- a/commands/internal/instances/instances.go +++ b/commands/internal/instances/instances.go @@ -134,7 +134,7 @@ func SetLibraryManager(inst *rpc.Instance, lm *librariesmanager.LibrariesManager } // Create a new *rpc.Instance ready to be initialized -func Create(dataDir, packagesDir, downloadsDir *paths.Path, extraUserAgent string, downloaderConfig downloader.Config) (*rpc.Instance, error) { +func Create(dataDir, packagesDir, userPackagesDir, downloadsDir *paths.Path, extraUserAgent string, downloaderConfig downloader.Config) (*rpc.Instance, error) { // Create package manager userAgent := "arduino-cli/" + version.VersionInfo.VersionString if extraUserAgent != "" { @@ -142,7 +142,7 @@ func Create(dataDir, packagesDir, downloadsDir *paths.Path, extraUserAgent strin } tempDir := dataDir.Join("tmp") - pm := packagemanager.NewBuilder(dataDir, packagesDir, downloadsDir, tempDir, userAgent, downloaderConfig).Build() + pm := packagemanager.NewBuilder(dataDir, packagesDir, userPackagesDir, downloadsDir, tempDir, userAgent, downloaderConfig).Build() lm, _ := librariesmanager.NewBuilder().Build() instance := &coreInstance{ diff --git a/commands/service.go b/commands/service.go index 03da5135b29..46c7bf3e6d5 100644 --- a/commands/service.go +++ b/commands/service.go @@ -19,28 +19,30 @@ import ( "context" "github.com/arduino/arduino-cli/internal/cli/configuration" + "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "github.com/arduino/arduino-cli/version" ) // NewArduinoCoreServer returns an implementation of the ArduinoCoreService gRPC service // that uses the provided version string. -func NewArduinoCoreServer(version string, settings *configuration.Settings) rpc.ArduinoCoreServiceServer { - return &arduinoCoreServerImpl{ - versionString: version, - settings: settings, - } +func NewArduinoCoreServer() rpc.ArduinoCoreServiceServer { + settings := configuration.NewSettings() + + // Setup i18n + i18n.Init(settings.Locale()) + + return &arduinoCoreServerImpl{settings: settings} } type arduinoCoreServerImpl struct { rpc.UnsafeArduinoCoreServiceServer // Force compile error for unimplemented methods - versionString string - // Settings holds configurations of the CLI and the gRPC consumers settings *configuration.Settings } // Version returns the version of the Arduino CLI func (s *arduinoCoreServerImpl) Version(ctx context.Context, req *rpc.VersionRequest) (*rpc.VersionResponse, error) { - return &rpc.VersionResponse{Version: s.versionString}, nil + return &rpc.VersionResponse{Version: version.VersionInfo.VersionString}, nil } diff --git a/commands/service_board_list_test.go b/commands/service_board_list_test.go index e9132a50949..6fb1366d111 100644 --- a/commands/service_board_list_test.go +++ b/commands/service_board_list_test.go @@ -48,7 +48,8 @@ func TestGetByVidPid(t *testing.T) { defer ts.Close() vidPidURL = ts.URL - res, err := apiByVidPid("0xf420", "0XF069", configuration.Init("")) + settings := configuration.NewSettings() + res, err := apiByVidPid("0xf420", "0XF069", settings) require.Nil(t, err) require.Len(t, res, 1) require.Equal(t, "Arduino/Genuino MKR1000", res[0].GetName()) @@ -56,23 +57,27 @@ func TestGetByVidPid(t *testing.T) { // wrong vid (too long), wrong pid (not an hex value) - _, err = apiByVidPid("0xfffff", "0xDEFG", configuration.Init("")) + _, err = apiByVidPid("0xfffff", "0xDEFG", settings) require.NotNil(t, err) } func TestGetByVidPidNotFound(t *testing.T) { + settings := configuration.NewSettings() + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotFound) })) defer ts.Close() vidPidURL = ts.URL - res, err := apiByVidPid("0x0420", "0x0069", configuration.Init("")) + res, err := apiByVidPid("0x0420", "0x0069", settings) require.NoError(t, err) require.Empty(t, res) } func TestGetByVidPid5xx(t *testing.T) { + settings := configuration.NewSettings() + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("500 - Ooooops!")) @@ -80,27 +85,30 @@ func TestGetByVidPid5xx(t *testing.T) { defer ts.Close() vidPidURL = ts.URL - res, err := apiByVidPid("0x0420", "0x0069", configuration.Init("")) + res, err := apiByVidPid("0x0420", "0x0069", settings) require.NotNil(t, err) require.Equal(t, "the server responded with status 500 Internal Server Error", err.Error()) require.Len(t, res, 0) } func TestGetByVidPidMalformedResponse(t *testing.T) { + settings := configuration.NewSettings() + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "{}") })) defer ts.Close() vidPidURL = ts.URL - res, err := apiByVidPid("0x0420", "0x0069", configuration.Init("")) + res, err := apiByVidPid("0x0420", "0x0069", settings) require.NotNil(t, err) require.Equal(t, "wrong format in server response", err.Error()) require.Len(t, res, 0) } func TestBoardDetectionViaAPIWithNonUSBPort(t *testing.T) { - items, err := identifyViaCloudAPI(properties.NewMap(), configuration.Init("")) + settings := configuration.NewSettings() + items, err := identifyViaCloudAPI(properties.NewMap(), settings) require.NoError(t, err) require.Empty(t, items) } @@ -112,7 +120,7 @@ func TestBoardIdentifySorting(t *testing.T) { defer paths.TempDir().Join("test").RemoveAll() // We don't really care about the paths in this case - pmb := packagemanager.NewBuilder(dataDir, dataDir, dataDir, dataDir, "test", downloader.GetDefaultConfig()) + pmb := packagemanager.NewBuilder(dataDir, dataDir, nil, dataDir, dataDir, "test", downloader.GetDefaultConfig()) // Create some boards with identical VID:PID combination pack := pmb.GetOrCreatePackage("packager") @@ -148,7 +156,7 @@ func TestBoardIdentifySorting(t *testing.T) { pme, release := pm.NewExplorer() defer release() - settings := configuration.Init("") + settings := configuration.NewSettings() res, err := identify(pme, &discovery.Port{Properties: idPrefs}, settings) require.NoError(t, err) require.NotNil(t, res) diff --git a/commands/service_cache_clean.go b/commands/service_cache_clean.go index df7a091f635..5897ebd2e99 100644 --- a/commands/service_cache_clean.go +++ b/commands/service_cache_clean.go @@ -18,13 +18,12 @@ package commands import ( "context" - "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" ) // CleanDownloadCacheDirectory clean the download cache directory (where archives are downloaded). func (s *arduinoCoreServerImpl) CleanDownloadCacheDirectory(ctx context.Context, req *rpc.CleanDownloadCacheDirectoryRequest) (*rpc.CleanDownloadCacheDirectoryResponse, error) { - cachePath := configuration.DownloadsDir(s.settings) + cachePath := s.settings.DownloadsDir() err := cachePath.RemoveAll() if err != nil { return nil, err diff --git a/commands/service_compile.go b/commands/service_compile.go index d7320caeed2..9722c72671a 100644 --- a/commands/service_compile.go +++ b/commands/service_compile.go @@ -32,7 +32,6 @@ import ( "github.com/arduino/arduino-cli/internal/arduino/sketch" "github.com/arduino/arduino-cli/internal/arduino/utils" "github.com/arduino/arduino-cli/internal/buildcache" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/inventory" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" paths "github.com/arduino/go-paths-helper" @@ -67,7 +66,7 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu ctx := stream.Context() syncSend := NewSynchronizedSend(stream.Send) - exportBinaries := s.settings.GetBool("sketch.always_export_binaries") + exportBinaries := s.settings.SketchAlwaysExportBinaries() if e := req.ExportBinaries; e != nil { exportBinaries = *e } @@ -175,8 +174,8 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu // cache is purged after compilation to not remove entries that might be required defer maybePurgeBuildCache( - s.settings.GetUint("build_cache.compilations_before_purge"), - s.settings.GetDuration("build_cache.ttl").Abs()) + s.settings.GetCompilationsBeforeBuildCachePurge(), + s.settings.GetBuildCacheTTL().Abs()) var coreBuildCachePath *paths.Path if req.GetBuildCachePath() == "" { @@ -198,7 +197,7 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu actualPlatform := buildPlatform otherLibrariesDirs := paths.NewPathList(req.GetLibraries()...) - otherLibrariesDirs.Add(configuration.LibrariesDir(s.settings)) + otherLibrariesDirs.Add(s.settings.LibrariesDir()) var libsManager *librariesmanager.LibrariesManager if pme.GetProfile() != nil { @@ -231,9 +230,9 @@ func (s *arduinoCoreServerImpl) Compile(req *rpc.CompileRequest, stream rpc.Ardu coreBuildCachePath, int(req.GetJobs()), req.GetBuildProperties(), - configuration.HardwareDirectories(s.settings), + s.settings.HardwareDirectories(), otherLibrariesDirs, - configuration.IDEBuiltinLibrariesDir(s.settings), + s.settings.IDEBuiltinLibrariesDir(), fqbn, req.GetClean(), req.GetSourceOverride(), diff --git a/commands/service_debug_test.go b/commands/service_debug_test.go index 8e627c44b76..1aa4feb9796 100644 --- a/commands/service_debug_test.go +++ b/commands/service_debug_test.go @@ -37,7 +37,7 @@ func TestGetCommandLine(t *testing.T) { sketchPath := paths.New("testdata", "debug", sketch) require.NoError(t, sketchPath.ToAbs()) - pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) + pmb := packagemanager.NewBuilder(nil, nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pmb.LoadHardwareFromDirectory(dataDir) diff --git a/commands/service_platform_search_test.go b/commands/service_platform_search_test.go index 3b7b87cf30d..dc7df5f190c 100644 --- a/commands/service_platform_search_test.go +++ b/commands/service_platform_search_test.go @@ -19,7 +19,6 @@ import ( "context" "testing" - "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" @@ -36,9 +35,17 @@ func TestPlatformSearch(t *testing.T) { err := paths.New("testdata", "platform", "package_index.json").CopyTo(dataDir.Join("package_index.json")) require.Nil(t, err) - settings := configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) - srv := NewArduinoCoreServer("", settings) ctx := context.Background() + srv := NewArduinoCoreServer() + + conf, err := paths.TempDir().Join("test", "arduino-cli.yaml").ReadFile() + require.NoError(t, err) + _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{ + SettingsFormat: "yaml", + EncodedSettings: string(conf), + }) + require.NoError(t, err) + createResp, err := srv.Create(ctx, &rpc.CreateRequest{}) require.NoError(t, err) @@ -337,9 +344,16 @@ func TestPlatformSearchSorting(t *testing.T) { err := paths.New("testdata", "platform", "package_index.json").CopyTo(dataDir.Join("package_index.json")) require.Nil(t, err) - settings := configuration.Init(paths.TempDir().Join("test", "arduino-cli.yaml").String()) - srv := NewArduinoCoreServer("", settings) ctx := context.Background() + srv := NewArduinoCoreServer() + + conf, err := paths.TempDir().Join("test", "arduino-cli.yaml").ReadFile() + require.NoError(t, err) + _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{ + SettingsFormat: "yaml", + EncodedSettings: string(conf), + }) + require.NoError(t, err) createResp, err := srv.Create(ctx, &rpc.CreateRequest{}) require.NoError(t, err) diff --git a/commands/service_settings.go b/commands/service_settings.go index 177d0819178..82bdb030aeb 100644 --- a/commands/service_settings.go +++ b/commands/service_settings.go @@ -18,161 +18,204 @@ package commands import ( "context" "encoding/json" - "errors" "fmt" - "strings" + "reflect" + "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "google.golang.org/protobuf/proto" + "gopkg.in/yaml.v3" ) -// SettingsGetAll returns a message with a string field containing all the settings -// currently in use, marshalled in JSON format. -func (s *arduinoCoreServerImpl) SettingsGetAll(ctx context.Context, req *rpc.SettingsGetAllRequest) (*rpc.SettingsGetAllResponse, error) { - b, err := json.Marshal(s.settings.AllSettings()) - if err == nil { - return &rpc.SettingsGetAllResponse{ - JsonData: string(b), - }, nil +// SettingsGetValue returns a settings value given its key. If the key is not present +// an error will be returned, so that we distinguish empty settings from missing +// ones. +func (s *arduinoCoreServerImpl) ConfigurationGet(ctx context.Context, req *rpc.ConfigurationGetRequest) (*rpc.ConfigurationGetResponse, error) { + conf := &rpc.Configuration{ + Directories: &rpc.Configuration_Directories{ + Builtin: &rpc.Configuration_Directories_Builtin{}, + Data: s.settings.DataDir().String(), + Downloads: s.settings.DownloadsDir().String(), + User: s.settings.UserDir().String(), + }, + Network: &rpc.Configuration_Network{}, + Sketch: &rpc.Configuration_Sketch{ + AlwaysExportBinaries: s.settings.SketchAlwaysExportBinaries(), + }, + BuildCache: &rpc.Configuration_BuildCache{ + CompilationsBeforePurge: uint64(s.settings.GetCompilationsBeforeBuildCachePurge()), + TtlSecs: uint64(s.settings.GetBuildCacheTTL().Seconds()), + }, + BoardManager: &rpc.Configuration_BoardManager{ + AdditionalUrls: s.settings.BoardManagerAdditionalUrls(), + }, + Daemon: &rpc.Configuration_Daemon{ + Port: s.settings.DaemonPort(), + }, + Output: &rpc.Configuration_Output{ + NoColor: s.settings.NoColor(), + }, + Logging: &rpc.Configuration_Logging{ + Level: s.settings.LoggingLevel(), + Format: s.settings.LoggingFormat(), + }, + Library: &rpc.Configuration_Library{ + EnableUnsafeInstall: s.settings.LibraryEnableUnsafeInstall(), + }, + Updater: &rpc.Configuration_Updater{ + EnableNotification: s.settings.UpdaterEnableNotification(), + }, } - return nil, err -} - -// mapper converts a map of nested maps to a map of scalar values. -// For example: -// -// {"foo": "bar", "daemon":{"port":"420"}, "sketch": {"always_export_binaries": "true"}} -// -// would convert to: -// -// {"foo": "bar", "daemon.port":"420", "sketch.always_export_binaries": "true"} -func mapper(toMap map[string]interface{}) map[string]interface{} { - res := map[string]interface{}{} - for k, v := range toMap { - switch data := v.(type) { - case map[string]interface{}: - for mK, mV := range mapper(data) { - // Concatenate keys - res[fmt.Sprintf("%s.%s", k, mK)] = mV - } - // This is done to avoid skipping keys containing empty maps - if len(data) == 0 { - res[k] = map[string]interface{}{} - } - default: - res[k] = v - } + if builtinLibs := s.settings.IDEBuiltinLibrariesDir(); builtinLibs != nil { + conf.Directories.Builtin.Libraries = proto.String(builtinLibs.String()) } - return res -} -// SettingsMerge applies multiple settings values at once. -func (s *arduinoCoreServerImpl) SettingsMerge(ctx context.Context, req *rpc.SettingsMergeRequest) (*rpc.SettingsMergeResponse, error) { - var toMerge map[string]interface{} - if err := json.Unmarshal([]byte(req.GetJsonData()), &toMerge); err != nil { - return nil, err + if ua := s.settings.ExtraUserAgent(); ua != "" { + conf.Network.ExtraUserAgent = &ua + } + if proxy, err := s.settings.NetworkProxy(); err == nil && proxy != nil { + conf.Network.Proxy = proto.String(proxy.String()) } - mapped := mapper(toMerge) + if logFile := s.settings.LoggingFile(); logFile != nil { + file := logFile.String() + conf.Logging.File = &file + } - // Set each value individually. - // This is done because Viper ignores empty strings or maps when - // using the MergeConfigMap function. - updatedSettings := configuration.Init("") - for k, v := range mapped { - updatedSettings.Set(k, v) + if locale := s.settings.Locale(); locale != "" { + conf.Locale = &locale } - configPath := s.settings.ConfigFileUsed() - updatedSettings.SetConfigFile(configPath) - s.settings = updatedSettings - return &rpc.SettingsMergeResponse{}, nil + return &rpc.ConfigurationGetResponse{Configuration: conf}, nil } -// SettingsGetValue returns a settings value given its key. If the key is not present -// an error will be returned, so that we distinguish empty settings from missing -// ones. -func (s *arduinoCoreServerImpl) SettingsGetValue(ctx context.Context, req *rpc.SettingsGetValueRequest) (*rpc.SettingsGetValueResponse, error) { +func (s *arduinoCoreServerImpl) SettingsSetValue(ctx context.Context, req *rpc.SettingsSetValueRequest) (*rpc.SettingsSetValueResponse, error) { + // Determine the existence and the kind of the value key := req.GetKey() - // Check if settings key actually existing, we don't use Viper.InConfig() - // since that doesn't check for keys formatted like daemon.port or those set - // with Viper.Set(). This way we check for all existing settings for sure. - keyExists := false - for _, k := range s.settings.AllKeys() { - if k == key || strings.HasPrefix(k, key) { - keyExists = true - break + // Extract the value from the request + encodedValue := []byte(req.GetEncodedValue()) + if len(encodedValue) == 0 { + // If the value is empty, unset the key + s.settings.Delete(key) + return &rpc.SettingsSetValueResponse{}, nil + } + + var newValue any + switch req.GetValueFormat() { + case "", "json": + if err := json.Unmarshal(encodedValue, &newValue); err != nil { + return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("invalid value: %v", err)} } + case "yaml": + if err := yaml.Unmarshal(encodedValue, &newValue); err != nil { + return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("invalid value: %v", err)} + } + case "cli": + err := s.settings.SetFromCLIArgs(key, req.GetEncodedValue()) + if err != nil { + return nil, err + } + return &rpc.SettingsSetValueResponse{}, nil + default: + return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported value format: %s", req.ValueFormat)} } - if !keyExists { - return nil, errors.New(tr("key not found in settings")) + + // If the value is "null", unset the key + if reflect.TypeOf(newValue) == reflect.TypeOf(nil) { + s.settings.Delete(key) + return &rpc.SettingsSetValueResponse{}, nil } - b, err := json.Marshal(s.settings.Get(key)) - value := &rpc.SettingsGetValueResponse{} - if err == nil { - value.Key = key - value.JsonData = string(b) + // Set the value + if err := s.settings.Set(key, newValue); err != nil { + return nil, err } - return value, err + return &rpc.SettingsSetValueResponse{}, nil } -// SettingsSetValue updates or set a value for a certain key. -func (s *arduinoCoreServerImpl) SettingsSetValue(ctx context.Context, val *rpc.SettingsSetValueRequest) (*rpc.SettingsSetValueResponse, error) { - key := val.GetKey() - var value interface{} - - err := json.Unmarshal([]byte(val.GetJsonData()), &value) - if err == nil { - s.settings.Set(key, value) +func (s *arduinoCoreServerImpl) SettingsGetValue(ctx context.Context, req *rpc.SettingsGetValueRequest) (*rpc.SettingsGetValueResponse, error) { + key := req.GetKey() + value, ok := s.settings.GetOk(key) + if !ok { + value, ok = s.settings.Defaults.GetOk(key) + } + if !ok { + return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("key %s not found", key)} } - return &rpc.SettingsSetValueResponse{}, err + switch req.GetValueFormat() { + case "", "json": + valueJson, err := json.Marshal(value) + if err != nil { + return nil, fmt.Errorf("error marshalling value: %v", err) + } + return &rpc.SettingsGetValueResponse{EncodedValue: string(valueJson)}, nil + case "yaml": + valueYaml, err := yaml.Marshal(value) + if err != nil { + return nil, fmt.Errorf("error marshalling value: %v", err) + } + return &rpc.SettingsGetValueResponse{EncodedValue: string(valueYaml)}, nil + default: + return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported value format: %s", req.ValueFormat)} + } } -// SettingsWrite to file set in request the settings currently stored in memory. -// We don't have a Read() function, that's not necessary since we only want one config file to be used -// and that's picked up when the CLI is run as daemon, either using the default path or a custom one -// set with the --config-file flag. -func (s *arduinoCoreServerImpl) SettingsWrite(ctx context.Context, req *rpc.SettingsWriteRequest) (*rpc.SettingsWriteResponse, error) { - if err := s.settings.WriteConfigAs(req.GetFilePath()); err != nil { - return nil, err +// ConfigurationSave encodes the current configuration in the specified format +func (s *arduinoCoreServerImpl) ConfigurationSave(ctx context.Context, req *rpc.ConfigurationSaveRequest) (*rpc.ConfigurationSaveResponse, error) { + switch req.GetSettingsFormat() { + case "yaml": + data, err := yaml.Marshal(s.settings) + if err != nil { + return nil, fmt.Errorf("error marshalling settings: %v", err) + } + return &rpc.ConfigurationSaveResponse{EncodedSettings: string(data)}, nil + case "json": + data, err := json.Marshal(s.settings) + if err != nil { + return nil, fmt.Errorf("error marshalling settings: %v", err) + } + return &rpc.ConfigurationSaveResponse{EncodedSettings: string(data)}, nil + default: + return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported format: %s", req.GetSettingsFormat())} } - return &rpc.SettingsWriteResponse{}, nil } -// SettingsDelete removes a key from the config file -func (s *arduinoCoreServerImpl) SettingsDelete(ctx context.Context, req *rpc.SettingsDeleteRequest) (*rpc.SettingsDeleteResponse, error) { - toDelete := req.GetKey() - - // Check if settings key actually existing, we don't use Viper.InConfig() - // since that doesn't check for keys formatted like daemon.port or those set - // with Viper.Set(). This way we check for all existing settings for sure. - keyExists := false - keys := []string{} - for _, k := range s.settings.AllKeys() { - if !strings.HasPrefix(k, toDelete) { - keys = append(keys, k) - continue +// SettingsReadFromFile read settings from a YAML file and replace the settings currently stored in memory. +func (s *arduinoCoreServerImpl) ConfigurationOpen(ctx context.Context, req *rpc.ConfigurationOpenRequest) (*rpc.ConfigurationOpenResponse, error) { + switch req.GetSettingsFormat() { + case "yaml": + err := yaml.Unmarshal([]byte(req.GetEncodedSettings()), s.settings) + if err != nil { + return nil, fmt.Errorf("error unmarshalling settings: %v", err) } - keyExists = true + case "json": + err := json.Unmarshal([]byte(req.GetEncodedSettings()), s.settings) + if err != nil { + return nil, fmt.Errorf("error unmarshalling settings: %v", err) + } + default: + return nil, &cmderrors.InvalidArgumentError{Message: fmt.Sprintf("unsupported format: %s", req.GetSettingsFormat())} } - if !keyExists { - return nil, errors.New(tr("key not found in settings")) - } + configuration.InjectEnvVars(s.settings) + return &rpc.ConfigurationOpenResponse{}, nil +} - // Override current settings to delete the key - updatedSettings := configuration.Init("") - for _, k := range keys { - updatedSettings.Set(k, s.settings.Get(k)) +// SettingsEnumerate returns the list of all the settings keys. +func (s *arduinoCoreServerImpl) SettingsEnumerate(ctx context.Context, req *rpc.SettingsEnumerateRequest) (*rpc.SettingsEnumerateResponse, error) { + var entries []*rpc.SettingsEnumerateResponse_Entry + for k, t := range s.settings.Defaults.Schema() { + entries = append(entries, &rpc.SettingsEnumerateResponse_Entry{ + Key: k, + Type: t.String(), + }) } - configPath := s.settings.ConfigFileUsed() - updatedSettings.SetConfigFile(configPath) - s.settings = updatedSettings - - return &rpc.SettingsDeleteResponse{}, nil + return &rpc.SettingsEnumerateResponse{ + Entries: entries, + }, nil } diff --git a/commands/service_settings_test.go b/commands/service_settings_test.go index e1d67fb0fad..1c77856a336 100644 --- a/commands/service_settings_test.go +++ b/commands/service_settings_test.go @@ -18,177 +18,219 @@ package commands import ( "context" "encoding/json" - "path/filepath" "testing" - "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" ) +func loadConfig(t *testing.T, srv rpc.ArduinoCoreServiceServer, confPath *paths.Path) { + confPath.ToAbs() + conf, err := confPath.ReadFile() + require.NoError(t, err) + _, err = srv.ConfigurationOpen(context.Background(), &rpc.ConfigurationOpenRequest{ + EncodedSettings: string(conf), + SettingsFormat: "yaml", + }) + require.NoError(t, err) +} + func TestGetAll(t *testing.T) { - settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) - svc := NewArduinoCoreServer("", settings) - resp, err := svc.SettingsGetAll(context.Background(), &rpc.SettingsGetAllRequest{}) + srv := NewArduinoCoreServer() + loadConfig(t, srv, paths.New("testdata", "arduino-cli.yml")) + resp, err := srv.ConfigurationGet(context.Background(), &rpc.ConfigurationGetRequest{}) require.Nil(t, err) - content, err := json.Marshal(settings.AllSettings()) - require.Nil(t, err) + defaultUserDir, err := srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "directories.user"}) + require.NoError(t, err) - require.Equal(t, string(content), resp.GetJsonData()) + content, err := json.Marshal(resp.GetConfiguration()) + require.Nil(t, err) + require.JSONEq(t, `{ + "board_manager": { + "additional_urls": [ "http://foobar.com", "http://example.com" ] + }, + "build_cache": { + "compilations_before_purge": 10, + "ttl_secs": 2592000 + }, + "directories": { + "builtin": {}, + "data": "/home/massi/.arduino15", + "downloads": "/home/massi/.arduino15/staging", + "user": `+defaultUserDir.GetEncodedValue()+` + }, + "library": {}, + "locale": "en", + "logging": { + "format": "text", + "level": "info" + }, + "daemon":{ + "port":"50051" + }, + "network":{ + "proxy":"123" + }, + "output": {}, + "sketch": {}, + "updater": {} + }`, string(content)) } func TestMerge(t *testing.T) { - initialSettings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) - svc := NewArduinoCoreServer("", initialSettings).(*arduinoCoreServerImpl) + srv := NewArduinoCoreServer() + loadConfig(t, srv, paths.New("testdata", "arduino-cli.yml")) + ctx := context.Background() + get := func(key string) string { + resp, err := srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: key}) + if err != nil { + return "" + } + return resp.GetEncodedValue() + } + // Verify defaults - require.Equal(t, "50051", svc.settings.GetString("daemon.port")) - require.Equal(t, "", svc.settings.GetString("foo")) - require.Equal(t, false, svc.settings.GetBool("sketch.always_export_binaries")) + require.Equal(t, `"50051"`, get("daemon.port")) + require.Equal(t, "", get("foo")) + require.Equal(t, "false", get("sketch.always_export_binaries")) bulkSettings := `{"foo": "bar", "daemon":{"port":"420"}, "sketch": {"always_export_binaries": "true"}}` - res, err := svc.SettingsMerge(ctx, &rpc.SettingsMergeRequest{JsonData: bulkSettings}) - require.NotNil(t, res) - require.NoError(t, err) + _, err := srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{EncodedSettings: bulkSettings, SettingsFormat: "json"}) + require.Error(t, err) - require.Equal(t, "420", svc.settings.GetString("daemon.port")) - require.Equal(t, "bar", svc.settings.GetString("foo")) - require.Equal(t, true, svc.settings.GetBool("sketch.always_export_binaries")) + bulkSettings = `{"daemon":{"port":"420"}, "sketch": {"always_export_binaries": "true"}}` + _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{EncodedSettings: bulkSettings, SettingsFormat: "json"}) + require.Error(t, err) - bulkSettings = `{"foo":"", "daemon": {}, "sketch": {"always_export_binaries": "false"}}` - res, err = svc.SettingsMerge(ctx, &rpc.SettingsMergeRequest{JsonData: bulkSettings}) - require.NotNil(t, res) + bulkSettings = `{"daemon":{"port":"420"}, "sketch": {"always_export_binaries": true}}` + _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{EncodedSettings: bulkSettings, SettingsFormat: "json"}) require.NoError(t, err) - require.Equal(t, "50051", svc.settings.GetString("daemon.port")) - require.Equal(t, "", svc.settings.GetString("foo")) - require.Equal(t, false, svc.settings.GetBool("sketch.always_export_binaries")) + require.Equal(t, `"420"`, get("daemon.port")) + require.Equal(t, ``, get("foo")) + require.Equal(t, "true", get("sketch.always_export_binaries")) - bulkSettings = `{"daemon": {"port":""}}` - res, err = svc.SettingsMerge(ctx, &rpc.SettingsMergeRequest{JsonData: bulkSettings}) - require.NotNil(t, res) + bulkSettings = `{"daemon": {}, "sketch": {"always_export_binaries": false}}` + _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{EncodedSettings: bulkSettings, SettingsFormat: "json"}) require.NoError(t, err) - require.Equal(t, "", svc.settings.GetString("daemon.port")) - // Verifies other values are not changed - require.Equal(t, "", svc.settings.GetString("foo")) - require.Equal(t, false, svc.settings.GetBool("sketch.always_export_binaries")) + require.Equal(t, `"50051"`, get("daemon.port")) + require.Equal(t, "", get("foo")) + require.Equal(t, "false", get("sketch.always_export_binaries")) - bulkSettings = `{"network": {}}` - res, err = svc.SettingsMerge(ctx, &rpc.SettingsMergeRequest{JsonData: bulkSettings}) - require.NotNil(t, res) + _, err = srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: "daemon.port", EncodedValue: ""}) require.NoError(t, err) - require.Equal(t, "", svc.settings.GetString("proxy")) + require.Equal(t, `"50051"`, get("daemon.port")) + // Verifies other values are not changed + require.Equal(t, "", get("foo")) + require.Equal(t, "false", get("sketch.always_export_binaries")) + } func TestGetValue(t *testing.T) { - settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) - svc := NewArduinoCoreServer("", settings) + srv := NewArduinoCoreServer() + loadConfig(t, srv, paths.New("testdata", "arduino-cli.yml")) key := &rpc.SettingsGetValueRequest{Key: "daemon"} - resp, err := svc.SettingsGetValue(context.Background(), key) + resp, err := srv.SettingsGetValue(context.Background(), key) require.NoError(t, err) - require.Equal(t, `{"port":"50051"}`, resp.GetJsonData()) + require.Equal(t, `{"port":"50051"}`, resp.GetEncodedValue()) key = &rpc.SettingsGetValueRequest{Key: "daemon.port"} - resp, err = svc.SettingsGetValue(context.Background(), key) + resp, err = srv.SettingsGetValue(context.Background(), key) require.NoError(t, err) - require.Equal(t, `"50051"`, resp.GetJsonData()) + require.Equal(t, `"50051"`, resp.GetEncodedValue()) } -func TestGetMergedValue(t *testing.T) { - settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) - svc := NewArduinoCoreServer("", settings) +func TestGetOfSettedValue(t *testing.T) { + srv := NewArduinoCoreServer() + loadConfig(t, srv, paths.New("testdata", "arduino-cli.yml")) - // Verifies value is not set - key := &rpc.SettingsGetValueRequest{Key: "foo"} - res, err := svc.SettingsGetValue(context.Background(), key) + // Verifies value is not set (try with a key without a default, like "directories.builtin.libraries") + ctx := context.Background() + res, err := srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: "directories.builtin.libraries"}) require.Nil(t, res) require.Error(t, err, "Error getting settings value") - // Merge value - bulkSettings := `{"foo": "bar"}` - _, err = svc.SettingsMerge(context.Background(), &rpc.SettingsMergeRequest{JsonData: bulkSettings}) + // Set value + _, err = srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{ + Key: "directories.builtin.libraries", + EncodedValue: `"bar"`}) require.NoError(t, err) // Verifies value is correctly returned - key = &rpc.SettingsGetValueRequest{Key: "foo"} - res, err = svc.SettingsGetValue(context.Background(), key) + res, err = srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: "directories.builtin.libraries"}) require.NoError(t, err) - require.Equal(t, `"bar"`, res.GetJsonData()) + require.Equal(t, `"bar"`, res.GetEncodedValue()) } func TestGetValueNotFound(t *testing.T) { - settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) - svc := NewArduinoCoreServer("", settings) + srv := NewArduinoCoreServer() + loadConfig(t, srv, paths.New("testdata", "arduino-cli.yml")) key := &rpc.SettingsGetValueRequest{Key: "DOESNTEXIST"} - _, err := svc.SettingsGetValue(context.Background(), key) + _, err := srv.SettingsGetValue(context.Background(), key) require.Error(t, err) } -func TestSetValue(t *testing.T) { - settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) - svc := NewArduinoCoreServer("", settings) - - val := &rpc.SettingsSetValueRequest{ - Key: "foo", - JsonData: `"bar"`, - } - _, err := svc.SettingsSetValue(context.Background(), val) - require.Nil(t, err) - require.Equal(t, "bar", settings.GetString("foo")) -} - func TestWrite(t *testing.T) { - settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) - svc := NewArduinoCoreServer("", settings) + srv := NewArduinoCoreServer() + loadConfig(t, srv, paths.New("testdata", "arduino-cli.yml")) // Writes some settings val := &rpc.SettingsSetValueRequest{ - Key: "foo", - JsonData: `"bar"`, + Key: "directories.builtin.libraries", + EncodedValue: `"bar"`, } - _, err := svc.SettingsSetValue(context.Background(), val) + _, err := srv.SettingsSetValue(context.Background(), val) require.NoError(t, err) - tempDir := paths.TempDir() - testFolder, err := tempDir.MkTempDir("testdata") - require.NoError(t, err) - defer testFolder.RemoveAll() - - // Verifies config files doesn't exist - configFile := testFolder.Join("arduino-cli.yml") - require.True(t, configFile.NotExist()) - - _, err = svc.SettingsWrite(context.Background(), &rpc.SettingsWriteRequest{ - FilePath: configFile.String(), + resp, err := srv.ConfigurationSave(context.Background(), &rpc.ConfigurationSaveRequest{ + SettingsFormat: "yaml", }) require.NoError(t, err) - // Verifies config file is created. - // We don't verify the content since we expect config library, Viper, to work - require.True(t, configFile.Exist()) + // Verify encoded content + require.YAMLEq(t, ` +board_manager: + additional_urls: + - http://foobar.com + - http://example.com + +daemon: + port: "50051" + +directories: + data: /home/massi/.arduino15 + downloads: /home/massi/.arduino15/staging + builtin: + libraries: bar + +logging: + file: "" + format: text + level: info + +network: + proxy: "123" +`, resp.GetEncodedSettings()) } func TestDelete(t *testing.T) { - settings := configuration.Init(filepath.Join("testdata", "arduino-cli.yaml")) - svc := NewArduinoCoreServer("", settings) + srv := NewArduinoCoreServer() + loadConfig(t, srv, paths.New("testdata", "arduino-cli.yml")) - _, err := svc.SettingsDelete(context.Background(), &rpc.SettingsDeleteRequest{ - Key: "doesnotexist", - }) - require.Error(t, err) + _, err := srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network"}) + require.NoError(t, err) - _, err = svc.SettingsDelete(context.Background(), &rpc.SettingsDeleteRequest{ - Key: "network", - }) + _, err = srv.SettingsSetValue(context.Background(), &rpc.SettingsSetValueRequest{Key: "network", EncodedValue: ""}) require.NoError(t, err) - _, err = svc.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network"}) + _, err = srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network"}) require.Error(t, err) } diff --git a/commands/service_sketch_load_test.go b/commands/service_sketch_load_test.go index 822dfea7c5d..d7dfcdcf8fa 100644 --- a/commands/service_sketch_load_test.go +++ b/commands/service_sketch_load_test.go @@ -19,13 +19,12 @@ import ( "context" "testing" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/stretchr/testify/require" ) func TestLoadSketchProfiles(t *testing.T) { - srv := NewArduinoCoreServer("", configuration.Init("")) + srv := NewArduinoCoreServer() loadResp, err := srv.LoadSketch(context.Background(), &commands.LoadSketchRequest{ SketchPath: "./testdata/sketch_with_profile", }) diff --git a/commands/service_sketch_new_test.go b/commands/service_sketch_new_test.go index 353dec17a05..8dfb5a8168e 100644 --- a/commands/service_sketch_new_test.go +++ b/commands/service_sketch_new_test.go @@ -20,7 +20,6 @@ import ( "fmt" "testing" - "github.com/arduino/arduino-cli/internal/cli/configuration" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/stretchr/testify/require" ) @@ -36,7 +35,7 @@ func Test_SketchNameWrongPattern(t *testing.T) { ",`hack[}attempt{];", } - srv := NewArduinoCoreServer("", configuration.Init("")) + srv := NewArduinoCoreServer() for _, name := range invalidNames { _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, @@ -49,7 +48,7 @@ func Test_SketchNameWrongPattern(t *testing.T) { } func Test_SketchNameEmpty(t *testing.T) { - srv := NewArduinoCoreServer("", configuration.Init("")) + srv := NewArduinoCoreServer() _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: "", SketchDir: t.TempDir(), @@ -63,7 +62,7 @@ func Test_SketchNameTooLong(t *testing.T) { for i := range tooLongName { tooLongName[i] = 'a' } - srv := NewArduinoCoreServer("", configuration.Init("")) + srv := NewArduinoCoreServer() _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: string(tooLongName), SketchDir: t.TempDir(), @@ -87,7 +86,7 @@ func Test_SketchNameOk(t *testing.T) { "_hello_world", string(lengthLimitName), } - srv := NewArduinoCoreServer("", configuration.Init("")) + srv := NewArduinoCoreServer() for _, name := range validNames { _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, @@ -100,7 +99,7 @@ func Test_SketchNameOk(t *testing.T) { func Test_SketchNameReserved(t *testing.T) { invalidNames := []string{"CON", "PRN", "AUX", "NUL", "COM0", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT0", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"} - srv := NewArduinoCoreServer("", configuration.Init("")) + srv := NewArduinoCoreServer() for _, name := range invalidNames { _, err := srv.NewSketch(context.Background(), &rpc.NewSketchRequest{ SketchName: name, diff --git a/commands/service_upload_test.go b/commands/service_upload_test.go index e8d70e19c4d..7d55f95b48b 100644 --- a/commands/service_upload_test.go +++ b/commands/service_upload_test.go @@ -128,7 +128,7 @@ func TestDetermineBuildPathAndSketchName(t *testing.T) { } func TestUploadPropertiesComposition(t *testing.T) { - pmb := packagemanager.NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) + pmb := packagemanager.NewBuilder(nil, nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) errs := pmb.LoadHardwareFromDirectory(paths.New("testdata", "upload", "hardware")) require.Len(t, errs, 0) buildPath1 := paths.New("testdata", "upload", "build_path_1") diff --git a/internal/arduino/cores/packagemanager/loader.go b/internal/arduino/cores/packagemanager/loader.go index 29e8fb511a4..8b42697a6e4 100644 --- a/internal/arduino/cores/packagemanager/loader.go +++ b/internal/arduino/cores/packagemanager/loader.go @@ -24,15 +24,20 @@ import ( "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/internal/arduino/cores" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/go-paths-helper" properties "github.com/arduino/go-properties-orderedmap" semver "go.bug.st/relaxed-semver" ) // LoadHardware read all plaforms from the configured paths -func (pm *Builder) LoadHardware(settings *configuration.Settings) []error { - hardwareDirs := configuration.HardwareDirectories(settings) +func (pm *Builder) LoadHardware() []error { + hardwareDirs := paths.NewPathList() + if pm.PackagesDir.IsDir() { + hardwareDirs.Add(pm.PackagesDir) + } + if pm.userPackagesDir != nil && pm.userPackagesDir.IsDir() { + hardwareDirs.Add(pm.userPackagesDir) + } return pm.LoadHardwareFromDirectories(hardwareDirs) } diff --git a/internal/arduino/cores/packagemanager/loader_test.go b/internal/arduino/cores/packagemanager/loader_test.go index a9ee015c86d..5d394280aa8 100644 --- a/internal/arduino/cores/packagemanager/loader_test.go +++ b/internal/arduino/cores/packagemanager/loader_test.go @@ -175,7 +175,7 @@ func TestLoadDiscoveries(t *testing.T) { defer fakePath.RemoveAll() createTestPackageManager := func() *PackageManager { - pmb := NewBuilder(fakePath, fakePath, fakePath, fakePath, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(fakePath, fakePath, nil, fakePath, fakePath, "test", downloader.GetDefaultConfig()) pack := pmb.packages.GetOrCreatePackage("arduino") // ble-discovery tool tool := pack.GetOrCreateTool("ble-discovery") diff --git a/internal/arduino/cores/packagemanager/package_manager.go b/internal/arduino/cores/packagemanager/package_manager.go index d9a5f79a2ac..ffe278a6205 100644 --- a/internal/arduino/cores/packagemanager/package_manager.go +++ b/internal/arduino/cores/packagemanager/package_manager.go @@ -55,6 +55,7 @@ type PackageManager struct { log logrus.FieldLogger IndexDir *paths.Path PackagesDir *paths.Path + userPackagesDir *paths.Path DownloadDir *paths.Path tempDir *paths.Path profile *sketch.Profile @@ -76,12 +77,13 @@ type Explorer PackageManager var tr = i18n.Tr // NewBuilder returns a new Builder -func NewBuilder(indexDir, packagesDir, downloadDir, tempDir *paths.Path, userAgent string, downloaderConfig downloader.Config) *Builder { +func NewBuilder(indexDir, packagesDir, userPackagesDir, downloadDir, tempDir *paths.Path, userAgent string, downloaderConfig downloader.Config) *Builder { return &Builder{ log: logrus.StandardLogger(), packages: cores.NewPackages(), IndexDir: indexDir, PackagesDir: packagesDir, + userPackagesDir: userPackagesDir, DownloadDir: downloadDir, tempDir: tempDir, packagesCustomGlobalProperties: properties.NewMap(), @@ -100,6 +102,7 @@ func (pmb *Builder) BuildIntoExistingPackageManager(target *PackageManager) { target.packages = pmb.packages target.IndexDir = pmb.IndexDir target.PackagesDir = pmb.PackagesDir + target.userPackagesDir = pmb.userPackagesDir target.DownloadDir = pmb.DownloadDir target.tempDir = pmb.tempDir target.packagesCustomGlobalProperties = pmb.packagesCustomGlobalProperties @@ -116,6 +119,7 @@ func (pmb *Builder) Build() *PackageManager { packages: pmb.packages, IndexDir: pmb.IndexDir, PackagesDir: pmb.PackagesDir, + userPackagesDir: pmb.userPackagesDir, DownloadDir: pmb.DownloadDir, tempDir: pmb.tempDir, packagesCustomGlobalProperties: pmb.packagesCustomGlobalProperties, @@ -166,7 +170,7 @@ func (pmb *Builder) calculateCompatibleReleases() { // this function will make the builder write the new configuration into this // PackageManager. func (pm *PackageManager) NewBuilder() (builder *Builder, commit func()) { - pmb := NewBuilder(pm.IndexDir, pm.PackagesDir, pm.DownloadDir, pm.tempDir, pm.userAgent, pm.downloaderConfig) + pmb := NewBuilder(pm.IndexDir, pm.PackagesDir, pm.userPackagesDir, pm.DownloadDir, pm.tempDir, pm.userAgent, pm.downloaderConfig) return pmb, func() { pmb.calculateCompatibleReleases() pmb.BuildIntoExistingPackageManager(pm) diff --git a/internal/arduino/cores/packagemanager/package_manager_test.go b/internal/arduino/cores/packagemanager/package_manager_test.go index fb215816d0c..595d08d0c21 100644 --- a/internal/arduino/cores/packagemanager/package_manager_test.go +++ b/internal/arduino/cores/packagemanager/package_manager_test.go @@ -24,7 +24,6 @@ import ( "testing" "github.com/arduino/arduino-cli/internal/arduino/cores" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/go-paths-helper" "github.com/arduino/go-properties-orderedmap" "github.com/stretchr/testify/require" @@ -39,7 +38,7 @@ var dataDir1 = paths.New("testdata", "data_dir_1") var extraHardware = paths.New("testdata", "extra_hardware") func TestFindBoardWithFQBN(t *testing.T) { - pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(customHardware, customHardware, nil, customHardware, customHardware, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pm := pmb.Build() pme, release := pm.NewExplorer() @@ -57,7 +56,7 @@ func TestFindBoardWithFQBN(t *testing.T) { func TestResolveFQBN(t *testing.T) { // Pass nil, since these paths are only used for installing - pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(nil, nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) // Hardware from main packages directory pmb.LoadHardwareFromDirectory(dataDir1.Join("packages")) // This contains the arduino:avr core @@ -342,7 +341,7 @@ func TestResolveFQBN(t *testing.T) { } func TestBoardOptionsFunctions(t *testing.T) { - pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(customHardware, customHardware, nil, customHardware, customHardware, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pm := pmb.Build() pme, release := pm.NewExplorer() @@ -382,7 +381,7 @@ func TestBoardOptionsFunctions(t *testing.T) { } func TestBoardOrdering(t *testing.T) { - pmb := NewBuilder(dataDir1, dataDir1.Join("packages"), nil, nil, "", downloader.GetDefaultConfig()) + pmb := NewBuilder(dataDir1, dataDir1.Join("packages"), nil, nil, nil, "", downloader.GetDefaultConfig()) _ = pmb.LoadHardwareFromDirectories(paths.NewPathList(dataDir1.Join("packages").String())) pm := pmb.Build() pme, release := pm.NewExplorer() @@ -433,11 +432,11 @@ func TestBoardOrdering(t *testing.T) { func TestFindToolsRequiredForBoard(t *testing.T) { t.Setenv("ARDUINO_DATA_DIR", dataDir1.String()) - settings := configuration.Init("") pmb := NewBuilder( dataDir1, - configuration.PackagesDir(settings), - configuration.DownloadsDir(settings), + dataDir1.Join("packages"), + nil, + dataDir1.Join("staging"), dataDir1, "test", downloader.GetDefaultConfig(), @@ -456,7 +455,7 @@ func TestFindToolsRequiredForBoard(t *testing.T) { // We ignore the errors returned since they might not be necessarily blocking // but just warnings for the user, like in the case a board is not loaded // because of malformed menus - pmb.LoadHardware(settings) + pmb.LoadHardware() pm := pmb.Build() pme, release := pm.NewExplorer() defer release() @@ -569,7 +568,7 @@ func TestFindToolsRequiredForBoard(t *testing.T) { } func TestIdentifyBoard(t *testing.T) { - pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(customHardware, customHardware, nil, customHardware, customHardware, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pm := pmb.Build() pme, release := pm.NewExplorer() @@ -596,12 +595,12 @@ func TestIdentifyBoard(t *testing.T) { func TestPackageManagerClear(t *testing.T) { // Create a PackageManager and load the harware - pmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(customHardware, customHardware, nil, customHardware, customHardware, "test", downloader.GetDefaultConfig()) pmb.LoadHardwareFromDirectory(customHardware) pm := pmb.Build() // Creates another PackageManager but don't load the hardware - emptyPmb := NewBuilder(customHardware, customHardware, customHardware, customHardware, "test", downloader.GetDefaultConfig()) + emptyPmb := NewBuilder(customHardware, customHardware, nil, customHardware, customHardware, "test", downloader.GetDefaultConfig()) emptyPm := emptyPmb.Build() // Verifies they're not equal @@ -623,7 +622,7 @@ func TestFindToolsRequiredFromPlatformRelease(t *testing.T) { require.NoError(t, err) defer fakePath.RemoveAll() - pmb := NewBuilder(fakePath, fakePath, fakePath, fakePath, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(fakePath, fakePath, nil, fakePath, fakePath, "test", downloader.GetDefaultConfig()) pack := pmb.GetOrCreatePackage("arduino") { @@ -744,7 +743,7 @@ func TestFindToolsRequiredFromPlatformRelease(t *testing.T) { } func TestFindPlatformReleaseDependencies(t *testing.T) { - pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(nil, nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) pmb.LoadPackageIndexFromFile(paths.New("testdata", "package_tooltest_index.json")) pmb.calculateCompatibleReleases() pm := pmb.Build() @@ -760,7 +759,7 @@ func TestFindPlatformReleaseDependencies(t *testing.T) { func TestLegacyPackageConversionToPluggableDiscovery(t *testing.T) { // Pass nil, since these paths are only used for installing - pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(nil, nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) // Hardware from main packages directory pmb.LoadHardwareFromDirectory(dataDir1.Join("packages")) pm := pmb.Build() @@ -830,7 +829,7 @@ func TestLegacyPackageConversionToPluggableDiscovery(t *testing.T) { func TestVariantAndCoreSelection(t *testing.T) { // Pass nil, since these paths are only used for installing - pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(nil, nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) // Hardware from main packages directory pmb.LoadHardwareFromDirectory(dataDir1.Join("packages")) pm := pmb.Build() @@ -925,7 +924,7 @@ func TestVariantAndCoreSelection(t *testing.T) { } func TestRunScript(t *testing.T) { - pmb := NewBuilder(nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) + pmb := NewBuilder(nil, nil, nil, nil, nil, "test", downloader.GetDefaultConfig()) pm := pmb.Build() pme, release := pm.NewExplorer() defer release() diff --git a/internal/arduino/cores/packagemanager/profiles.go b/internal/arduino/cores/packagemanager/profiles.go index 6cd6f3578d2..598d1cdc959 100644 --- a/internal/arduino/cores/packagemanager/profiles.go +++ b/internal/arduino/cores/packagemanager/profiles.go @@ -74,7 +74,7 @@ func (pmb *Builder) loadProfilePlatform(platformRef *sketch.ProfilePlatformRefer release := platform.GetOrCreateRelease(platformRef.Version) uid := platformRef.InternalUniqueIdentifier() - destDir := configuration.ProfilesCacheDir(settings).Join(uid) + destDir := settings.ProfilesCacheDir().Join(uid) if !destDir.IsDir() && installMissing { // Try installing the missing platform if err := pmb.installMissingProfilePlatform(platformRef, destDir, downloadCB, taskCB); err != nil { @@ -91,7 +91,7 @@ func (pmb *Builder) installMissingProfilePlatform(platformRef *sketch.ProfilePla if err != nil { return fmt.Errorf("installing missing platform: could not create temp dir %s", err) } - tmpPmb := NewBuilder(tmp, tmp, pmb.DownloadDir, tmp, pmb.userAgent, pmb.downloaderConfig) + tmpPmb := NewBuilder(tmp, tmp, nil, pmb.DownloadDir, tmp, pmb.userAgent, pmb.downloaderConfig) defer tmp.RemoveAll() // Download the main index and parse it @@ -142,7 +142,7 @@ func (pmb *Builder) loadProfileTool(toolRef *cores.ToolDependency, indexURL *url tool := targetPackage.GetOrCreateTool(toolRef.ToolName) uid := toolRef.InternalUniqueIdentifier(indexURL) - destDir := configuration.ProfilesCacheDir(settings).Join(uid) + destDir := settings.ProfilesCacheDir().Join(uid) if !destDir.IsDir() && installMissing { // Try installing the missing tool diff --git a/internal/arduino/resources/helpers_test.go b/internal/arduino/resources/helpers_test.go index 72c595f6c89..75961bec26f 100644 --- a/internal/arduino/resources/helpers_test.go +++ b/internal/arduino/resources/helpers_test.go @@ -52,7 +52,7 @@ func TestDownloadApplyUserAgentHeaderUsingConfig(t *testing.T) { URL: srv.URL, } - settings := configuration.Init("") + settings := configuration.NewSettings() settings.Set("network.user_agent_ext", goldUserAgentValue) config, err := settings.DownloaderConfig() require.NoError(t, err) diff --git a/internal/cli/arguments/reference_test.go b/internal/cli/arguments/reference_test.go index f91109f8de6..e55051cc768 100644 --- a/internal/cli/arguments/reference_test.go +++ b/internal/cli/arguments/reference_test.go @@ -21,7 +21,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -55,7 +54,7 @@ func TestArgsStringify(t *testing.T) { } func TestParseReferenceCores(t *testing.T) { - srv := commands.NewArduinoCoreServer("", configuration.Init("")) + srv := commands.NewArduinoCoreServer() ctx := context.Background() for _, tt := range goodCores { actual, err := arguments.ParseReference(ctx, srv, tt.in) @@ -76,7 +75,7 @@ func TestParseArgs(t *testing.T) { input = append(input, tt.in) } - srv := commands.NewArduinoCoreServer("", configuration.Init("")) + srv := commands.NewArduinoCoreServer() refs, err := arguments.ParseReferences(context.Background(), srv, input) assert.Nil(t, err) assert.Equal(t, len(goodCores), len(refs)) diff --git a/internal/cli/cache/clean.go b/internal/cli/cache/clean.go index 4859676ae1c..a55b9c8309b 100644 --- a/internal/cli/cache/clean.go +++ b/internal/cli/cache/clean.go @@ -29,7 +29,7 @@ func initCleanCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cleanCommand := &cobra.Command{ Use: "clean", Short: tr("Delete Boards/Library Manager download cache."), - Long: tr("Delete contents of the `directories.downloads` folder, where archive files are staged during installation of libraries and boards platforms."), + Long: tr("Delete contents of the downloads cache folder, where archive files are staged during installation of libraries and boards platforms."), Example: " " + os.Args[0] + " cache clean", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { diff --git a/internal/cli/cli.go b/internal/cli/cli.go index ef6c54e806e..5467e617fc7 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -17,6 +17,7 @@ package cli import ( "context" + "encoding/json" "fmt" "io" "os" @@ -28,7 +29,6 @@ import ( "github.com/arduino/arduino-cli/internal/cli/compile" "github.com/arduino/arduino-cli/internal/cli/completion" "github.com/arduino/arduino-cli/internal/cli/config" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/core" "github.com/arduino/arduino-cli/internal/cli/daemon" "github.com/arduino/arduino-cli/internal/cli/debug" @@ -55,31 +55,73 @@ import ( semver "go.bug.st/relaxed-semver" ) -var ( - verbose bool - jsonOutput bool - outputFormat string - configFile string -) - // NewCommand creates a new ArduinoCli command root -func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cobra.AddTemplateFunc("tr", i18n.Tr) var updaterMessageChan chan *semver.Version - // ArduinoCli is the root command + var ( + verbose bool + noColor bool + logLevel string + logFile string + logFormat string + jsonOutput bool + outputFormat string + configFile string + additionalUrls []string + ) + + resp, err := srv.ConfigurationGet(context.Background(), &rpc.ConfigurationGetRequest{}) + if err != nil { + panic("Error creating configuration: " + err.Error()) + } + settings := resp.GetConfiguration() + + defaultLogFile := settings.GetLogging().GetFile() + defaultLogFormat := settings.GetLogging().GetFormat() + defaultAdditionalURLs := settings.GetBoardManager().GetAdditionalUrls() + defaultOutputNoColor := settings.GetOutput().GetNoColor() + cmd := &cobra.Command{ Use: "arduino-cli", Short: tr("Arduino CLI."), Long: tr("Arduino Command Line Interface (arduino-cli)."), Example: fmt.Sprintf(" %s <%s> [%s...]", os.Args[0], tr("command"), tr("flags")), PersistentPreRun: func(cmd *cobra.Command, args []string) { + ctx := cmd.Context() + + // Override server settings with the flags from the command line + set := func(key string, value any) { + if valueJson, err := json.Marshal(value); err != nil { + feedback.Fatal(tr("Error setting value %s: %v", key, err), feedback.ErrGeneric) + } else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: string(valueJson)}); err != nil { + feedback.Fatal(tr("Error setting value %s: %v", key, err), feedback.ErrGeneric) + } + } + set("logging.level", logLevel) + set("logging.file", logFile) + set("board_manager.additional_urls", additionalUrls) + set("output.no_color", noColor) + if jsonOutput { outputFormat = "json" } + if outputFormat != "text" { + cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { + feedback.Fatal(tr("Should show help message, but it is available only in TEXT mode."), feedback.ErrBadArgument) + }) + } - preRun(cmd, defaultSettings) + preRun(verbose, outputFormat, logLevel, logFile, logFormat, noColor, settings) + + // Log the configuration file used + if configFile := ctx.Value("config_file").(string); configFile != "" { + logrus.Infof("Using config file: %s", configFile) + } else { + logrus.Info("Config file not found, using default values") + } if cmd.Name() != "version" { updaterMessageChan = make(chan *semver.Version) @@ -115,13 +157,13 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration cmd.AddCommand(board.NewCommand(srv)) cmd.AddCommand(cache.NewCommand(srv)) - cmd.AddCommand(compile.NewCommand(srv, defaultSettings)) + cmd.AddCommand(compile.NewCommand(srv, settings)) cmd.AddCommand(completion.NewCommand()) - cmd.AddCommand(config.NewCommand(srv, defaultSettings)) + cmd.AddCommand(config.NewCommand(srv, settings)) cmd.AddCommand(core.NewCommand(srv)) - cmd.AddCommand(daemon.NewCommand(srv, defaultSettings)) + cmd.AddCommand(daemon.NewCommand(srv, settings)) cmd.AddCommand(generatedocs.NewCommand()) - cmd.AddCommand(lib.NewCommand(srv, defaultSettings)) + cmd.AddCommand(lib.NewCommand(srv, settings)) cmd.AddCommand(monitor.NewCommand(srv)) cmd.AddCommand(outdated.NewCommand(srv)) cmd.AddCommand(sketch.NewCommand(srv)) @@ -132,31 +174,26 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration cmd.AddCommand(burnbootloader.NewCommand(srv)) cmd.AddCommand(version.NewCommand(srv)) cmd.AddCommand(feedback.NewCommand()) + cmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, tr("Print the logs on the standard output.")) cmd.Flag("verbose").Hidden = true cmd.PersistentFlags().BoolVar(&verbose, "log", false, tr("Print the logs on the standard output.")) + defaultLogLevel := settings.GetLogging().GetLevel() validLogLevels := []string{"trace", "debug", "info", "warn", "error", "fatal", "panic"} - cmd.PersistentFlags().String("log-level", "", tr("Messages with this level and above will be logged. Valid levels are: %s", strings.Join(validLogLevels, ", "))) - cmd.RegisterFlagCompletionFunc("log-level", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return validLogLevels, cobra.ShellCompDirectiveDefault - }) - cmd.PersistentFlags().String("log-file", "", tr("Path to the file where logs will be written.")) + cmd.PersistentFlags().StringVar(&logLevel, "log-level", defaultLogLevel, tr("Messages with this level and above will be logged. Valid levels are: %s", strings.Join(validLogLevels, ", "))) + cmd.RegisterFlagCompletionFunc("log-level", cobra.FixedCompletions(validLogLevels, cobra.ShellCompDirectiveDefault)) + cmd.PersistentFlags().StringVar(&logFile, "log-file", defaultLogFile, tr("Path to the file where logs will be written.")) validLogFormats := []string{"text", "json"} - cmd.PersistentFlags().String("log-format", "", tr("The output format for the logs, can be: %s", strings.Join(validLogFormats, ", "))) - cmd.RegisterFlagCompletionFunc("log-format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return validLogFormats, cobra.ShellCompDirectiveDefault - }) + cmd.PersistentFlags().StringVar(&logFormat, "log-format", defaultLogFormat, tr("The output format for the logs, can be: %s", strings.Join(validLogFormats, ", "))) + cmd.RegisterFlagCompletionFunc("log-format", cobra.FixedCompletions(validLogFormats, cobra.ShellCompDirectiveDefault)) validOutputFormats := []string{"text", "json", "jsonmini"} cmd.PersistentFlags().StringVar(&outputFormat, "format", "text", tr("The command output format, can be: %s", strings.Join(validOutputFormats, ", "))) - cmd.RegisterFlagCompletionFunc("format", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return validOutputFormats, cobra.ShellCompDirectiveDefault - }) + cmd.RegisterFlagCompletionFunc("format", cobra.FixedCompletions(validOutputFormats, cobra.ShellCompDirectiveDefault)) cmd.Flag("format").Hidden = true cmd.PersistentFlags().BoolVar(&jsonOutput, "json", false, tr("Print the output in JSON format.")) cmd.PersistentFlags().StringVar(&configFile, "config-file", "", tr("The custom config file (if not specified the default will be used).")) - cmd.PersistentFlags().StringSlice("additional-urls", []string{}, tr("Comma-separated list of additional URLs for the Boards Manager.")) - cmd.PersistentFlags().Bool("no-color", false, "Disable colored output.") - configuration.BindFlags(cmd, defaultSettings) + cmd.PersistentFlags().StringSliceVar(&additionalUrls, "additional-urls", defaultAdditionalURLs, tr("Comma-separated list of additional URLs for the Boards Manager.")) + cmd.PersistentFlags().BoolVar(&noColor, "no-color", defaultOutputNoColor, "Disable colored output.") return cmd } @@ -177,17 +214,15 @@ func toLogLevel(s string) (t logrus.Level, found bool) { return } -func preRun(cmd *cobra.Command, defaultSettings *configuration.Settings) { - configFile := defaultSettings.ConfigFileUsed() - +func preRun(verbose bool, outputFormat string, logLevel, logFile, logFormat string, noColor bool, settings *rpc.Configuration) { // initialize inventory - err := inventory.Init(configuration.DataDir(defaultSettings).String()) + err := inventory.Init(settings.GetDirectories().GetData()) if err != nil { feedback.Fatal(fmt.Sprintf("Error: %v", err), feedback.ErrInitializingInventory) } // https://no-color.org/ - color.NoColor = defaultSettings.GetBool("output.no_color") || os.Getenv("NO_COLOR") != "" + color.NoColor = noColor || os.Getenv("NO_COLOR") != "" // Set default feedback output to colorable feedback.SetOut(colorable.NewColorableStdout()) @@ -210,13 +245,12 @@ func preRun(cmd *cobra.Command, defaultSettings *configuration.Settings) { } // set the Logger format - logFormat := strings.ToLower(defaultSettings.GetString("logging.format")) + logFormat = strings.ToLower(logFormat) if logFormat == "json" { logrus.SetFormatter(&logrus.JSONFormatter{}) } // should we log to file? - logFile := defaultSettings.GetString("logging.file") if logFile != "" { file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { @@ -232,41 +266,26 @@ func preRun(cmd *cobra.Command, defaultSettings *configuration.Settings) { } // configure logging filter - if lvl, found := toLogLevel(defaultSettings.GetString("logging.level")); !found { - feedback.Fatal(tr("Invalid option for --log-level: %s", defaultSettings.GetString("logging.level")), feedback.ErrBadArgument) + if logrusLevel, found := toLogLevel(logLevel); !found { + feedback.Fatal(tr("Invalid logging level: %s", logLevel), feedback.ErrBadArgument) } else { - logrus.SetLevel(lvl) + logrus.SetLevel(logrusLevel) } // // Prepare the Feedback system // - // check the right output format was passed - format, found := feedback.ParseOutputFormat(outputFormat) - if !found { + // use the output format to configure the Feedback + format, ok := feedback.ParseOutputFormat(outputFormat) + if !ok { feedback.Fatal(tr("Invalid output format: %s", outputFormat), feedback.ErrBadArgument) } - - // use the output format to configure the Feedback feedback.SetFormat(format) // // Print some status info and check command is consistent // - if configFile != "" { - logrus.Infof("Using config file: %s", configFile) - } else { - logrus.Info("Config file not found, using default values") - } - logrus.Info(versioninfo.VersionInfo.Application + " version " + versioninfo.VersionInfo.VersionString) - - if outputFormat != "text" { - cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { - logrus.Warn("Calling help on JSON format") - feedback.Fatal(tr("Invalid Call : should show Help, but it is available only in TEXT mode."), feedback.ErrBadArgument) - }) - } } diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 290b5a4c649..4b4ad4164bd 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -27,7 +27,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/commands/cmderrors" "github.com/arduino/arduino-cli/internal/cli/arguments" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/feedback/result" "github.com/arduino/arduino-cli/internal/cli/feedback/table" @@ -58,7 +57,7 @@ var ( uploadAfterCompile bool // Upload the binary after the compilation. portArgs arguments.Port // Upload port, e.g.: COM10 or /dev/ttyACM0. verify bool // Upload, verify uploaded binary after the upload. - exportBinaries bool // + exportBinaries bool // If set built binaries will be exported to the sketch folder exportDir string // The compiled binary is written to this file optimizeForDebug bool // Optimize compile output for debug, not for release programmer arguments.Programmer // Use the specified programmer to upload @@ -77,7 +76,7 @@ var ( ) // NewCommand created a new `compile` command -func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) *cobra.Command { compileCommand := &cobra.Command{ Use: "compile", Short: tr("Compiles Arduino sketches."), @@ -99,7 +98,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration showPropertiesArg.AddToCommand(compileCommand) compileCommand.Flags().BoolVar(&preprocess, "preprocess", false, tr("Print preprocessed code to stdout instead of compiling.")) compileCommand.Flags().StringVar(&buildCachePath, "build-cache-path", "", tr("Builds of 'core.a' are saved into this path to be cached and reused.")) - compileCommand.Flags().StringVarP(&exportDir, "output-dir", "", "", tr("Save build artifacts in this directory.")) + compileCommand.Flags().StringVar(&exportDir, "output-dir", "", tr("Save build artifacts in this directory.")) compileCommand.Flags().StringVar(&buildPath, "build-path", "", tr("Path where to save compiled files. If omitted, a directory will be created in the default temporary path of your OS.")) compileCommand.Flags().StringSliceVar(&buildProperties, "build-properties", []string{}, @@ -127,13 +126,13 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration programmer.AddToCommand(compileCommand, srv) compileCommand.Flags().BoolVar(&compilationDatabaseOnly, "only-compilation-database", false, tr("Just produce the compilation database, without actually compiling. All build commands are skipped except pre* hooks.")) compileCommand.Flags().BoolVar(&clean, "clean", false, tr("Optional, cleanup the build folder and do not use any cached build.")) - compileCommand.Flags().BoolVarP(&exportBinaries, "export-binaries", "e", false, tr("If set built binaries will be exported to the sketch folder.")) + compileCommand.Flags().BoolVarP(&exportBinaries, "export-binaries", "e", settings.GetSketch().GetAlwaysExportBinaries(), + tr("If set built binaries will be exported to the sketch folder.")) compileCommand.Flags().StringVar(&sourceOverrides, "source-override", "", tr("Optional. Path to a .json file that contains a set of replacements of the sketch source code.")) compileCommand.Flag("source-override").Hidden = true compileCommand.Flags().BoolVar(&skipLibrariesDiscovery, "skip-libraries-discovery", false, "Skip libraries discovery. This flag is provided only for use in language server and other, very specific, use cases. Do not use for normal compiles") compileCommand.Flag("skip-libraries-discovery").Hidden = true compileCommand.Flags().Int32VarP(&jobs, "jobs", "j", 0, tr("Max number of parallel compiles. If set to 0 the number of available CPUs cores will be used.")) - defaultSettings.BindPFlag("sketch.always_export_binaries", compileCommand.Flags().Lookup("export-binaries")) compileCommand.Flags().MarkDeprecated("build-properties", tr("please use --build-property instead.")) @@ -233,6 +232,7 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer Warnings: warnings, Verbose: verbose, Quiet: quiet, + ExportBinaries: &exportBinaries, ExportDir: exportDir, Libraries: libraries, OptimizeForDebug: optimizeForDebug, diff --git a/internal/cli/config/add.go b/internal/cli/config/add.go index 5678e52e470..059ecad07c1 100644 --- a/internal/cli/config/add.go +++ b/internal/cli/config/add.go @@ -16,35 +16,18 @@ package config import ( + "context" + "encoding/json" "os" - "reflect" + "slices" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) -func uniquify[T comparable](s []T) []T { - // use a map, which enforces unique keys - inResult := make(map[T]bool) - var result []T - // loop through input slice **in order**, - // to ensure output retains that order - // (except that it removes duplicates) - for i := 0; i < len(s); i++ { - // attempt to use the element as a key - if _, ok := inResult[s[i]]; !ok { - // if key didn't exist in map, - // add to map and append to result - inResult[s[i]] = true - result = append(result, s[i]) - } - } - return result -} - -func initAddCommand(defaultSettings *configuration.Settings) *cobra.Command { +func initAddCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { addCommand := &cobra.Command{ Use: "add", Short: tr("Adds one or more values to a setting."), @@ -54,31 +37,44 @@ func initAddCommand(defaultSettings *configuration.Settings) *cobra.Command { " " + os.Args[0] + " config add board_manager.additional_urls https://example.com/package_example_index.json https://another-url.com/package_another_index.json\n", Args: cobra.MinimumNArgs(2), Run: func(cmd *cobra.Command, args []string) { - runAddCommand(args, defaultSettings) + ctx := cmd.Context() + runAddCommand(ctx, srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetSlicesConfigurationKeys(defaultSettings), cobra.ShellCompDirectiveDefault + ctx := cmd.Context() + return getAllArraySettingsKeys(ctx, srv), cobra.ShellCompDirectiveDefault }, } return addCommand } -func runAddCommand(args []string, defaultSettings *configuration.Settings) { +func runAddCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli config add`") key := args[0] - kind := validateKey(key) - if kind != reflect.Slice { + if !slices.Contains(getAllArraySettingsKeys(ctx, srv), key) { msg := tr("The key '%[1]v' is not a list of items, can't add to it.\nMaybe use '%[2]s'?", key, "config set") feedback.Fatal(msg, feedback.ErrGeneric) } - v := defaultSettings.GetStringSlice(key) - v = append(v, args[1:]...) - v = uniquify(v) - defaultSettings.Set(key, v) + var currentValues []string + if resp, err := srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: key}); err != nil { + feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric) + } else if err := json.Unmarshal([]byte(resp.GetEncodedValue()), ¤tValues); err != nil { + feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric) + } - if err := defaultSettings.WriteConfig(); err != nil { - feedback.Fatal(tr("Can't write config file: %v", err), feedback.ErrGeneric) + for _, arg := range args[1:] { + if !slices.Contains(currentValues, arg) { + currentValues = append(currentValues, arg) + } + } + + if newValuesJSON, err := json.Marshal(currentValues); err != nil { + feedback.Fatal(tr("Cannot remove the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric) + } else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: string(newValuesJSON)}); err != nil { + feedback.Fatal(tr("Cannot remove the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric) } + + saveConfiguration(ctx, srv) } diff --git a/internal/cli/config/config.go b/internal/cli/config/config.go index d8d4cbf5e46..8c69e8e3f44 100644 --- a/internal/cli/config/config.go +++ b/internal/cli/config/config.go @@ -16,46 +16,64 @@ package config import ( + "context" "os" - "reflect" + "strings" - "github.com/arduino/arduino-cli/internal/cli/configuration" + f "github.com/arduino/arduino-cli/internal/algorithms" + "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "github.com/arduino/go-paths-helper" "github.com/spf13/cobra" ) var tr = i18n.Tr // NewCommand created a new `config` command -func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) *cobra.Command { configCommand := &cobra.Command{ Use: "config", Short: tr("Arduino configuration commands."), Example: " " + os.Args[0] + " config init", } - configCommand.AddCommand(initAddCommand(defaultSettings)) - configCommand.AddCommand(initDeleteCommand(srv, defaultSettings)) - configCommand.AddCommand(initDumpCommand(defaultSettings)) - configCommand.AddCommand(initGetCommand(srv, defaultSettings)) - configCommand.AddCommand(initInitCommand(defaultSettings)) - configCommand.AddCommand(initRemoveCommand(defaultSettings)) - configCommand.AddCommand(initSetCommand(defaultSettings)) + configCommand.AddCommand(initAddCommand(srv)) + configCommand.AddCommand(initDeleteCommand(srv)) + configCommand.AddCommand(initDumpCommand(srv)) + configCommand.AddCommand(initGetCommand(srv)) + configCommand.AddCommand(initInitCommand(srv)) + configCommand.AddCommand(initRemoveCommand(srv)) + configCommand.AddCommand(initSetCommand(srv)) return configCommand } -// GetSlicesConfigurationKeys is an helper function useful to autocomplete. -// It returns a list of configuration keys which can be changed -func GetSlicesConfigurationKeys(settings *configuration.Settings) []string { - var res []string - keys := settings.AllKeys() - for _, key := range keys { - kind, _ := typeOf(key) - if kind == reflect.Slice { - res = append(res, key) - } +func getAllSettingsKeys(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + res, _ := srv.SettingsEnumerate(ctx, &rpc.SettingsEnumerateRequest{}) + allKeys := f.Map(res.GetEntries(), (*rpc.SettingsEnumerateResponse_Entry).GetKey) + return allKeys +} + +func getAllArraySettingsKeys(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { + res, _ := srv.SettingsEnumerate(ctx, &rpc.SettingsEnumerateRequest{}) + arrayEntries := f.Filter(res.GetEntries(), func(e *rpc.SettingsEnumerateResponse_Entry) bool { + return strings.HasPrefix(e.GetType(), "[]") + }) + arrayKeys := f.Map(arrayEntries, (*rpc.SettingsEnumerateResponse_Entry).GetKey) + return arrayKeys +} + +func saveConfiguration(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { + var outConfig []byte + if res, err := srv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"}); err != nil { + feedback.Fatal(tr("Error writing to file: %v", err), feedback.ErrGeneric) + } else { + outConfig = []byte(res.GetEncodedSettings()) + } + + configFile := ctx.Value("config_file").(string) + if err := paths.New(configFile).WriteFile(outConfig); err != nil { + feedback.Fatal(tr("Error writing to file: %v", err), feedback.ErrGeneric) } - return res } diff --git a/internal/cli/config/delete.go b/internal/cli/config/delete.go index 75b81563aed..7ba5437cda2 100644 --- a/internal/cli/config/delete.go +++ b/internal/cli/config/delete.go @@ -19,15 +19,13 @@ import ( "context" "os" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) -func initDeleteCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { - configFile := defaultSettings.ConfigFileUsed() +func initDeleteCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { deleteCommand := &cobra.Command{ Use: "delete", Short: tr("Deletes a settings key and all its sub keys."), @@ -37,26 +35,24 @@ func initDeleteCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *config " " + os.Args[0] + " config delete board_manager.additional_urls", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - runDeleteCommand(srv, args, configFile) + ctx := cmd.Context() + runDeleteCommand(ctx, srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return defaultSettings.AllKeys(), cobra.ShellCompDirectiveDefault + ctx := cmd.Context() + return getAllSettingsKeys(ctx, srv), cobra.ShellCompDirectiveDefault }, } return deleteCommand } -func runDeleteCommand(srv rpc.ArduinoCoreServiceServer, args []string, configFile string) { +func runDeleteCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli config delete`") - ctx := context.Background() - toDelete := args[0] - _, err := srv.SettingsDelete(ctx, &rpc.SettingsDeleteRequest{Key: toDelete}) - if err != nil { - feedback.Fatal(tr("Cannot delete the key %[1]s: %[2]v", toDelete, err), feedback.ErrGeneric) - } - _, err = srv.SettingsWrite(ctx, &rpc.SettingsWriteRequest{FilePath: configFile}) - if err != nil { - feedback.Fatal(tr("Cannot write the file %[1]s: %[2]v", configFile, err), feedback.ErrGeneric) + key := args[0] + if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: ""}); err != nil { + feedback.Fatal(tr("Cannot delete the key %[1]s: %[2]v", key, err), feedback.ErrGeneric) } + + saveConfiguration(ctx, srv) } diff --git a/internal/cli/config/dump.go b/internal/cli/config/dump.go index 695e5b11ce8..5212ec9d1fa 100644 --- a/internal/cli/config/dump.go +++ b/internal/cli/config/dump.go @@ -18,14 +18,13 @@ package config import ( "os" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "gopkg.in/yaml.v3" ) -func initDumpCommand(defaultSettings *configuration.Settings) *cobra.Command { +func initDumpCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { var dumpCommand = &cobra.Command{ Use: "dump", Short: tr("Prints the current configuration"), @@ -34,16 +33,41 @@ func initDumpCommand(defaultSettings *configuration.Settings) *cobra.Command { Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { logrus.Info("Executing `arduino-cli config dump`") - feedback.PrintResult(dumpResult{defaultSettings.AllSettings()}) + res := &rawResult{} + switch feedback.GetFormat() { + case feedback.JSON, feedback.MinifiedJSON: + resp, err := srv.ConfigurationSave(cmd.Context(), &rpc.ConfigurationSaveRequest{SettingsFormat: "json"}) + if err != nil { + logrus.Fatalf("Error creating configuration: %v", err) + } + res.rawJSON = []byte(resp.GetEncodedSettings()) + case feedback.Text: + resp, err := srv.ConfigurationSave(cmd.Context(), &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"}) + if err != nil { + logrus.Fatalf("Error creating configuration: %v", err) + } + res.rawYAML = []byte(resp.GetEncodedSettings()) + default: + logrus.Fatalf("Unsupported format: %v", feedback.GetFormat()) + } + feedback.PrintResult(dumpResult{Config: res}) }, } return dumpCommand } -// output from this command requires special formatting, let's create a dedicated -// feedback.Result implementation +type rawResult struct { + rawJSON []byte + rawYAML []byte +} + +func (r *rawResult) MarshalJSON() ([]byte, error) { + // it is already encoded in rawJSON field + return r.rawJSON, nil +} + type dumpResult struct { - Config map[string]interface{} `json:"config"` + Config *rawResult `json:"config"` } func (dr dumpResult) Data() interface{} { @@ -51,10 +75,6 @@ func (dr dumpResult) Data() interface{} { } func (dr dumpResult) String() string { - bs, err := yaml.Marshal(dr.Config) - if err != nil { - // Should never happen - panic(tr("unable to marshal config to YAML: %v", err)) - } - return string(bs) + // In case of text output do not wrap the output in outer JSON or YAML structure + return string(dr.Config.rawYAML) } diff --git a/internal/cli/config/get.go b/internal/cli/config/get.go index dec61be03a7..3061333366c 100644 --- a/internal/cli/config/get.go +++ b/internal/cli/config/get.go @@ -21,7 +21,6 @@ import ( "fmt" "os" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" @@ -29,7 +28,7 @@ import ( "gopkg.in/yaml.v3" ) -func initGetCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { +func initGetCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { getCommand := &cobra.Command{ Use: "get", Short: tr("Gets a settings key value."), @@ -43,7 +42,8 @@ func initGetCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configura runGetCommand(srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return defaultSettings.AllKeys(), cobra.ShellCompDirectiveDefault + ctx := cmd.Context() + return getAllSettingsKeys(ctx, srv), cobra.ShellCompDirectiveDefault }, } return getCommand @@ -59,8 +59,7 @@ func runGetCommand(srv rpc.ArduinoCoreServiceServer, args []string) { feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", toGet, err), feedback.ErrGeneric) } var result getResult - err = json.Unmarshal([]byte(resp.GetJsonData()), &result.resp) - if err != nil { + if err := json.Unmarshal([]byte(resp.GetEncodedValue()), &result.resp); err != nil { // Should never happen... panic(fmt.Sprintf("Cannot parse JSON for key %[1]s: %[2]v", toGet, err)) } diff --git a/internal/cli/config/init.go b/internal/cli/config/init.go index 5bbc753b153..65f514dfe39 100644 --- a/internal/cli/config/init.go +++ b/internal/cli/config/init.go @@ -16,12 +16,12 @@ package config import ( + "context" "os" - "strings" "github.com/arduino/arduino-cli/internal/cli/arguments" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -35,7 +35,7 @@ var ( const defaultFileName = "arduino-cli.yaml" -func initInitCommand(defaultSettings *configuration.Settings) *cobra.Command { +func initInitCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { initCommand := &cobra.Command{ Use: "init", Short: tr("Writes current configuration to a configuration file."), @@ -50,7 +50,7 @@ func initInitCommand(defaultSettings *configuration.Settings) *cobra.Command { arguments.CheckFlagsConflicts(cmd, "dest-file", "dest-dir") }, Run: func(cmd *cobra.Command, args []string) { - runInitCommand(cmd, defaultSettings) + runInitCommand(srv) }, } initCommand.Flags().StringVar(&destDir, "dest-dir", "", tr("Sets where to save the configuration file.")) @@ -59,8 +59,9 @@ func initInitCommand(defaultSettings *configuration.Settings) *cobra.Command { return initCommand } -func runInitCommand(cmd *cobra.Command, defaultSettings *configuration.Settings) { +func runInitCommand(srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli config init`") + ctx := context.Background() var configFileAbsPath *paths.Path var configFileDir *paths.Path @@ -72,17 +73,18 @@ func runInitCommand(cmd *cobra.Command, defaultSettings *configuration.Settings) if err != nil { feedback.Fatal(tr("Cannot find absolute path: %v", err), feedback.ErrGeneric) } - configFileDir = configFileAbsPath.Parent() - case destDir == "": - destDir = defaultSettings.GetString("directories.Data") - fallthrough - default: + + case destDir != "": configFileDir, err = paths.New(destDir).Abs() if err != nil { feedback.Fatal(tr("Cannot find absolute path: %v", err), feedback.ErrGeneric) } configFileAbsPath = configFileDir.Join(defaultFileName) + + default: + configFileAbsPath = paths.New(ctx.Value("config_file").(string)) + configFileDir = configFileAbsPath.Parent() } if !overwrite && configFileAbsPath.Exist() { @@ -95,19 +97,22 @@ func runInitCommand(cmd *cobra.Command, defaultSettings *configuration.Settings) feedback.Fatal(tr("Cannot create config file directory: %v", err), feedback.ErrGeneric) } - newSettings := configuration.NewSettings() - configuration.BindFlags(cmd, newSettings) + // for _, url := range newSettings.GetStringSlice("board_manager.additional_urls") { + // if strings.Contains(url, ",") { + // feedback.Fatal(tr("Urls cannot contain commas. Separate multiple urls exported as env var with a space:\n%s", url), + // feedback.ErrGeneric) + // } + // } - for _, url := range newSettings.GetStringSlice("board_manager.additional_urls") { - if strings.Contains(url, ",") { - feedback.Fatal(tr("Urls cannot contain commas. Separate multiple urls exported as env var with a space:\n%s", url), - feedback.ErrGeneric) - } + resp, err := srv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"}) + if err != nil { + feedback.Fatal(tr("Error creating configuration: %v", err), feedback.ErrGeneric) } - if err := newSettings.WriteConfigAs(configFileAbsPath.String()); err != nil { + if err := configFileAbsPath.WriteFile([]byte(resp.GetEncodedSettings())); err != nil { feedback.Fatal(tr("Cannot create config file: %v", err), feedback.ErrGeneric) } + feedback.PrintResult(initResult{ConfigFileAbsPath: configFileAbsPath}) } diff --git a/internal/cli/config/remove.go b/internal/cli/config/remove.go index efbd416913a..4114a146a45 100644 --- a/internal/cli/config/remove.go +++ b/internal/cli/config/remove.go @@ -16,16 +16,18 @@ package config import ( + "context" + "encoding/json" "os" - "reflect" + "slices" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) -func initRemoveCommand(defaultSettings *configuration.Settings) *cobra.Command { +func initRemoveCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { removeCommand := &cobra.Command{ Use: "remove", Short: tr("Removes one or more values from a setting."), @@ -35,39 +37,42 @@ func initRemoveCommand(defaultSettings *configuration.Settings) *cobra.Command { " " + os.Args[0] + " config remove board_manager.additional_urls https://example.com/package_example_index.json https://another-url.com/package_another_index.json\n", Args: cobra.MinimumNArgs(2), Run: func(cmd *cobra.Command, args []string) { - runRemoveCommand(args, defaultSettings) + ctx := cmd.Context() + runRemoveCommand(ctx, srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetSlicesConfigurationKeys(defaultSettings), cobra.ShellCompDirectiveDefault + ctx := cmd.Context() + return getAllArraySettingsKeys(ctx, srv), cobra.ShellCompDirectiveDefault }, } return removeCommand } -func runRemoveCommand(args []string, defaultSettings *configuration.Settings) { +func runRemoveCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli config remove`") key := args[0] - kind := validateKey(key) - if kind != reflect.Slice { + if !slices.Contains(getAllArraySettingsKeys(ctx, srv), key) { msg := tr("The key '%[1]v' is not a list of items, can't remove from it.\nMaybe use '%[2]s'?", key, "config delete") feedback.Fatal(msg, feedback.ErrGeneric) } - mappedValues := map[string]bool{} - for _, v := range defaultSettings.GetStringSlice(key) { - mappedValues[v] = true + var currentValues []string + if resp, err := srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: key}); err != nil { + feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric) + } else if err := json.Unmarshal([]byte(resp.GetEncodedValue()), ¤tValues); err != nil { + feedback.Fatal(tr("Cannot get the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric) } + for _, arg := range args[1:] { - delete(mappedValues, arg) - } - values := []string{} - for k := range mappedValues { - values = append(values, k) + currentValues = slices.DeleteFunc(currentValues, func(in string) bool { return in == arg }) } - defaultSettings.Set(key, values) - if err := defaultSettings.WriteConfig(); err != nil { - feedback.Fatal(tr("Can't write config file: %v", err), feedback.ErrGeneric) + if newValuesJSON, err := json.Marshal(currentValues); err != nil { + feedback.Fatal(tr("Cannot remove the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric) + } else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: string(newValuesJSON)}); err != nil { + feedback.Fatal(tr("Cannot remove the configuration key %[1]s: %[2]v", key, err), feedback.ErrGeneric) } + + saveConfiguration(ctx, srv) } diff --git a/internal/cli/config/set.go b/internal/cli/config/set.go index 10fb9e6f239..dd219ba1918 100644 --- a/internal/cli/config/set.go +++ b/internal/cli/config/set.go @@ -16,17 +16,17 @@ package config import ( + "context" + "encoding/json" "os" - "reflect" - "strconv" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) -func initSetCommand(defaultSettings *configuration.Settings) *cobra.Command { +func initSetCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { setCommand := &cobra.Command{ Use: "set", Short: tr("Sets a setting value."), @@ -38,41 +38,39 @@ func initSetCommand(defaultSettings *configuration.Settings) *cobra.Command { " " + os.Args[0] + " config set board_manager.additional_urls https://example.com/package_example_index.json https://another-url.com/package_another_index.json", Args: cobra.MinimumNArgs(2), Run: func(cmd *cobra.Command, args []string) { - runSetCommand(defaultSettings, args) + runSetCommand(cmd.Context(), srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return defaultSettings.AllKeys(), cobra.ShellCompDirectiveDefault + ctx := cmd.Context() + return getAllSettingsKeys(ctx, srv), cobra.ShellCompDirectiveDefault }, } return setCommand } -func runSetCommand(defaultSettings *configuration.Settings, args []string) { +func runSetCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli config set`") - key := args[0] - kind := validateKey(key) - if kind != reflect.Slice && len(args) > 2 { - feedback.Fatal(tr("Can't set multiple values in key %v", key), feedback.ErrGeneric) + req := &rpc.SettingsSetValueRequest{ + Key: args[0], } - - var value interface{} - switch kind { - case reflect.Slice: - value = uniquify(args[1:]) - case reflect.String: - value = args[1] - case reflect.Bool: - var err error - value, err = strconv.ParseBool(args[1]) + if len(args) == 2 { + // Single value + req.EncodedValue = args[1] + req.ValueFormat = "cli" + } else { + // Array + jsonValues, err := json.Marshal(args[1:]) if err != nil { - feedback.Fatal(tr("error parsing value: %v", err), feedback.ErrGeneric) + feedback.Fatal(tr("Error setting value: %v", err), feedback.ErrGeneric) } + req.EncodedValue = string(jsonValues) + req.ValueFormat = "json" } - defaultSettings.Set(key, value) - - if err := defaultSettings.WriteConfig(); err != nil { - feedback.Fatal(tr("Writing config file: %v", err), feedback.ErrGeneric) + if _, err := srv.SettingsSetValue(ctx, req); err != nil { + feedback.Fatal(tr("Error setting value: %v", err), feedback.ErrGeneric) } + + saveConfiguration(ctx, srv) } diff --git a/internal/cli/config/validate.go b/internal/cli/config/validate.go deleted file mode 100644 index f494bfaac0b..00000000000 --- a/internal/cli/config/validate.go +++ /dev/null @@ -1,61 +0,0 @@ -// 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 config - -import ( - "fmt" - "reflect" - - "github.com/arduino/arduino-cli/internal/cli/feedback" -) - -var validMap = map[string]reflect.Kind{ - "board_manager.additional_urls": reflect.Slice, - "daemon.port": reflect.String, - "directories.data": reflect.String, - "directories.downloads": reflect.String, - "directories.user": reflect.String, - "directories.builtin.tools": reflect.String, - "directories.builtin.libraries": reflect.String, - "library.enable_unsafe_install": reflect.Bool, - "locale": reflect.String, - "logging.file": reflect.String, - "logging.format": reflect.String, - "logging.level": reflect.String, - "sketch.always_export_binaries": reflect.Bool, - "metrics.addr": reflect.String, - "metrics.enabled": reflect.Bool, - "network.proxy": reflect.String, - "network.user_agent_ext": reflect.String, - "output.no_color": reflect.Bool, - "updater.enable_notification": reflect.Bool, -} - -func typeOf(key string) (reflect.Kind, error) { - t, ok := validMap[key] - if !ok { - return reflect.Invalid, fmt.Errorf(tr("Settings key doesn't exist")) - } - return t, nil -} - -func validateKey(key string) reflect.Kind { - kind, err := typeOf(key) - if err != nil { - feedback.FatalError(err, feedback.ErrGeneric) - } - return kind -} diff --git a/internal/cli/configuration/board_manager.go b/internal/cli/configuration/board_manager.go new file mode 100644 index 00000000000..22f982f5404 --- /dev/null +++ b/internal/cli/configuration/board_manager.go @@ -0,0 +1,23 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +func (settings *Settings) BoardManagerAdditionalUrls() []string { + if urls, ok, _ := settings.GetStringSliceOk("board_manager.additional_urls"); ok { + return urls + } + return settings.Defaults.GetStringSlice("board_manager.additional_urls") +} diff --git a/internal/cli/configuration/build_cache.go b/internal/cli/configuration/build_cache.go new file mode 100644 index 00000000000..a4bca322307 --- /dev/null +++ b/internal/cli/configuration/build_cache.go @@ -0,0 +1,34 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +import "time" + +// GetCompilationsBeforeBuildCachePurge returns the number of compilations before the build cache is purged. +func (s *Settings) GetCompilationsBeforeBuildCachePurge() uint { + if res, ok, _ := s.GetUintOk("build_cache.compilations_before_purge"); ok { + return res + } + return s.Defaults.GetUint("build_cache.compilations_before_purge") +} + +// GetBuildCacheTTL returns the time-to-live of the build cache (i.e. the minimum age to wait before purging the cache). +func (s *Settings) GetBuildCacheTTL() time.Duration { + if res, ok, _ := s.GetDurationOk("build_cache.ttl"); ok { + return res + } + return s.Defaults.GetDuration("build_cache.ttl") +} diff --git a/internal/cli/configuration/configuration.go b/internal/cli/configuration/configuration.go index 996a1b1cbfc..672cbb466df 100644 --- a/internal/cli/configuration/configuration.go +++ b/internal/cli/configuration/configuration.go @@ -19,73 +19,31 @@ import ( "os" "path/filepath" "runtime" - "strings" "github.com/arduino/arduino-cli/internal/cli/feedback" + "github.com/arduino/arduino-cli/internal/go-configmap" "github.com/arduino/arduino-cli/internal/i18n" - paths "github.com/arduino/go-paths-helper" "github.com/arduino/go-win32-utils" - "github.com/spf13/cobra" - "github.com/spf13/viper" ) var tr = i18n.Tr // Settings contains the configuration of the Arduino CLI core service type Settings struct { - *viper.Viper + *configmap.Map + Defaults *configmap.Map } // NewSettings creates a new instance of Settings with the default values set func NewSettings() *Settings { - res := &Settings{viper.New()} + res := &Settings{ + Map: configmap.New(), + Defaults: configmap.New(), + } SetDefaults(res) return res } -// Init initialize defaults and read the configuration file. -// Please note the logging system hasn't been configured yet, -// so logging shouldn't be used here. -func Init(configFile string) *Settings { - // Create a new viper instance with default values for all the settings - settings := NewSettings() - - // Set config name and config path - if configFilePath := paths.New(configFile); configFilePath != nil { - settings.SetConfigName(strings.TrimSuffix(configFilePath.Base(), configFilePath.Ext())) - settings.AddConfigPath(configFilePath.Parent().String()) - } else { - configDir := settings.GetString("directories.Data") - // Get default data path if none was provided - if configDir == "" { - configDir = getDefaultArduinoDataDir() - } - - settings.SetConfigName("arduino-cli") - settings.AddConfigPath(configDir) - } - - // Attempt to read config file - if err := settings.ReadInConfig(); err != nil { - // ConfigFileNotFoundError is acceptable, anything else - // should be reported to the user - if _, ok := err.(viper.ConfigFileNotFoundError); !ok { - feedback.Warning(tr("Error reading config file: %v", err)) - } - } - - return settings -} - -// BindFlags creates all the flags binding between the cobra Command and the instance of viper -func BindFlags(cmd *cobra.Command, settings *Settings) { - settings.BindPFlag("logging.level", cmd.Flag("log-level")) - settings.BindPFlag("logging.file", cmd.Flag("log-file")) - settings.BindPFlag("logging.format", cmd.Flag("log-format")) - settings.BindPFlag("board_manager.additional_urls", cmd.Flag("additional-urls")) - settings.BindPFlag("output.no_color", cmd.Flag("no-color")) -} - // getDefaultArduinoDataDir returns the full path to the default arduino folder func getDefaultArduinoDataDir() string { userHomeDir, err := os.UserHomeDir() @@ -136,11 +94,6 @@ func getDefaultUserDir() string { } } -// GetDefaultBuiltinLibrariesDir returns the full path to the default builtin libraries dir -func GetDefaultBuiltinLibrariesDir() string { - return filepath.Join(getDefaultArduinoDataDir(), "libraries") -} - // FindConfigFileInArgsFallbackOnEnv returns the config file path using the // argument '--config-file' (if specified), if empty looks for the ARDUINO_CONFIG_FILE env, // or looking in the current working dir @@ -153,5 +106,8 @@ func FindConfigFileInArgsFallbackOnEnv(args []string) string { } } } - return os.Getenv("ARDUINO_CONFIG_FILE") + if p, ok := os.LookupEnv("ARDUINO_CONFIG_FILE"); ok { + return p + } + return filepath.Join(getDefaultArduinoDataDir(), "arduino-cli.yaml") } diff --git a/internal/cli/configuration/configuration_test.go b/internal/cli/configuration/configuration_test.go index 8b0fd3938cc..68d6ab682d4 100644 --- a/internal/cli/configuration/configuration_test.go +++ b/internal/cli/configuration/configuration_test.go @@ -16,47 +16,28 @@ package configuration import ( - "fmt" - "os" - "path/filepath" "testing" "github.com/stretchr/testify/require" ) -func tmpDirOrDie() string { - dir, err := os.MkdirTemp(os.TempDir(), "cli_test") - if err != nil { - panic(fmt.Sprintf("error creating tmp dir: %v", err)) - } - // Symlinks are evaluated becase the temp folder on Mac OS is inside /var, it's not writable - // and is a symlink to /private/var, we want the full path so we do this - dir, err = filepath.EvalSymlinks(dir) - if err != nil { - panic(fmt.Sprintf("error evaluating tmp dir symlink: %v", err)) - } - return dir -} - func TestInit(t *testing.T) { - tmp := tmpDirOrDie() - defer os.RemoveAll(tmp) - settings := Init(filepath.Join(tmp, "arduino-cli.yaml")) - require.NotNil(t, settings) + settings := NewSettings() - require.Equal(t, "info", settings.GetString("logging.level")) - require.Equal(t, "text", settings.GetString("logging.format")) + require.Equal(t, "info", settings.Defaults.GetString("logging.level")) + require.Equal(t, "text", settings.Defaults.GetString("logging.format")) - require.Empty(t, settings.GetStringSlice("board_manager.additional_urls")) + require.Empty(t, settings.Defaults.GetStringSlice("board_manager.additional_urls")) - require.NotEmpty(t, settings.GetString("directories.Data")) - require.NotEmpty(t, settings.GetString("directories.Downloads")) - require.NotEmpty(t, settings.GetString("directories.User")) + require.NotEmpty(t, settings.Defaults.GetString("directories.data")) + require.Empty(t, settings.Defaults.GetString("directories.downloads")) + require.NotEmpty(t, settings.DownloadsDir().String()) + require.NotEmpty(t, settings.Defaults.GetString("directories.user")) - require.Equal(t, "50051", settings.GetString("daemon.port")) + require.Equal(t, "50051", settings.Defaults.GetString("daemon.port")) - require.Equal(t, true, settings.GetBool("metrics.enabled")) - require.Equal(t, ":9090", settings.GetString("metrics.addr")) + require.Equal(t, true, settings.Defaults.GetBool("metrics.enabled")) + require.Equal(t, ":9090", settings.Defaults.GetString("metrics.addr")) } func TestFindConfigFile(t *testing.T) { diff --git a/internal/cli/configuration/daemon.go b/internal/cli/configuration/daemon.go new file mode 100644 index 00000000000..9ae053c2aee --- /dev/null +++ b/internal/cli/configuration/daemon.go @@ -0,0 +1,23 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +func (s *Settings) DaemonPort() string { + if port, ok, _ := s.GetStringOk("daemon.port"); ok { + return port + } + return s.Defaults.GetString("daemon.port") +} diff --git a/internal/cli/configuration/defaults.go b/internal/cli/configuration/defaults.go index c983310a746..a47538dd298 100644 --- a/internal/cli/configuration/defaults.go +++ b/internal/cli/configuration/defaults.go @@ -16,55 +16,70 @@ package configuration import ( - "path/filepath" - "strings" + "os" "time" ) // SetDefaults sets the default values for certain keys func SetDefaults(settings *Settings) { + setKeyTypeSchema := func(k string, v any) { + settings.SetKeyTypeSchema(k, v) + settings.Defaults.SetKeyTypeSchema(k, v) + } + setDefaultValueAndKeyTypeSchema := func(k string, v any) { + setKeyTypeSchema(k, v) + settings.Defaults.Set(k, v) + } + // logging - settings.SetDefault("logging.level", "info") - settings.SetDefault("logging.format", "text") + setDefaultValueAndKeyTypeSchema("logging.level", "info") + setDefaultValueAndKeyTypeSchema("logging.format", "text") + setKeyTypeSchema("logging.file", "") // Libraries - settings.SetDefault("library.enable_unsafe_install", false) + setDefaultValueAndKeyTypeSchema("library.enable_unsafe_install", false) // Boards Manager - settings.SetDefault("board_manager.additional_urls", []string{}) + setDefaultValueAndKeyTypeSchema("board_manager.additional_urls", []string{}) // arduino directories - settings.SetDefault("directories.Data", getDefaultArduinoDataDir()) - settings.SetDefault("directories.Downloads", filepath.Join(getDefaultArduinoDataDir(), "staging")) - settings.SetDefault("directories.User", getDefaultUserDir()) + setDefaultValueAndKeyTypeSchema("directories.data", getDefaultArduinoDataDir()) + setDefaultValueAndKeyTypeSchema("directories.downloads", "") + setDefaultValueAndKeyTypeSchema("directories.user", getDefaultUserDir()) // Sketch compilation - settings.SetDefault("sketch.always_export_binaries", false) - settings.SetDefault("build_cache.ttl", time.Hour*24*30) - settings.SetDefault("build_cache.compilations_before_purge", 10) + setDefaultValueAndKeyTypeSchema("sketch.always_export_binaries", false) + setDefaultValueAndKeyTypeSchema("build_cache.ttl", (time.Hour * 24 * 30).String()) + setDefaultValueAndKeyTypeSchema("build_cache.compilations_before_purge", uint(10)) // daemon settings - settings.SetDefault("daemon.port", "50051") + setDefaultValueAndKeyTypeSchema("daemon.port", "50051") // metrics settings - settings.SetDefault("metrics.enabled", true) - settings.SetDefault("metrics.addr", ":9090") + setDefaultValueAndKeyTypeSchema("metrics.enabled", true) + setDefaultValueAndKeyTypeSchema("metrics.addr", ":9090") // output settings - settings.SetDefault("output.no_color", false) + setDefaultValueAndKeyTypeSchema("output.no_color", false) // updater settings - settings.SetDefault("updater.enable_notification", true) + setDefaultValueAndKeyTypeSchema("updater.enable_notification", true) +} +// InjectEnvVars change settings based on the environment variables values +func InjectEnvVars(settings *Settings) { // Bind env vars - settings.SetEnvPrefix("ARDUINO") - settings.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - settings.AutomaticEnv() + settings.InjectEnvVars(os.Environ(), "ARDUINO") // Bind env aliases to keep backward compatibility - settings.BindEnv("library.enable_unsafe_install", "ARDUINO_ENABLE_UNSAFE_LIBRARY_INSTALL") - settings.BindEnv("directories.User", "ARDUINO_SKETCHBOOK_DIR") - settings.BindEnv("directories.Downloads", "ARDUINO_DOWNLOADS_DIR") - settings.BindEnv("directories.Data", "ARDUINO_DATA_DIR") - settings.BindEnv("sketch.always_export_binaries", "ARDUINO_SKETCH_ALWAYS_EXPORT_BINARIES") + setIfEnvExists := func(key, env string) { + if v, ok := os.LookupEnv(env); ok { + settings.SetFromCLIArgs(key, v) + } + } + setIfEnvExists("library.enable_unsafe_install", "ARDUINO_ENABLE_UNSAFE_LIBRARY_INSTALL") + setIfEnvExists("directories.user", "ARDUINO_SKETCHBOOK_DIR") + setIfEnvExists("directories.downloads", "ARDUINO_DOWNLOADS_DIR") + setIfEnvExists("directories.data", "ARDUINO_DATA_DIR") + setIfEnvExists("sketch.always_export_binaries", "ARDUINO_SKETCH_ALWAYS_EXPORT_BINARIES") } diff --git a/internal/cli/configuration/directories.go b/internal/cli/configuration/directories.go index 0fb9a9d19e5..a58aa21f885 100644 --- a/internal/cli/configuration/directories.go +++ b/internal/cli/configuration/directories.go @@ -20,20 +20,15 @@ import ( ) // HardwareDirectories returns all paths that may contains hardware packages. -func HardwareDirectories(settings *Settings) paths.PathList { +func (settings *Settings) HardwareDirectories() paths.PathList { res := paths.PathList{} - if settings.IsSet("directories.Data") { - packagesDir := PackagesDir(settings) - if packagesDir.IsDir() { - res.Add(packagesDir) - } + if packagesDir := settings.PackagesDir(); packagesDir.IsDir() { + res.Add(packagesDir) } - if settings.IsSet("directories.User") { - skDir := paths.New(settings.GetString("directories.User")) - hwDir := skDir.Join("hardware") - if hwDir.IsDir() { + if userDir, ok, _ := settings.GetStringOk("directories.user"); ok { + if hwDir := paths.New(userDir, "hardware"); hwDir.IsDir() { res.Add(hwDir) } } @@ -43,34 +38,51 @@ func HardwareDirectories(settings *Settings) paths.PathList { // IDEBuiltinLibrariesDir returns the IDE-bundled libraries path. Usually // this directory is present in the Arduino IDE. -func IDEBuiltinLibrariesDir(settings *Settings) *paths.Path { - return paths.New(settings.GetString("directories.builtin.Libraries")) +func (settings *Settings) IDEBuiltinLibrariesDir() *paths.Path { + if builtinLibsDir, ok, _ := settings.GetStringOk("directories.builtin.libraries"); ok { + return paths.New(builtinLibsDir) + } + return nil } // LibrariesDir returns the full path to the user directory containing // custom libraries -func LibrariesDir(settings *Settings) *paths.Path { - return paths.New(settings.GetString("directories.User")).Join("libraries") +func (settings *Settings) LibrariesDir() *paths.Path { + return settings.UserDir().Join("libraries") +} + +// UserDir returns the full path to the user directory +func (settings *Settings) UserDir() *paths.Path { + if userDir, ok, _ := settings.GetStringOk("directories.user"); ok { + return paths.New(userDir) + } + return paths.New(settings.Defaults.GetString("directories.user")) } // PackagesDir returns the full path to the packages folder -func PackagesDir(settings *Settings) *paths.Path { - return DataDir(settings).Join("packages") +func (settings *Settings) PackagesDir() *paths.Path { + return settings.DataDir().Join("packages") } // ProfilesCacheDir returns the full path to the profiles cache directory // (it contains all the platforms and libraries used to compile a sketch // using profiles) -func ProfilesCacheDir(settings *Settings) *paths.Path { - return DataDir(settings).Join("internal") +func (settings *Settings) ProfilesCacheDir() *paths.Path { + return settings.DataDir().Join("internal") } // DataDir returns the full path to the data directory -func DataDir(settings *Settings) *paths.Path { - return paths.New(settings.GetString("directories.Data")) +func (settings *Settings) DataDir() *paths.Path { + if dataDir, ok, _ := settings.GetStringOk("directories.data"); ok { + return paths.New(dataDir) + } + return paths.New(settings.Defaults.GetString("directories.data")) } // DownloadsDir returns the full path to the download cache directory -func DownloadsDir(settings *Settings) *paths.Path { - return paths.New(settings.GetString("directories.Downloads")) +func (settings *Settings) DownloadsDir() *paths.Path { + if downloadDir, ok, _ := settings.GetStringOk("directories.downloads"); ok { + return paths.New(downloadDir) + } + return settings.DataDir().Join("staging") } diff --git a/internal/cli/configuration/libraries.go b/internal/cli/configuration/libraries.go new file mode 100644 index 00000000000..6dc73b9b0d6 --- /dev/null +++ b/internal/cli/configuration/libraries.go @@ -0,0 +1,20 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +func (s *Settings) LibraryEnableUnsafeInstall() bool { + return s.GetBool("library.enable_unsafe_install") +} diff --git a/internal/cli/configuration/locale.go b/internal/cli/configuration/locale.go new file mode 100644 index 00000000000..e292ea8f170 --- /dev/null +++ b/internal/cli/configuration/locale.go @@ -0,0 +1,20 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +func (s *Settings) Locale() string { + return s.Defaults.GetString("locale") +} diff --git a/internal/cli/configuration/logging.go b/internal/cli/configuration/logging.go new file mode 100644 index 00000000000..73f1bacab35 --- /dev/null +++ b/internal/cli/configuration/logging.go @@ -0,0 +1,42 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +import "github.com/arduino/go-paths-helper" + +func (s *Settings) LoggingLevel() string { + if l, ok, _ := s.GetStringOk("logging.level"); ok { + return l + } + return s.Defaults.GetString("logging.level") +} + +func (s *Settings) LoggingFormat() string { + if l, ok, _ := s.GetStringOk("logging.format"); ok { + return l + } + return s.Defaults.GetString("logging.format") +} + +func (s *Settings) LoggingFile() *paths.Path { + if l, ok, _ := s.GetStringOk("logging.file"); ok && l != "" { + return paths.New(l) + } + if l, ok, _ := s.Defaults.GetStringOk("logging.file"); ok && l != "" { + return paths.New(l) + } + return nil +} diff --git a/internal/cli/configuration/network.go b/internal/cli/configuration/network.go index c88b974c10d..7fac7ee6890 100644 --- a/internal/cli/configuration/network.go +++ b/internal/cli/configuration/network.go @@ -1,6 +1,6 @@ // This file is part of arduino-cli. // -// Copyright 2020 ARDUINO SA (http://www.arduino.cc/) +// Copyright 2024 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. @@ -28,7 +28,7 @@ import ( ) // UserAgent returns the user agent (mainly used by HTTP clients) -func UserAgent(settings *Settings) string { +func (settings *Settings) UserAgent() string { subComponent := "" if settings != nil { subComponent = settings.GetString("network.user_agent_ext") @@ -51,15 +51,14 @@ func UserAgent(settings *Settings) string { extendedUA) } +// ExtraUserAgent returns the extended user-agent section provided via configuration settings +func (settings *Settings) ExtraUserAgent() string { + return settings.GetString("network.user_agent_ext") +} + // NetworkProxy returns the proxy configuration (mainly used by HTTP clients) -func NetworkProxy(settings *Settings) (*url.URL, error) { - if settings == nil || !settings.IsSet("network.proxy") { - return nil, nil - } - if proxyConfig := settings.GetString("network.proxy"); proxyConfig == "" { - // empty configuration - // this workaround must be here until viper can UnSet properties: - // https://github.com/spf13/viper/pull/519 +func (settings *Settings) NetworkProxy() (*url.URL, error) { + if proxyConfig, ok, _ := settings.GetStringOk("network.proxy"); !ok { return nil, nil } else if proxy, err := url.Parse(proxyConfig); err != nil { return nil, fmt.Errorf(tr("Invalid network.proxy '%[1]s': %[2]s"), proxyConfig, err) @@ -70,7 +69,7 @@ func NetworkProxy(settings *Settings) (*url.URL, error) { // NewHttpClient returns a new http client for use in the arduino-cli func (settings *Settings) NewHttpClient() (*http.Client, error) { - proxy, err := NetworkProxy(settings) + proxy, err := settings.NetworkProxy() if err != nil { return nil, err } @@ -79,7 +78,7 @@ func (settings *Settings) NewHttpClient() (*http.Client, error) { transport: &http.Transport{ Proxy: http.ProxyURL(proxy), }, - userAgent: UserAgent(settings), + userAgent: settings.UserAgent(), }, }, nil } diff --git a/internal/cli/configuration/network_test.go b/internal/cli/configuration/network_test.go index 6d6218c8f5d..ba713394d34 100644 --- a/internal/cli/configuration/network_test.go +++ b/internal/cli/configuration/network_test.go @@ -32,7 +32,7 @@ func TestUserAgentHeader(t *testing.T) { })) defer ts.Close() - settings := configuration.Init("") + settings := configuration.NewSettings() settings.Set("network.user_agent_ext", "test-user-agent") client, err := settings.NewHttpClient() require.NoError(t, err) @@ -55,7 +55,7 @@ func TestProxy(t *testing.T) { })) defer ts.Close() - settings := configuration.Init("") + settings := configuration.NewSettings() settings.Set("network.proxy", ts.URL) client, err := settings.NewHttpClient() require.NoError(t, err) diff --git a/internal/cli/configuration/output.go b/internal/cli/configuration/output.go new file mode 100644 index 00000000000..67ae5e72d99 --- /dev/null +++ b/internal/cli/configuration/output.go @@ -0,0 +1,20 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +func (s *Settings) NoColor() bool { + return s.GetBool("output.no_color") +} diff --git a/internal/cli/configuration/sketch.go b/internal/cli/configuration/sketch.go new file mode 100644 index 00000000000..27638b67df5 --- /dev/null +++ b/internal/cli/configuration/sketch.go @@ -0,0 +1,25 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +// SketchAlwaysExportBinaries returns true if the compile command should +// export binaries by default. +func (settings *Settings) SketchAlwaysExportBinaries() bool { + if res, ok, _ := settings.GetBoolOk("sketch.always_export_binaries"); ok { + return res + } + return settings.Defaults.GetBool("sketch.always_export_binaries") +} diff --git a/internal/cli/configuration/updater.go b/internal/cli/configuration/updater.go new file mode 100644 index 00000000000..3f553782254 --- /dev/null +++ b/internal/cli/configuration/updater.go @@ -0,0 +1,23 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configuration + +func (s *Settings) UpdaterEnableNotification() bool { + if en, ok, _ := s.GetBoolOk("updater.enable_notification"); ok { + return en + } + return s.GetBool("updater.enable_notification") +} diff --git a/internal/cli/daemon/daemon.go b/internal/cli/daemon/daemon.go index 8e719400eaf..76c7e9a24ef 100644 --- a/internal/cli/daemon/daemon.go +++ b/internal/cli/daemon/daemon.go @@ -21,10 +21,10 @@ import ( "fmt" "net" "os" + "path/filepath" "strings" "syscall" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -43,7 +43,7 @@ var ( ) // NewCommand created a new `daemon` command -func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) *cobra.Command { var daemonPort string daemonCommand := &cobra.Command{ Use: "daemon", @@ -52,19 +52,40 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration Args: cobra.NoArgs, PreRun: func(cmd *cobra.Command, args []string) { // Bundled libraries support is enabled by default when running as a daemon - defaultSettings.SetDefault( - "directories.builtin.Libraries", - configuration.GetDefaultBuiltinLibrariesDir()) + if settings.GetDirectories().GetBuiltin().GetLibraries() == "" { + defaultBuiltinLibDir := filepath.Join(settings.GetDirectories().GetData(), "libraries") + _, err := srv.SettingsSetValue(cmd.Context(), &rpc.SettingsSetValueRequest{ + Key: "directories.builtin.libraries", + ValueFormat: "cli", + EncodedValue: defaultBuiltinLibDir, + }) + if err != nil { + // Should never happen... + panic("Failed to set default value for directories.builtin.libraries: " + err.Error()) + } + } }, Run: func(cmd *cobra.Command, args []string) { runDaemonCommand(srv, daemonPort) }, } - daemonCommand.Flags().StringVar(&daemonPort, "port", defaultSettings.GetString("daemon.port"), tr("The TCP port the daemon will listen to")) - daemonCommand.Flags().BoolVar(&daemonize, "daemonize", false, tr("Do not terminate daemon process if the parent process dies")) - daemonCommand.Flags().BoolVar(&debug, "debug", false, tr("Enable debug logging of gRPC calls")) - daemonCommand.Flags().StringVar(&debugFile, "debug-file", "", tr("Append debug logging to the specified file")) - daemonCommand.Flags().StringSliceVar(&debugFilters, "debug-filter", []string{}, tr("Display only the provided gRPC calls")) + defaultDaemonPort := settings.GetDaemon().GetPort() + + daemonCommand.Flags().StringVar(&daemonPort, + "port", defaultDaemonPort, + tr("The TCP port the daemon will listen to")) + daemonCommand.Flags().BoolVar(&daemonize, + "daemonize", false, + tr("Do not terminate daemon process if the parent process dies")) + daemonCommand.Flags().BoolVar(&debug, + "debug", false, + tr("Enable debug logging of gRPC calls")) + daemonCommand.Flags().StringVar(&debugFile, + "debug-file", "", + tr("Append debug logging to the specified file")) + daemonCommand.Flags().StringSliceVar(&debugFilters, + "debug-filter", []string{}, + tr("Display only the provided gRPC calls")) return daemonCommand } diff --git a/internal/cli/lib/install.go b/internal/cli/lib/install.go index d8aafc8bd1a..7465b4f4fbd 100644 --- a/internal/cli/lib/install.go +++ b/internal/cli/lib/install.go @@ -23,7 +23,6 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/cli/instance" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -34,13 +33,13 @@ import ( semver "go.bug.st/relaxed-semver" ) -func initInstallCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { +func initInstallCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) *cobra.Command { var noDeps bool var noOverwrite bool var gitURL bool var zipPath bool var useBuiltinLibrariesDir bool - enableUnsafeInstall := defaultSettings.GetBool("library.enable_unsafe_install") + enableUnsafeInstall := settings.GetLibrary().GetEnableUnsafeInstall() installCommand := &cobra.Command{ Use: fmt.Sprintf("install %s[@%s]...", tr("LIBRARY"), tr("VERSION_NUMBER")), Short: tr("Installs one or more specified libraries into the system."), diff --git a/internal/cli/lib/lib.go b/internal/cli/lib/lib.go index d26c8678f08..5aa89cee8dd 100644 --- a/internal/cli/lib/lib.go +++ b/internal/cli/lib/lib.go @@ -18,7 +18,6 @@ package lib import ( "os" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" @@ -27,7 +26,7 @@ import ( var tr = i18n.Tr // NewCommand created a new `lib` command -func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *configuration.Settings) *cobra.Command { +func NewCommand(srv rpc.ArduinoCoreServiceServer, defaultSettings *rpc.Configuration) *cobra.Command { libCommand := &cobra.Command{ Use: "lib", Short: tr("Arduino commands about libraries."), diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index aa1d0f1b314..4bfa3c06a7c 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -116,6 +116,7 @@ func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, namesOnly instance.Init(ctx, srv, inst) } + // Perform library search searchResp, err := srv.LibrarySearch(ctx, &rpc.LibrarySearchRequest{ Instance: inst, SearchArgs: strings.Join(args, " "), diff --git a/internal/docsgen/main.go b/internal/docsgen/main.go index 69ac4983de9..fa175fff583 100644 --- a/internal/docsgen/main.go +++ b/internal/docsgen/main.go @@ -18,8 +18,8 @@ package main import ( "os" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli" - "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/spf13/cobra/doc" ) @@ -31,11 +31,10 @@ func main() { os.MkdirAll(os.Args[1], 0755) // Create the output folder if it doesn't already exist - settings := configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args)) - cli := cli.NewCommand(nil, settings) + srv := commands.NewArduinoCoreServer() + cli := cli.NewCommand(srv) cli.DisableAutoGenTag = true // Disable addition of auto-generated date stamp - err := doc.GenMarkdownTree(cli, os.Args[1]) - if err != nil { + if err := doc.GenMarkdownTree(cli, os.Args[1]); err != nil { panic(err) } } diff --git a/internal/go-configmap/cli.go b/internal/go-configmap/cli.go new file mode 100644 index 00000000000..3d4313a076e --- /dev/null +++ b/internal/go-configmap/cli.go @@ -0,0 +1,111 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap + +import ( + "fmt" + "strconv" + "strings" +) + +func (c *Map) SetFromCLIArgs(key string, args ...string) error { + if len(args) == 0 { + c.Delete(key) + return nil + } + + // in case of schemaless configuration, we don't know the type of the setting + // we will save it as a string or array of strings + if len(c.schema) == 0 { + switch len(args) { + case 1: + c.Set(key, args[0]) + default: + c.Set(key, args) + } + return nil + } + + // Find the correct type for the given setting + valueType, ok := c.schema[key] + if !ok { + return fmt.Errorf("key not found: %s", key) + } + + var value any + isArray := false + { + var conversionError error + switch valueType.String() { + case "uint": + value, conversionError = strconv.Atoi(args[0]) + case "bool": + value, conversionError = strconv.ParseBool(args[0]) + case "string": + value = args[0] + case "[]string": + value = args + isArray = true + default: + return fmt.Errorf("unhandled type: %s", valueType) + } + if conversionError != nil { + return fmt.Errorf("error setting value: %v", conversionError) + } + } + if !isArray && len(args) != 1 { + return fmt.Errorf("error setting value: key is not an array, but multiple values were provided") + } + + return c.Set(key, value) +} + +func (c *Map) InjectEnvVars(env []string, prefix string) []error { + if prefix != "" { + prefix = strings.ToUpper(prefix) + "_" + } + + errs := []error{} + + envKeyToConfigKey := map[string]string{} + for _, k := range c.AllKeys() { + normalizedKey := prefix + strings.ToUpper(k) + normalizedKey = strings.Replace(normalizedKey, ".", "_", -1) + envKeyToConfigKey[normalizedKey] = k + } + + for _, e := range env { + // Extract key and value from env + parts := strings.SplitN(e, "=", 2) + if len(parts) != 2 { + continue + } + envKey := strings.ToUpper(parts[0]) + envValue := parts[1] + + // Check if the configuration has a matching key + key, ok := envKeyToConfigKey[envKey] + if !ok { + continue + } + + // Update the configuration value + if err := c.SetFromCLIArgs(key, envValue); err != nil { + errs = append(errs, err) + } + } + return errs +} diff --git a/internal/go-configmap/configuration.go b/internal/go-configmap/configuration.go new file mode 100644 index 00000000000..fa504a272bd --- /dev/null +++ b/internal/go-configmap/configuration.go @@ -0,0 +1,212 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap + +import ( + "fmt" + "reflect" + "strings" +) + +type Map struct { + values map[string]any + schema map[string]reflect.Type +} + +func New() *Map { + return &Map{ + values: make(map[string]any), + schema: make(map[string]reflect.Type), + } +} + +func (c Map) Get(key string) any { + value, _ := c.GetOk(key) + return value +} + +func (c Map) GetOk(key string) (any, bool) { + keys := strings.Split(key, ".") + return c.get(keys) +} + +func (c Map) get(keys []string) (any, bool) { + if len(keys) == 0 { + return nil, false + } + value, ok := c.values[keys[0]] + if len(keys) == 1 { + return value, ok + } + + if subConf, ok := value.(*Map); ok { + return subConf.get(keys[1:]) + } + return nil, false +} + +func (c Map) Set(key string, value any) error { + if len(c.schema) > 0 { + t, ok := c.schema[key] + if !ok { + return fmt.Errorf("schema not defined for key '%s'", key) + } + newValue, err := tryConversion(value, t) + if err != nil { + return fmt.Errorf("invalid type for key '%s': %w", key, err) + } + value = newValue + } + keys := strings.Split(key, ".") + c.set(keys, value) + return nil +} + +func tryConversion(current any, desiredType reflect.Type) (any, error) { + currentType := reflect.TypeOf(current) + if currentType == desiredType { + return current, nil + } + + switch desiredType.Kind() { + case reflect.Uint: + // Exception for JSON decoder: json decoder will decode all numbers as float64 + if currentFloat, ok := current.(float64); ok { + return uint(currentFloat), nil + } + if currentInt, ok := current.(int); ok { + return uint(currentInt), nil + } + case reflect.Int: + // Exception for JSON decoder: json decoder will decode all numbers as float64 + if currentFloat, ok := current.(float64); ok { + return int(currentFloat), nil + } + case reflect.Array, reflect.Slice: + currentArray, ok := current.([]any) + if !ok { + break + } + for i, elem := range currentArray { + newElem, err := tryConversion(elem, desiredType.Elem()) + if err != nil { + return nil, err + } + currentArray[i] = newElem + } + return currentArray, nil + } + return nil, fmt.Errorf("invalid conversion, got %T but want %v", current, desiredType) +} + +func (c Map) set(keys []string, value any) { + if len(keys) == 0 { + return + } + if len(keys) == 1 { + c.values[keys[0]] = value + return + } + + var subConf *Map + if subValue, ok := c.values[keys[0]]; !ok { + subConf = New() + c.values[keys[0]] = subConf + } else if conf, ok := subValue.(*Map); !ok { + subConf = New() + c.values[keys[0]] = subConf + } else { + subConf = conf + } + subConf.set(keys[1:], value) +} + +func (c Map) Delete(key string) { + keys := strings.Split(key, ".") + c.delete(keys) +} + +func (c Map) delete(keys []string) { + if len(keys) == 0 { + return + } + if len(keys) == 1 { + delete(c.values, keys[0]) + return + } + + if subValue, ok := c.values[keys[0]]; !ok { + return + } else if subConf, ok := subValue.(*Map); !ok { + return + } else { + subConf.delete(keys[1:]) + } +} + +func (c *Map) Merge(x *Map) error { + for xk, xv := range x.values { + if xSubConf, ok := xv.(*Map); ok { + if subConf, ok := c.values[xk].(*Map); ok { + if err := subConf.Merge(xSubConf); err != nil { + return err + } + continue + } + return fmt.Errorf("cannot merge sub-configuration into non sub-configuration: '%s'", xk) + } + + v, ok := c.values[xk] + if !ok { + return fmt.Errorf("target key do not exist: '%s'", xk) + } + if reflect.TypeOf(v) != reflect.TypeOf(xv) { + return fmt.Errorf("invalid types for key '%s': got %T but want %T", xk, v, xv) + } + c.values[xk] = xv + } + return nil +} + +func (c *Map) AllKeys() []string { + return c.allKeys("") +} + +func (c *Map) Schema() map[string]reflect.Type { + return c.schema +} + +func (c *Map) allKeys(prefix string) []string { + keys := []string{} + if len(c.schema) > 0 { + for k := range c.schema { + keys = append(keys, prefix+k) + } + } else { + for k, v := range c.values { + if subConf, ok := v.(*Map); ok { + keys = append(keys, subConf.allKeys(prefix+k+".")...) + } else { + keys = append(keys, prefix+k) + } + } + } + return keys +} + +func (c *Map) SetKeyTypeSchema(key string, t any) { + c.schema[key] = reflect.TypeOf(t) +} diff --git a/internal/go-configmap/configuration_test.go b/internal/go-configmap/configuration_test.go new file mode 100644 index 00000000000..7c213d15a6c --- /dev/null +++ b/internal/go-configmap/configuration_test.go @@ -0,0 +1,168 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/arduino/arduino-cli/internal/go-configmap" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +func TestConfiguration(t *testing.T) { + c := configmap.New() + c.Set("foo", "bar") + c.Set("fooz.bar", "baz") + c.Set("answer", 42) + require.Equal(t, "bar", c.Get("foo")) + require.Equal(t, "baz", c.Get("fooz.bar")) + require.Equal(t, 42, c.Get("answer")) + + yml, err := yaml.Marshal(c) + require.NoError(t, err) + fmt.Println(string(yml)) + + d := configmap.New() + err = yaml.Unmarshal(yml, &d) + require.NoError(t, err) + + yml2, err := yaml.Marshal(d) + require.NoError(t, err) + require.Equal(t, string(yml), string(yml2)) + + d.Set("fooz.abc", "def") + d.Set("fooz.cde", "fgh") + require.Equal(t, "def", d.Get("fooz.abc")) + require.Equal(t, "fgh", d.Get("fooz.cde")) + d.Delete("fooz.abc") + require.Nil(t, d.Get("fooz.abc")) + require.Equal(t, "fgh", d.Get("fooz.cde")) + d.Delete("fooz") + require.Nil(t, d.Get("fooz.cde")) +} + +func TestYAMLCleanUpOfZeroValues(t *testing.T) { + inYml := []byte(` +foo: bar +directories: + builtins: {} +`) + c := configmap.New() + outYml1, err := yaml.Marshal(c) + require.NoError(t, err) + require.Equal(t, "{}\n", string(outYml1)) + + err = yaml.Unmarshal(inYml, &c) + require.NoError(t, err) + + outYml2, err := yaml.Marshal(c) + require.NoError(t, err) + require.Equal(t, "foo: bar\n", string(outYml2)) +} + +func TestApplyEnvVars(t *testing.T) { + c := configmap.New() + c.Set("foo", "bar") + c.Set("fooz.bar", "baz") + c.Set("answer", 42) + c.InjectEnvVars([]string{"APP_FOO=app-bar", "APP_FOOZ_BAR=app-baz"}, "APP") + require.Equal(t, "app-bar", c.Get("foo")) + require.Equal(t, "app-baz", c.Get("fooz.bar")) + require.Equal(t, 42, c.Get("answer")) +} + +func TestMerge(t *testing.T) { + c := configmap.New() + c.Set("foo", "bar") + c.Set("fooz.bar", "baz") + c.Set("answer", 42) + + d := configmap.New() + d.Set("answer", 24) + require.NoError(t, c.Merge(d)) + require.Equal(t, "bar", c.Get("foo")) + require.Equal(t, "baz", c.Get("fooz.bar")) + require.Equal(t, 24, c.Get("answer")) + + e := configmap.New() + e.Set("fooz.bar", "barz") + require.NoError(t, c.Merge(e)) + require.Equal(t, "bar", c.Get("foo")) + require.Equal(t, "barz", c.Get("fooz.bar")) + require.Equal(t, 24, c.Get("answer")) + + f := configmap.New() + f.Set("fooz.bar", 10) + require.Error(t, c.Merge(f)) + fmt.Println(c.Merge(f)) + + g := configmap.New() + g.Set("fooz.bart", "baz") + require.Error(t, c.Merge(g)) + fmt.Println(c.Merge(g)) +} + +func TestAllKeys(t *testing.T) { + { + c := configmap.New() + c.Set("foo", "bar") + c.Set("fooz.bar", "baz") + c.Set("answer", 42) + require.ElementsMatch(t, []string{"foo", "fooz.bar", "answer"}, c.AllKeys()) + } + { + inYml := []byte(` +foo: bar +dir: + a: yes + b: no + c: {} + d: + - 1 + - 2 +`) + c := configmap.New() + err := yaml.Unmarshal(inYml, &c) + require.NoError(t, err) + require.ElementsMatch(t, []string{"foo", "dir.a", "dir.b", "dir.d"}, c.AllKeys()) + } +} + +func TestSchema(t *testing.T) { + c := configmap.New() + c.SetKeyTypeSchema("string", "") + c.SetKeyTypeSchema("int", 15) + c.SetKeyTypeSchema("obj.string", "") + c.SetKeyTypeSchema("obj.int", 15) + require.NoError(t, c.Set("string", "abc")) + require.Error(t, c.Set("string", 123)) + require.NoError(t, c.Set("int", 123)) + require.Error(t, c.Set("int", "abc")) + require.Equal(t, "abc", c.Get("string")) + + json1 := []byte(`{"string":"abc","int":123,"obj":{"string":"abc","int":123}}`) + require.NoError(t, json.Unmarshal(json1, &c)) + require.Equal(t, "abc", c.Get("string")) + require.Equal(t, 123, c.Get("int")) + + json2 := []byte(`{"string":123,"int":123,"obj":{"string":"abc","int":123}}`) + require.Error(t, json.Unmarshal(json2, &c)) + json3 := []byte(`{"string":"avc","int":123,"obj":{"string":123,"int":123}}`) + require.Error(t, json.Unmarshal(json3, &c)) +} diff --git a/internal/go-configmap/json.go b/internal/go-configmap/json.go new file mode 100644 index 00000000000..7ab0deaad4f --- /dev/null +++ b/internal/go-configmap/json.go @@ -0,0 +1,52 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap + +import "encoding/json" + +func (c Map) MarshalJSON() ([]byte, error) { + return json.Marshal(c.values) +} + +func (c *Map) UnmarshalJSON(data []byte) error { + in := map[string]any{} + if err := json.Unmarshal(data, &in); err != nil { + return err + } + + c.values = map[string]any{} + for k, v := range flattenMap(in) { + if err := c.Set(k, v); err != nil { + return err + } + } + return nil +} + +func flattenMap(in map[string]any) map[string]any { + out := map[string]any{} + for k, v := range in { + switch v := v.(type) { + case map[string]any: + for kk, vv := range flattenMap(v) { + out[k+"."+kk] = vv + } + default: + out[k] = v + } + } + return out +} diff --git a/internal/go-configmap/json_test.go b/internal/go-configmap/json_test.go new file mode 100644 index 00000000000..54566589baf --- /dev/null +++ b/internal/go-configmap/json_test.go @@ -0,0 +1,48 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap_test + +import ( + "encoding/json" + "fmt" + "testing" + + "github.com/arduino/arduino-cli/internal/go-configmap" + "github.com/stretchr/testify/require" +) + +func TestJson(t *testing.T) { + c := configmap.New() + c.Set("foo", "bar") + c.Set("fooz.bar", "baz") + c.Set("answer", 42) + require.Equal(t, "bar", c.Get("foo")) + require.Equal(t, "baz", c.Get("fooz.bar")) + require.Equal(t, 42, c.Get("answer")) + + j1, err := json.Marshal(c) + require.NoError(t, err) + fmt.Println(string(j1)) + + d := configmap.New() + err = json.Unmarshal(j1, d) + require.NoError(t, err) + require.Equal(t, "baz", d.Get("fooz.bar")) + + j2, err := json.Marshal(d) + require.NoError(t, err) + require.Equal(t, string(j1), string(j2)) +} diff --git a/internal/go-configmap/types.go b/internal/go-configmap/types.go new file mode 100644 index 00000000000..d6a032b8dd6 --- /dev/null +++ b/internal/go-configmap/types.go @@ -0,0 +1,215 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap + +import ( + "errors" + "fmt" + "time" +) + +func (c Map) GetStringOk(key string) (string, bool, error) { + v, ok := c.GetOk(key) + if !ok { + return "", false, nil + } + if s, ok := v.(string); ok { + return s, true, nil + } + return "", false, errors.New(key + " is not a string") +} + +func (c Map) GetString(key string) string { + v, ok, err := c.GetStringOk(key) + if err != nil { + panic(err.Error()) + } + if ok { + return v + } + return "" +} + +func (c Map) SetString(key string, value string) { + c.Set(key, value) +} + +func (c Map) GetBoolOk(key string) (bool, bool, error) { + v, ok := c.GetOk(key) + if !ok { + return false, false, nil + } + if b, ok := v.(bool); ok { + return b, true, nil + } + return false, false, errors.New(key + " is not a bool") +} + +func (c Map) GetBool(key string) bool { + v, ok, err := c.GetBoolOk(key) + if err != nil { + panic(err.Error()) + } + if ok { + return v + } + return false +} + +func (c Map) SetBool(key string, value bool) { + c.Set(key, value) +} + +func (c Map) GetUintOk(key string) (uint, bool, error) { + v, ok := c.GetOk(key) + if !ok { + return 0, false, nil + } + if i, ok := v.(uint); ok { + return i, true, nil + } + return 0, false, errors.New(key + " is not a uint") +} + +func (c Map) GetUint(key string) uint { + v, ok, err := c.GetUintOk(key) + if err != nil { + panic(err.Error()) + } + if ok { + return v + } + return 0 +} + +func (c Map) SetUint(key string, value uint) { + c.Set(key, value) +} + +func (c Map) GetIntOk(key string) (int, bool, error) { + v, ok := c.GetOk(key) + if !ok { + return 0, false, nil + } + if i, ok := v.(int); ok { + return i, true, nil + } + return 0, false, errors.New(key + " is not a uint") +} + +func (c Map) GetInt(key string) int { + v, ok, err := c.GetIntOk(key) + if err != nil { + panic(err.Error()) + } + if ok { + return v + } + return 0 +} + +func (c Map) SetInt(key string, value int) { + c.Set(key, value) +} + +func (c Map) GetUint32Ok(key string) (uint32, bool, error) { + v, ok := c.GetOk(key) + if !ok { + return 0, false, nil + } + if i, ok := v.(uint32); ok { + return i, true, nil + } + return 0, false, errors.New(key + " is not a uint32") +} + +func (c Map) GetUint32(key string) uint32 { + v, ok, err := c.GetUint32Ok(key) + if err != nil { + panic(err.Error()) + } + if ok { + return v + } + return 0 +} + +func (c Map) SetUint32(key string, value uint32) { + c.Set(key, value) +} + +func (c Map) GetStringSliceOk(key string) ([]string, bool, error) { + v, ok := c.GetOk(key) + if !ok { + return nil, false, nil + } + if genArray, ok := v.([]string); ok { + return genArray, true, nil + } + if genArray, ok := v.([]interface{}); ok { + // transform []interface{} to []string + var strArray []string + for i, gen := range genArray { + if str, ok := gen.(string); ok { + strArray = append(strArray, str) + } else { + return nil, false, fmt.Errorf("%s[%d] is not a string", key, i) + } + } + return strArray, true, nil + } + return nil, false, fmt.Errorf("%s is not an array of strings", key) +} + +func (c Map) GetStringSlice(key string) []string { + v, ok, err := c.GetStringSliceOk(key) + if err != nil { + panic(err.Error()) + } + if ok { + return v + } + return nil +} + +func (c Map) GetDurationOk(key string) (time.Duration, bool, error) { + v, ok := c.GetOk(key) + if !ok { + return 0, false, nil + } + if s, ok := v.(string); !ok { + return 0, false, errors.New(key + " is not a Duration") + } else if d, err := time.ParseDuration(s); err != nil { + return 0, false, fmt.Errorf("%s is not a valid Duration: %w", key, err) + } else { + return d, true, nil + } +} + +func (c Map) GetDuration(key string) time.Duration { + v, ok, err := c.GetDurationOk(key) + if err != nil { + panic(err.Error()) + } + if ok { + return v + } + return 0 +} + +func (c Map) SetDuration(key string, value time.Duration) { + c.SetString(key, value.String()) +} diff --git a/internal/go-configmap/yaml.go b/internal/go-configmap/yaml.go new file mode 100644 index 00000000000..214e12ba727 --- /dev/null +++ b/internal/go-configmap/yaml.go @@ -0,0 +1,38 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap + +import ( + "gopkg.in/yaml.v3" +) + +func (c Map) MarshalYAML() (interface{}, error) { + return c.values, nil +} + +func (c *Map) UnmarshalYAML(node *yaml.Node) error { + in := map[string]any{} + if err := node.Decode(&in); err != nil { + return err + } + + for k, v := range flattenMap(in) { + if err := c.Set(k, v); err != nil { + return err + } + } + return nil +} diff --git a/internal/go-configmap/yaml_test.go b/internal/go-configmap/yaml_test.go new file mode 100644 index 00000000000..9293f70662f --- /dev/null +++ b/internal/go-configmap/yaml_test.go @@ -0,0 +1,48 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap_test + +import ( + "fmt" + "testing" + + "github.com/arduino/arduino-cli/internal/go-configmap" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +func TestYaml(t *testing.T) { + c := configmap.New() + c.Set("foo", "bar") + c.Set("fooz.bar", "baz") + c.Set("answer", 42) + require.Equal(t, "bar", c.Get("foo")) + require.Equal(t, "baz", c.Get("fooz.bar")) + require.Equal(t, 42, c.Get("answer")) + + y1, err := yaml.Marshal(c) + require.NoError(t, err) + fmt.Println(string(y1)) + + d := configmap.New() + err = yaml.Unmarshal(y1, d) + require.NoError(t, err) + require.Equal(t, "baz", d.Get("fooz.bar")) + + y2, err := yaml.Marshal(d) + require.NoError(t, err) + require.Equal(t, string(y1), string(y2)) +} diff --git a/internal/integrationtest/arduino-cli.go b/internal/integrationtest/arduino-cli.go index 7e2ff315f98..0e795f64d26 100644 --- a/internal/integrationtest/arduino-cli.go +++ b/internal/integrationtest/arduino-cli.go @@ -326,7 +326,7 @@ func (cli *ArduinoCLI) run(stdoutBuff, stderrBuff io.Writer, stdinBuff io.Reader defer fmt.Fprintln(terminalOut, "::endgroup::") } - fmt.Fprintln(terminalOut, color.HiBlackString(">>> Running: ")+color.HiYellowString("%s %s", cli.path, strings.Join(args, " "))) + fmt.Fprintln(terminalOut, color.HiBlackString(">>> Running: ")+color.HiYellowString("%s %s %s", cli.path, strings.Join(args, " "), env)) cliProc, err := paths.NewProcessFromPath(cli.convertEnvForExecutils(env), cli.path, args...) cli.t.NoError(err) stdout, err := cliProc.StdoutPipe() @@ -444,8 +444,8 @@ func (cli *ArduinoCLI) Create() *ArduinoCLIInstance { // SetValue calls the "SetValue" gRPC method. func (cli *ArduinoCLI) SetValue(key, jsonData string) error { req := &commands.SettingsSetValueRequest{ - Key: key, - JsonData: jsonData, + Key: key, + EncodedValue: jsonData, } logCallf(">>> SetValue(%+v)\n", req) _, err := cli.daemonClient.SettingsSetValue(context.Background(), req) diff --git a/internal/integrationtest/compile_1/compile_test.go b/internal/integrationtest/compile_1/compile_test.go index 6d6dd605602..27b31cb82c1 100644 --- a/internal/integrationtest/compile_1/compile_test.go +++ b/internal/integrationtest/compile_1/compile_test.go @@ -522,7 +522,7 @@ func compileWithExportBinariesConfig(t *testing.T, env *integrationtest.Environm { "config": { "sketch": { - "always_export_binaries": "true" + "always_export_binaries": true } } }`) diff --git a/main.go b/main.go index 2255ae626b4..56c58ea36d5 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,8 @@ package main import ( + "context" + "fmt" "os" "github.com/arduino/arduino-cli/commands" @@ -23,17 +25,45 @@ import ( "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/i18n" - "github.com/arduino/arduino-cli/version" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "github.com/arduino/go-paths-helper" ) func main() { - defaultSettings := configuration.Init(configuration.FindConfigFileInArgsFallbackOnEnv(os.Args)) - i18n.Init(defaultSettings.GetString("locale")) + // Create a new ArduinoCoreServer + srv := commands.NewArduinoCoreServer() - srv := commands.NewArduinoCoreServer(version.VersionInfo.VersionString, defaultSettings) + // Search for the configuration file in the command line arguments and in the environment + configFile := configuration.FindConfigFileInArgsFallbackOnEnv(os.Args) + ctx := context.Background() + ctx = context.WithValue(ctx, "config_file", configFile) - arduinoCmd := cli.NewCommand(srv, defaultSettings) - if err := arduinoCmd.Execute(); err != nil { + // Read the settings from the configuration file + openReq := &rpc.ConfigurationOpenRequest{SettingsFormat: "yaml"} + if configData, err := paths.New(configFile).ReadFile(); err == nil { + openReq.EncodedSettings = string(configData) + } else if !os.IsNotExist(err) { + feedback.FatalError(fmt.Errorf("couldn't read configuration file: %w", err), feedback.ErrGeneric) + } + if _, err := srv.ConfigurationOpen(ctx, openReq); err != nil { + feedback.FatalError(fmt.Errorf("couldn't load configuration: %w", err), feedback.ErrGeneric) + } + + // Get the current settings from the server + resp, err := srv.ConfigurationGet(ctx, &rpc.ConfigurationGetRequest{}) + if err != nil { + feedback.FatalError(err, feedback.ErrGeneric) + } + config := resp.GetConfiguration() + + // Setup i18n + i18n.Init(config.GetLocale()) + + // Setup command line parser with the server and settings + arduinoCmd := cli.NewCommand(srv) + + // Execute the command line + if err := arduinoCmd.ExecuteContext(ctx); err != nil { feedback.FatalError(err, feedback.ErrGeneric) } } diff --git a/rpc/cc/arduino/cli/commands/v1/commands.pb.go b/rpc/cc/arduino/cli/commands/v1/commands.pb.go index ca33b869446..859a2bf0900 100644 --- a/rpc/cc/arduino/cli/commands/v1/commands.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/commands.pb.go @@ -2076,7 +2076,7 @@ var file_cc_arduino_cli_commands_v1_commands_proto_rawDesc = []byte{ 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x03, 0x12, 0x34, 0x0a, 0x30, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x49, 0x4e, 0x44, 0x45, 0x58, 0x5f, 0x44, 0x4f, 0x57, - 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x32, 0xd1, 0x2f, + 0x4e, 0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x32, 0xfb, 0x2f, 0x0a, 0x12, 0x41, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x43, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x61, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, @@ -2412,58 +2412,60 @@ var file_cc_arduino_cli_commands_v1_commands_proto_rawDesc = []byte{ 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x61, 0x63, 0x68, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x73, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x12, 0x31, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, - 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x74, - 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x12, - 0x30, 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, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x73, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2e, 0x63, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x61, 0x76, 0x65, 0x12, 0x34, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x35, 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, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x61, 0x76, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x34, + 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, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x65, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x10, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x65, 0x74, 0x12, + 0x33, 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, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x11, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x12, 0x34, 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, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, + 0x10, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x33, 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, 0x53, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x33, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 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, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, - 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x33, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, - 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x74, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x57, 0x72, - 0x69, 0x74, 0x65, 0x12, 0x30, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x63, 0x63, 0x2e, 0x61, 0x72, 0x64, 0x75, 0x69, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x10, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x33, 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, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x31, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 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, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 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, + 0x76, 0x31, 0x2e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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 ( @@ -2549,12 +2551,12 @@ var file_cc_arduino_cli_commands_v1_commands_proto_goTypes = []interface{}{ (*DebugRequest)(nil), // 65: cc.arduino.cli.commands.v1.DebugRequest (*IsDebugSupportedRequest)(nil), // 66: cc.arduino.cli.commands.v1.IsDebugSupportedRequest (*GetDebugConfigRequest)(nil), // 67: cc.arduino.cli.commands.v1.GetDebugConfigRequest - (*SettingsGetAllRequest)(nil), // 68: cc.arduino.cli.commands.v1.SettingsGetAllRequest - (*SettingsMergeRequest)(nil), // 69: cc.arduino.cli.commands.v1.SettingsMergeRequest - (*SettingsGetValueRequest)(nil), // 70: cc.arduino.cli.commands.v1.SettingsGetValueRequest - (*SettingsSetValueRequest)(nil), // 71: cc.arduino.cli.commands.v1.SettingsSetValueRequest - (*SettingsWriteRequest)(nil), // 72: cc.arduino.cli.commands.v1.SettingsWriteRequest - (*SettingsDeleteRequest)(nil), // 73: cc.arduino.cli.commands.v1.SettingsDeleteRequest + (*ConfigurationSaveRequest)(nil), // 68: cc.arduino.cli.commands.v1.ConfigurationSaveRequest + (*ConfigurationOpenRequest)(nil), // 69: cc.arduino.cli.commands.v1.ConfigurationOpenRequest + (*ConfigurationGetRequest)(nil), // 70: cc.arduino.cli.commands.v1.ConfigurationGetRequest + (*SettingsEnumerateRequest)(nil), // 71: cc.arduino.cli.commands.v1.SettingsEnumerateRequest + (*SettingsGetValueRequest)(nil), // 72: cc.arduino.cli.commands.v1.SettingsGetValueRequest + (*SettingsSetValueRequest)(nil), // 73: cc.arduino.cli.commands.v1.SettingsSetValueRequest (*BoardDetailsResponse)(nil), // 74: cc.arduino.cli.commands.v1.BoardDetailsResponse (*BoardListResponse)(nil), // 75: cc.arduino.cli.commands.v1.BoardListResponse (*BoardListAllResponse)(nil), // 76: cc.arduino.cli.commands.v1.BoardListAllResponse @@ -2586,12 +2588,12 @@ var file_cc_arduino_cli_commands_v1_commands_proto_goTypes = []interface{}{ (*DebugResponse)(nil), // 102: cc.arduino.cli.commands.v1.DebugResponse (*IsDebugSupportedResponse)(nil), // 103: cc.arduino.cli.commands.v1.IsDebugSupportedResponse (*GetDebugConfigResponse)(nil), // 104: cc.arduino.cli.commands.v1.GetDebugConfigResponse - (*SettingsGetAllResponse)(nil), // 105: cc.arduino.cli.commands.v1.SettingsGetAllResponse - (*SettingsMergeResponse)(nil), // 106: cc.arduino.cli.commands.v1.SettingsMergeResponse - (*SettingsGetValueResponse)(nil), // 107: cc.arduino.cli.commands.v1.SettingsGetValueResponse - (*SettingsSetValueResponse)(nil), // 108: cc.arduino.cli.commands.v1.SettingsSetValueResponse - (*SettingsWriteResponse)(nil), // 109: cc.arduino.cli.commands.v1.SettingsWriteResponse - (*SettingsDeleteResponse)(nil), // 110: cc.arduino.cli.commands.v1.SettingsDeleteResponse + (*ConfigurationSaveResponse)(nil), // 105: cc.arduino.cli.commands.v1.ConfigurationSaveResponse + (*ConfigurationOpenResponse)(nil), // 106: cc.arduino.cli.commands.v1.ConfigurationOpenResponse + (*ConfigurationGetResponse)(nil), // 107: cc.arduino.cli.commands.v1.ConfigurationGetResponse + (*SettingsEnumerateResponse)(nil), // 108: cc.arduino.cli.commands.v1.SettingsEnumerateResponse + (*SettingsGetValueResponse)(nil), // 109: cc.arduino.cli.commands.v1.SettingsGetValueResponse + (*SettingsSetValueResponse)(nil), // 110: cc.arduino.cli.commands.v1.SettingsSetValueResponse } var file_cc_arduino_cli_commands_v1_commands_proto_depIdxs = []int32{ 31, // 0: cc.arduino.cli.commands.v1.CreateResponse.instance:type_name -> cc.arduino.cli.commands.v1.Instance @@ -2657,12 +2659,12 @@ var file_cc_arduino_cli_commands_v1_commands_proto_depIdxs = []int32{ 67, // 60: cc.arduino.cli.commands.v1.ArduinoCoreService.GetDebugConfig:input_type -> cc.arduino.cli.commands.v1.GetDebugConfigRequest 24, // 61: cc.arduino.cli.commands.v1.ArduinoCoreService.CheckForArduinoCLIUpdates:input_type -> cc.arduino.cli.commands.v1.CheckForArduinoCLIUpdatesRequest 26, // 62: cc.arduino.cli.commands.v1.ArduinoCoreService.CleanDownloadCacheDirectory:input_type -> cc.arduino.cli.commands.v1.CleanDownloadCacheDirectoryRequest - 68, // 63: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsGetAll:input_type -> cc.arduino.cli.commands.v1.SettingsGetAllRequest - 69, // 64: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsMerge:input_type -> cc.arduino.cli.commands.v1.SettingsMergeRequest - 70, // 65: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsGetValue:input_type -> cc.arduino.cli.commands.v1.SettingsGetValueRequest - 71, // 66: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsSetValue:input_type -> cc.arduino.cli.commands.v1.SettingsSetValueRequest - 72, // 67: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsWrite:input_type -> cc.arduino.cli.commands.v1.SettingsWriteRequest - 73, // 68: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsDelete:input_type -> cc.arduino.cli.commands.v1.SettingsDeleteRequest + 68, // 63: cc.arduino.cli.commands.v1.ArduinoCoreService.ConfigurationSave:input_type -> cc.arduino.cli.commands.v1.ConfigurationSaveRequest + 69, // 64: cc.arduino.cli.commands.v1.ArduinoCoreService.ConfigurationOpen:input_type -> cc.arduino.cli.commands.v1.ConfigurationOpenRequest + 70, // 65: cc.arduino.cli.commands.v1.ArduinoCoreService.ConfigurationGet:input_type -> cc.arduino.cli.commands.v1.ConfigurationGetRequest + 71, // 66: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsEnumerate:input_type -> cc.arduino.cli.commands.v1.SettingsEnumerateRequest + 72, // 67: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsGetValue:input_type -> cc.arduino.cli.commands.v1.SettingsGetValueRequest + 73, // 68: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsSetValue:input_type -> cc.arduino.cli.commands.v1.SettingsSetValueRequest 3, // 69: cc.arduino.cli.commands.v1.ArduinoCoreService.Create:output_type -> cc.arduino.cli.commands.v1.CreateResponse 5, // 70: cc.arduino.cli.commands.v1.ArduinoCoreService.Init:output_type -> cc.arduino.cli.commands.v1.InitResponse 8, // 71: cc.arduino.cli.commands.v1.ArduinoCoreService.Destroy:output_type -> cc.arduino.cli.commands.v1.DestroyResponse @@ -2706,12 +2708,12 @@ var file_cc_arduino_cli_commands_v1_commands_proto_depIdxs = []int32{ 104, // 109: cc.arduino.cli.commands.v1.ArduinoCoreService.GetDebugConfig:output_type -> cc.arduino.cli.commands.v1.GetDebugConfigResponse 25, // 110: cc.arduino.cli.commands.v1.ArduinoCoreService.CheckForArduinoCLIUpdates:output_type -> cc.arduino.cli.commands.v1.CheckForArduinoCLIUpdatesResponse 27, // 111: cc.arduino.cli.commands.v1.ArduinoCoreService.CleanDownloadCacheDirectory:output_type -> cc.arduino.cli.commands.v1.CleanDownloadCacheDirectoryResponse - 105, // 112: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsGetAll:output_type -> cc.arduino.cli.commands.v1.SettingsGetAllResponse - 106, // 113: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsMerge:output_type -> cc.arduino.cli.commands.v1.SettingsMergeResponse - 107, // 114: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsGetValue:output_type -> cc.arduino.cli.commands.v1.SettingsGetValueResponse - 108, // 115: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsSetValue:output_type -> cc.arduino.cli.commands.v1.SettingsSetValueResponse - 109, // 116: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsWrite:output_type -> cc.arduino.cli.commands.v1.SettingsWriteResponse - 110, // 117: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsDelete:output_type -> cc.arduino.cli.commands.v1.SettingsDeleteResponse + 105, // 112: cc.arduino.cli.commands.v1.ArduinoCoreService.ConfigurationSave:output_type -> cc.arduino.cli.commands.v1.ConfigurationSaveResponse + 106, // 113: cc.arduino.cli.commands.v1.ArduinoCoreService.ConfigurationOpen:output_type -> cc.arduino.cli.commands.v1.ConfigurationOpenResponse + 107, // 114: cc.arduino.cli.commands.v1.ArduinoCoreService.ConfigurationGet:output_type -> cc.arduino.cli.commands.v1.ConfigurationGetResponse + 108, // 115: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsEnumerate:output_type -> cc.arduino.cli.commands.v1.SettingsEnumerateResponse + 109, // 116: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsGetValue:output_type -> cc.arduino.cli.commands.v1.SettingsGetValueResponse + 110, // 117: cc.arduino.cli.commands.v1.ArduinoCoreService.SettingsSetValue:output_type -> cc.arduino.cli.commands.v1.SettingsSetValueResponse 69, // [69:118] is the sub-list for method output_type 20, // [20:69] is the sub-list for method input_type 20, // [20:20] is the sub-list for extension type_name diff --git a/rpc/cc/arduino/cli/commands/v1/commands.proto b/rpc/cc/arduino/cli/commands/v1/commands.proto index 78660e28d5c..ce5aba9ed91 100644 --- a/rpc/cc/arduino/cli/commands/v1/commands.proto +++ b/rpc/cc/arduino/cli/commands/v1/commands.proto @@ -197,25 +197,28 @@ service ArduinoCoreService { rpc CleanDownloadCacheDirectory(CleanDownloadCacheDirectoryRequest) returns (CleanDownloadCacheDirectoryResponse); - // List all the settings. - rpc SettingsGetAll(SettingsGetAllRequest) returns (SettingsGetAllResponse); + // Writes the settings currently stored in memory in a YAML file + rpc ConfigurationSave(ConfigurationSaveRequest) + returns (ConfigurationSaveResponse); - // Set multiple settings values at once. - rpc SettingsMerge(SettingsMergeRequest) returns (SettingsMergeResponse); + // Read the settings from a YAML file + rpc ConfigurationOpen(ConfigurationOpenRequest) + returns (ConfigurationOpenResponse); - // Get the value of a specific setting. + rpc ConfigurationGet(ConfigurationGetRequest) + returns (ConfigurationGetResponse); + + // Enumerate all the keys/values pairs available in the configuration + rpc SettingsEnumerate(SettingsEnumerateRequest) + returns (SettingsEnumerateResponse); + + // Get a single configuration value rpc SettingsGetValue(SettingsGetValueRequest) returns (SettingsGetValueResponse); - // Set the value of a specific setting. + // Set a single configuration value rpc SettingsSetValue(SettingsSetValueRequest) returns (SettingsSetValueResponse); - - // Writes to file settings currently stored in memory - rpc SettingsWrite(SettingsWriteRequest) returns (SettingsWriteResponse); - - // Deletes an entry and rewrites the file settings - rpc SettingsDelete(SettingsDeleteRequest) returns (SettingsDeleteResponse); } message CreateRequest {} 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 5021e89d488..4ebd93a59f0 100644 --- a/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/commands_grpc.pb.go @@ -77,12 +77,12 @@ const ( ArduinoCoreService_GetDebugConfig_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/GetDebugConfig" ArduinoCoreService_CheckForArduinoCLIUpdates_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/CheckForArduinoCLIUpdates" ArduinoCoreService_CleanDownloadCacheDirectory_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/CleanDownloadCacheDirectory" - ArduinoCoreService_SettingsGetAll_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsGetAll" - ArduinoCoreService_SettingsMerge_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsMerge" + ArduinoCoreService_ConfigurationSave_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/ConfigurationSave" + ArduinoCoreService_ConfigurationOpen_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/ConfigurationOpen" + ArduinoCoreService_ConfigurationGet_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/ConfigurationGet" + ArduinoCoreService_SettingsEnumerate_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsEnumerate" ArduinoCoreService_SettingsGetValue_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsGetValue" ArduinoCoreService_SettingsSetValue_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsSetValue" - ArduinoCoreService_SettingsWrite_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsWrite" - ArduinoCoreService_SettingsDelete_FullMethodName = "/cc.arduino.cli.commands.v1.ArduinoCoreService/SettingsDelete" ) // ArduinoCoreServiceClient is the client API for ArduinoCoreService service. @@ -183,18 +183,17 @@ type ArduinoCoreServiceClient interface { CheckForArduinoCLIUpdates(ctx context.Context, in *CheckForArduinoCLIUpdatesRequest, opts ...grpc.CallOption) (*CheckForArduinoCLIUpdatesResponse, error) // Clean the download cache directory (where archives are downloaded). CleanDownloadCacheDirectory(ctx context.Context, in *CleanDownloadCacheDirectoryRequest, opts ...grpc.CallOption) (*CleanDownloadCacheDirectoryResponse, error) - // List all the settings. - SettingsGetAll(ctx context.Context, in *SettingsGetAllRequest, opts ...grpc.CallOption) (*SettingsGetAllResponse, error) - // Set multiple settings values at once. - SettingsMerge(ctx context.Context, in *SettingsMergeRequest, opts ...grpc.CallOption) (*SettingsMergeResponse, error) - // Get the value of a specific setting. + // Writes the settings currently stored in memory in a YAML file + ConfigurationSave(ctx context.Context, in *ConfigurationSaveRequest, opts ...grpc.CallOption) (*ConfigurationSaveResponse, error) + // Read the settings from a YAML file + ConfigurationOpen(ctx context.Context, in *ConfigurationOpenRequest, opts ...grpc.CallOption) (*ConfigurationOpenResponse, error) + ConfigurationGet(ctx context.Context, in *ConfigurationGetRequest, opts ...grpc.CallOption) (*ConfigurationGetResponse, error) + // Enumerate all the keys/values pairs available in the configuration + SettingsEnumerate(ctx context.Context, in *SettingsEnumerateRequest, opts ...grpc.CallOption) (*SettingsEnumerateResponse, error) + // Get a single configuration value SettingsGetValue(ctx context.Context, in *SettingsGetValueRequest, opts ...grpc.CallOption) (*SettingsGetValueResponse, error) - // Set the value of a specific setting. + // Set a single configuration value SettingsSetValue(ctx context.Context, in *SettingsSetValueRequest, opts ...grpc.CallOption) (*SettingsSetValueResponse, error) - // Writes to file settings currently stored in memory - SettingsWrite(ctx context.Context, in *SettingsWriteRequest, opts ...grpc.CallOption) (*SettingsWriteResponse, error) - // Deletes an entry and rewrites the file settings - SettingsDelete(ctx context.Context, in *SettingsDeleteRequest, opts ...grpc.CallOption) (*SettingsDeleteResponse, error) } type arduinoCoreServiceClient struct { @@ -1073,54 +1072,54 @@ func (c *arduinoCoreServiceClient) CleanDownloadCacheDirectory(ctx context.Conte return out, nil } -func (c *arduinoCoreServiceClient) SettingsGetAll(ctx context.Context, in *SettingsGetAllRequest, opts ...grpc.CallOption) (*SettingsGetAllResponse, error) { - out := new(SettingsGetAllResponse) - err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsGetAll_FullMethodName, in, out, opts...) +func (c *arduinoCoreServiceClient) ConfigurationSave(ctx context.Context, in *ConfigurationSaveRequest, opts ...grpc.CallOption) (*ConfigurationSaveResponse, error) { + out := new(ConfigurationSaveResponse) + err := c.cc.Invoke(ctx, ArduinoCoreService_ConfigurationSave_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *arduinoCoreServiceClient) SettingsMerge(ctx context.Context, in *SettingsMergeRequest, opts ...grpc.CallOption) (*SettingsMergeResponse, error) { - out := new(SettingsMergeResponse) - err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsMerge_FullMethodName, in, out, opts...) +func (c *arduinoCoreServiceClient) ConfigurationOpen(ctx context.Context, in *ConfigurationOpenRequest, opts ...grpc.CallOption) (*ConfigurationOpenResponse, error) { + out := new(ConfigurationOpenResponse) + err := c.cc.Invoke(ctx, ArduinoCoreService_ConfigurationOpen_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *arduinoCoreServiceClient) SettingsGetValue(ctx context.Context, in *SettingsGetValueRequest, opts ...grpc.CallOption) (*SettingsGetValueResponse, error) { - out := new(SettingsGetValueResponse) - err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsGetValue_FullMethodName, in, out, opts...) +func (c *arduinoCoreServiceClient) ConfigurationGet(ctx context.Context, in *ConfigurationGetRequest, opts ...grpc.CallOption) (*ConfigurationGetResponse, error) { + out := new(ConfigurationGetResponse) + err := c.cc.Invoke(ctx, ArduinoCoreService_ConfigurationGet_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *arduinoCoreServiceClient) SettingsSetValue(ctx context.Context, in *SettingsSetValueRequest, opts ...grpc.CallOption) (*SettingsSetValueResponse, error) { - out := new(SettingsSetValueResponse) - err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsSetValue_FullMethodName, in, out, opts...) +func (c *arduinoCoreServiceClient) SettingsEnumerate(ctx context.Context, in *SettingsEnumerateRequest, opts ...grpc.CallOption) (*SettingsEnumerateResponse, error) { + out := new(SettingsEnumerateResponse) + err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsEnumerate_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *arduinoCoreServiceClient) SettingsWrite(ctx context.Context, in *SettingsWriteRequest, opts ...grpc.CallOption) (*SettingsWriteResponse, error) { - out := new(SettingsWriteResponse) - err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsWrite_FullMethodName, in, out, opts...) +func (c *arduinoCoreServiceClient) SettingsGetValue(ctx context.Context, in *SettingsGetValueRequest, opts ...grpc.CallOption) (*SettingsGetValueResponse, error) { + out := new(SettingsGetValueResponse) + err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsGetValue_FullMethodName, in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *arduinoCoreServiceClient) SettingsDelete(ctx context.Context, in *SettingsDeleteRequest, opts ...grpc.CallOption) (*SettingsDeleteResponse, error) { - out := new(SettingsDeleteResponse) - err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsDelete_FullMethodName, in, out, opts...) +func (c *arduinoCoreServiceClient) SettingsSetValue(ctx context.Context, in *SettingsSetValueRequest, opts ...grpc.CallOption) (*SettingsSetValueResponse, error) { + out := new(SettingsSetValueResponse) + err := c.cc.Invoke(ctx, ArduinoCoreService_SettingsSetValue_FullMethodName, in, out, opts...) if err != nil { return nil, err } @@ -1225,18 +1224,17 @@ type ArduinoCoreServiceServer interface { CheckForArduinoCLIUpdates(context.Context, *CheckForArduinoCLIUpdatesRequest) (*CheckForArduinoCLIUpdatesResponse, error) // Clean the download cache directory (where archives are downloaded). CleanDownloadCacheDirectory(context.Context, *CleanDownloadCacheDirectoryRequest) (*CleanDownloadCacheDirectoryResponse, error) - // List all the settings. - SettingsGetAll(context.Context, *SettingsGetAllRequest) (*SettingsGetAllResponse, error) - // Set multiple settings values at once. - SettingsMerge(context.Context, *SettingsMergeRequest) (*SettingsMergeResponse, error) - // Get the value of a specific setting. + // Writes the settings currently stored in memory in a YAML file + ConfigurationSave(context.Context, *ConfigurationSaveRequest) (*ConfigurationSaveResponse, error) + // Read the settings from a YAML file + ConfigurationOpen(context.Context, *ConfigurationOpenRequest) (*ConfigurationOpenResponse, error) + ConfigurationGet(context.Context, *ConfigurationGetRequest) (*ConfigurationGetResponse, error) + // Enumerate all the keys/values pairs available in the configuration + SettingsEnumerate(context.Context, *SettingsEnumerateRequest) (*SettingsEnumerateResponse, error) + // Get a single configuration value SettingsGetValue(context.Context, *SettingsGetValueRequest) (*SettingsGetValueResponse, error) - // Set the value of a specific setting. + // Set a single configuration value SettingsSetValue(context.Context, *SettingsSetValueRequest) (*SettingsSetValueResponse, error) - // Writes to file settings currently stored in memory - SettingsWrite(context.Context, *SettingsWriteRequest) (*SettingsWriteResponse, error) - // Deletes an entry and rewrites the file settings - SettingsDelete(context.Context, *SettingsDeleteRequest) (*SettingsDeleteResponse, error) mustEmbedUnimplementedArduinoCoreServiceServer() } @@ -1373,11 +1371,17 @@ func (UnimplementedArduinoCoreServiceServer) CheckForArduinoCLIUpdates(context.C func (UnimplementedArduinoCoreServiceServer) CleanDownloadCacheDirectory(context.Context, *CleanDownloadCacheDirectoryRequest) (*CleanDownloadCacheDirectoryResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CleanDownloadCacheDirectory not implemented") } -func (UnimplementedArduinoCoreServiceServer) SettingsGetAll(context.Context, *SettingsGetAllRequest) (*SettingsGetAllResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SettingsGetAll not implemented") +func (UnimplementedArduinoCoreServiceServer) ConfigurationSave(context.Context, *ConfigurationSaveRequest) (*ConfigurationSaveResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfigurationSave not implemented") +} +func (UnimplementedArduinoCoreServiceServer) ConfigurationOpen(context.Context, *ConfigurationOpenRequest) (*ConfigurationOpenResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfigurationOpen not implemented") +} +func (UnimplementedArduinoCoreServiceServer) ConfigurationGet(context.Context, *ConfigurationGetRequest) (*ConfigurationGetResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ConfigurationGet not implemented") } -func (UnimplementedArduinoCoreServiceServer) SettingsMerge(context.Context, *SettingsMergeRequest) (*SettingsMergeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SettingsMerge not implemented") +func (UnimplementedArduinoCoreServiceServer) SettingsEnumerate(context.Context, *SettingsEnumerateRequest) (*SettingsEnumerateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SettingsEnumerate not implemented") } func (UnimplementedArduinoCoreServiceServer) SettingsGetValue(context.Context, *SettingsGetValueRequest) (*SettingsGetValueResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SettingsGetValue not implemented") @@ -1385,12 +1389,6 @@ func (UnimplementedArduinoCoreServiceServer) SettingsGetValue(context.Context, * func (UnimplementedArduinoCoreServiceServer) SettingsSetValue(context.Context, *SettingsSetValueRequest) (*SettingsSetValueResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method SettingsSetValue not implemented") } -func (UnimplementedArduinoCoreServiceServer) SettingsWrite(context.Context, *SettingsWriteRequest) (*SettingsWriteResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SettingsWrite not implemented") -} -func (UnimplementedArduinoCoreServiceServer) SettingsDelete(context.Context, *SettingsDeleteRequest) (*SettingsDeleteResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SettingsDelete not implemented") -} func (UnimplementedArduinoCoreServiceServer) mustEmbedUnimplementedArduinoCoreServiceServer() {} // UnsafeArduinoCoreServiceServer may be embedded to opt out of forward compatibility for this service. @@ -2251,110 +2249,110 @@ func _ArduinoCoreService_CleanDownloadCacheDirectory_Handler(srv interface{}, ct return interceptor(ctx, in, info, handler) } -func _ArduinoCoreService_SettingsGetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SettingsGetAllRequest) +func _ArduinoCoreService_ConfigurationSave_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfigurationSaveRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ArduinoCoreServiceServer).SettingsGetAll(ctx, in) + return srv.(ArduinoCoreServiceServer).ConfigurationSave(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ArduinoCoreService_SettingsGetAll_FullMethodName, + FullMethod: ArduinoCoreService_ConfigurationSave_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArduinoCoreServiceServer).SettingsGetAll(ctx, req.(*SettingsGetAllRequest)) + return srv.(ArduinoCoreServiceServer).ConfigurationSave(ctx, req.(*ConfigurationSaveRequest)) } return interceptor(ctx, in, info, handler) } -func _ArduinoCoreService_SettingsMerge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SettingsMergeRequest) +func _ArduinoCoreService_ConfigurationOpen_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfigurationOpenRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ArduinoCoreServiceServer).SettingsMerge(ctx, in) + return srv.(ArduinoCoreServiceServer).ConfigurationOpen(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ArduinoCoreService_SettingsMerge_FullMethodName, + FullMethod: ArduinoCoreService_ConfigurationOpen_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArduinoCoreServiceServer).SettingsMerge(ctx, req.(*SettingsMergeRequest)) + return srv.(ArduinoCoreServiceServer).ConfigurationOpen(ctx, req.(*ConfigurationOpenRequest)) } return interceptor(ctx, in, info, handler) } -func _ArduinoCoreService_SettingsGetValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SettingsGetValueRequest) +func _ArduinoCoreService_ConfigurationGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfigurationGetRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ArduinoCoreServiceServer).SettingsGetValue(ctx, in) + return srv.(ArduinoCoreServiceServer).ConfigurationGet(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ArduinoCoreService_SettingsGetValue_FullMethodName, + FullMethod: ArduinoCoreService_ConfigurationGet_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArduinoCoreServiceServer).SettingsGetValue(ctx, req.(*SettingsGetValueRequest)) + return srv.(ArduinoCoreServiceServer).ConfigurationGet(ctx, req.(*ConfigurationGetRequest)) } return interceptor(ctx, in, info, handler) } -func _ArduinoCoreService_SettingsSetValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SettingsSetValueRequest) +func _ArduinoCoreService_SettingsEnumerate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SettingsEnumerateRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ArduinoCoreServiceServer).SettingsSetValue(ctx, in) + return srv.(ArduinoCoreServiceServer).SettingsEnumerate(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ArduinoCoreService_SettingsSetValue_FullMethodName, + FullMethod: ArduinoCoreService_SettingsEnumerate_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArduinoCoreServiceServer).SettingsSetValue(ctx, req.(*SettingsSetValueRequest)) + return srv.(ArduinoCoreServiceServer).SettingsEnumerate(ctx, req.(*SettingsEnumerateRequest)) } return interceptor(ctx, in, info, handler) } -func _ArduinoCoreService_SettingsWrite_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SettingsWriteRequest) +func _ArduinoCoreService_SettingsGetValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SettingsGetValueRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ArduinoCoreServiceServer).SettingsWrite(ctx, in) + return srv.(ArduinoCoreServiceServer).SettingsGetValue(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ArduinoCoreService_SettingsWrite_FullMethodName, + FullMethod: ArduinoCoreService_SettingsGetValue_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArduinoCoreServiceServer).SettingsWrite(ctx, req.(*SettingsWriteRequest)) + return srv.(ArduinoCoreServiceServer).SettingsGetValue(ctx, req.(*SettingsGetValueRequest)) } return interceptor(ctx, in, info, handler) } -func _ArduinoCoreService_SettingsDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SettingsDeleteRequest) +func _ArduinoCoreService_SettingsSetValue_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SettingsSetValueRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(ArduinoCoreServiceServer).SettingsDelete(ctx, in) + return srv.(ArduinoCoreServiceServer).SettingsSetValue(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: ArduinoCoreService_SettingsDelete_FullMethodName, + FullMethod: ArduinoCoreService_SettingsSetValue_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ArduinoCoreServiceServer).SettingsDelete(ctx, req.(*SettingsDeleteRequest)) + return srv.(ArduinoCoreServiceServer).SettingsSetValue(ctx, req.(*SettingsSetValueRequest)) } return interceptor(ctx, in, info, handler) } @@ -2455,28 +2453,28 @@ var ArduinoCoreService_ServiceDesc = grpc.ServiceDesc{ Handler: _ArduinoCoreService_CleanDownloadCacheDirectory_Handler, }, { - MethodName: "SettingsGetAll", - Handler: _ArduinoCoreService_SettingsGetAll_Handler, + MethodName: "ConfigurationSave", + Handler: _ArduinoCoreService_ConfigurationSave_Handler, }, { - MethodName: "SettingsMerge", - Handler: _ArduinoCoreService_SettingsMerge_Handler, + MethodName: "ConfigurationOpen", + Handler: _ArduinoCoreService_ConfigurationOpen_Handler, }, { - MethodName: "SettingsGetValue", - Handler: _ArduinoCoreService_SettingsGetValue_Handler, + MethodName: "ConfigurationGet", + Handler: _ArduinoCoreService_ConfigurationGet_Handler, }, { - MethodName: "SettingsSetValue", - Handler: _ArduinoCoreService_SettingsSetValue_Handler, + MethodName: "SettingsEnumerate", + Handler: _ArduinoCoreService_SettingsEnumerate_Handler, }, { - MethodName: "SettingsWrite", - Handler: _ArduinoCoreService_SettingsWrite_Handler, + MethodName: "SettingsGetValue", + Handler: _ArduinoCoreService_SettingsGetValue_Handler, }, { - MethodName: "SettingsDelete", - Handler: _ArduinoCoreService_SettingsDelete_Handler, + MethodName: "SettingsSetValue", + Handler: _ArduinoCoreService_SettingsSetValue_Handler, }, }, Streams: []grpc.StreamDesc{ diff --git a/rpc/cc/arduino/cli/commands/v1/settings.pb.go b/rpc/cc/arduino/cli/commands/v1/settings.pb.go index 8a594bbd49f..13765e459b7 100644 --- a/rpc/cc/arduino/cli/commands/v1/settings.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/settings.pb.go @@ -35,17 +35,28 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type SettingsGetAllResponse struct { +// Configuration to apply to the given instance. +// Any missing field will be kept at the default value. +type Configuration struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The settings, in JSON format. - JsonData string `protobuf:"bytes,1,opt,name=json_data,json=jsonData,proto3" json:"json_data,omitempty"` -} - -func (x *SettingsGetAllResponse) Reset() { - *x = SettingsGetAllResponse{} + Directories *Configuration_Directories `protobuf:"bytes,1,opt,name=directories,proto3" json:"directories,omitempty"` + Network *Configuration_Network `protobuf:"bytes,2,opt,name=network,proto3" json:"network,omitempty"` + Sketch *Configuration_Sketch `protobuf:"bytes,3,opt,name=sketch,proto3" json:"sketch,omitempty"` + BuildCache *Configuration_BuildCache `protobuf:"bytes,4,opt,name=build_cache,json=buildCache,proto3" json:"build_cache,omitempty"` + BoardManager *Configuration_BoardManager `protobuf:"bytes,5,opt,name=board_manager,json=boardManager,proto3" json:"board_manager,omitempty"` + Daemon *Configuration_Daemon `protobuf:"bytes,6,opt,name=daemon,proto3" json:"daemon,omitempty"` + Output *Configuration_Output `protobuf:"bytes,7,opt,name=output,proto3" json:"output,omitempty"` + Logging *Configuration_Logging `protobuf:"bytes,8,opt,name=logging,proto3" json:"logging,omitempty"` + Library *Configuration_Library `protobuf:"bytes,9,opt,name=library,proto3" json:"library,omitempty"` + Updater *Configuration_Updater `protobuf:"bytes,10,opt,name=updater,proto3" json:"updater,omitempty"` + Locale *string `protobuf:"bytes,100,opt,name=locale,proto3,oneof" json:"locale,omitempty"` +} + +func (x *Configuration) Reset() { + *x = Configuration{} if protoimpl.UnsafeEnabled { mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -53,13 +64,13 @@ func (x *SettingsGetAllResponse) Reset() { } } -func (x *SettingsGetAllResponse) String() string { +func (x *Configuration) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsGetAllResponse) ProtoMessage() {} +func (*Configuration) ProtoMessage() {} -func (x *SettingsGetAllResponse) ProtoReflect() protoreflect.Message { +func (x *Configuration) ProtoReflect() protoreflect.Message { mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -71,29 +82,96 @@ func (x *SettingsGetAllResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsGetAllResponse.ProtoReflect.Descriptor instead. -func (*SettingsGetAllResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use Configuration.ProtoReflect.Descriptor instead. +func (*Configuration) Descriptor() ([]byte, []int) { return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0} } -func (x *SettingsGetAllResponse) GetJsonData() string { +func (x *Configuration) GetDirectories() *Configuration_Directories { + if x != nil { + return x.Directories + } + return nil +} + +func (x *Configuration) GetNetwork() *Configuration_Network { + if x != nil { + return x.Network + } + return nil +} + +func (x *Configuration) GetSketch() *Configuration_Sketch { + if x != nil { + return x.Sketch + } + return nil +} + +func (x *Configuration) GetBuildCache() *Configuration_BuildCache { + if x != nil { + return x.BuildCache + } + return nil +} + +func (x *Configuration) GetBoardManager() *Configuration_BoardManager { + if x != nil { + return x.BoardManager + } + return nil +} + +func (x *Configuration) GetDaemon() *Configuration_Daemon { + if x != nil { + return x.Daemon + } + return nil +} + +func (x *Configuration) GetOutput() *Configuration_Output { + if x != nil { + return x.Output + } + return nil +} + +func (x *Configuration) GetLogging() *Configuration_Logging { + if x != nil { + return x.Logging + } + return nil +} + +func (x *Configuration) GetLibrary() *Configuration_Library { + if x != nil { + return x.Library + } + return nil +} + +func (x *Configuration) GetUpdater() *Configuration_Updater { if x != nil { - return x.JsonData + return x.Updater + } + return nil +} + +func (x *Configuration) GetLocale() string { + if x != nil && x.Locale != nil { + return *x.Locale } return "" } -type SettingsMergeRequest struct { +type ConfigurationGetRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - - // The settings, in JSON format. - JsonData string `protobuf:"bytes,1,opt,name=json_data,json=jsonData,proto3" json:"json_data,omitempty"` } -func (x *SettingsMergeRequest) Reset() { - *x = SettingsMergeRequest{} +func (x *ConfigurationGetRequest) Reset() { + *x = ConfigurationGetRequest{} if protoimpl.UnsafeEnabled { mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -101,13 +179,13 @@ func (x *SettingsMergeRequest) Reset() { } } -func (x *SettingsMergeRequest) String() string { +func (x *ConfigurationGetRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsMergeRequest) ProtoMessage() {} +func (*ConfigurationGetRequest) ProtoMessage() {} -func (x *SettingsMergeRequest) ProtoReflect() protoreflect.Message { +func (x *ConfigurationGetRequest) ProtoReflect() protoreflect.Message { mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -119,46 +197,706 @@ func (x *SettingsMergeRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsMergeRequest.ProtoReflect.Descriptor instead. -func (*SettingsMergeRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ConfigurationGetRequest.ProtoReflect.Descriptor instead. +func (*ConfigurationGetRequest) Descriptor() ([]byte, []int) { return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{1} } -func (x *SettingsMergeRequest) GetJsonData() string { +type ConfigurationGetResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The current configuration + Configuration *Configuration `protobuf:"bytes,1,opt,name=configuration,proto3" json:"configuration,omitempty"` +} + +func (x *ConfigurationGetResponse) Reset() { + *x = ConfigurationGetResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigurationGetResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigurationGetResponse) ProtoMessage() {} + +func (x *ConfigurationGetResponse) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_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 ConfigurationGetResponse.ProtoReflect.Descriptor instead. +func (*ConfigurationGetResponse) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{2} +} + +func (x *ConfigurationGetResponse) GetConfiguration() *Configuration { + if x != nil { + return x.Configuration + } + return nil +} + +type ConfigurationSaveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The format of the encoded settings, allowed values are "json" and "yaml" + SettingsFormat string `protobuf:"bytes,1,opt,name=settings_format,json=settingsFormat,proto3" json:"settings_format,omitempty"` +} + +func (x *ConfigurationSaveRequest) Reset() { + *x = ConfigurationSaveRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigurationSaveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigurationSaveRequest) ProtoMessage() {} + +func (x *ConfigurationSaveRequest) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[3] + 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 ConfigurationSaveRequest.ProtoReflect.Descriptor instead. +func (*ConfigurationSaveRequest) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{3} +} + +func (x *ConfigurationSaveRequest) GetSettingsFormat() string { if x != nil { - return x.JsonData + return x.SettingsFormat } return "" } -type SettingsGetValueResponse struct { +type ConfigurationSaveResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The encoded settings + EncodedSettings string `protobuf:"bytes,1,opt,name=encoded_settings,json=encodedSettings,proto3" json:"encoded_settings,omitempty"` +} + +func (x *ConfigurationSaveResponse) Reset() { + *x = ConfigurationSaveResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigurationSaveResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigurationSaveResponse) ProtoMessage() {} + +func (x *ConfigurationSaveResponse) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[4] + 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 ConfigurationSaveResponse.ProtoReflect.Descriptor instead. +func (*ConfigurationSaveResponse) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{4} +} + +func (x *ConfigurationSaveResponse) GetEncodedSettings() string { + if x != nil { + return x.EncodedSettings + } + return "" +} + +type ConfigurationOpenRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The encoded settings + EncodedSettings string `protobuf:"bytes,1,opt,name=encoded_settings,json=encodedSettings,proto3" json:"encoded_settings,omitempty"` + // The format of the encoded settings, allowed values are "json" and "yaml" + SettingsFormat string `protobuf:"bytes,2,opt,name=settings_format,json=settingsFormat,proto3" json:"settings_format,omitempty"` +} + +func (x *ConfigurationOpenRequest) Reset() { + *x = ConfigurationOpenRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigurationOpenRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigurationOpenRequest) ProtoMessage() {} + +func (x *ConfigurationOpenRequest) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[5] + 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 ConfigurationOpenRequest.ProtoReflect.Descriptor instead. +func (*ConfigurationOpenRequest) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{5} +} + +func (x *ConfigurationOpenRequest) GetEncodedSettings() string { + if x != nil { + return x.EncodedSettings + } + return "" +} + +func (x *ConfigurationOpenRequest) GetSettingsFormat() string { + if x != nil { + return x.SettingsFormat + } + return "" +} + +type ConfigurationOpenResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ConfigurationOpenResponse) Reset() { + *x = ConfigurationOpenResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConfigurationOpenResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConfigurationOpenResponse) ProtoMessage() {} + +func (x *ConfigurationOpenResponse) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_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 ConfigurationOpenResponse.ProtoReflect.Descriptor instead. +func (*ConfigurationOpenResponse) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{6} +} + +type SettingsGetValueRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The key of the setting. + // The key to get Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // The setting, in JSON format. - JsonData string `protobuf:"bytes,2,opt,name=json_data,json=jsonData,proto3" json:"json_data,omitempty"` + // The format of the encoded_value (default is "json", allowed values are + // "json" and "yaml) + ValueFormat string `protobuf:"bytes,2,opt,name=value_format,json=valueFormat,proto3" json:"value_format,omitempty"` } -func (x *SettingsGetValueResponse) Reset() { - *x = SettingsGetValueResponse{} +func (x *SettingsGetValueRequest) Reset() { + *x = SettingsGetValueRequest{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[2] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsGetValueResponse) String() string { +func (x *SettingsGetValueRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsGetValueResponse) ProtoMessage() {} +func (*SettingsGetValueRequest) ProtoMessage() {} + +func (x *SettingsGetValueRequest) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[7] + 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 SettingsGetValueRequest.ProtoReflect.Descriptor instead. +func (*SettingsGetValueRequest) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{7} +} + +func (x *SettingsGetValueRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *SettingsGetValueRequest) GetValueFormat() string { + if x != nil { + return x.ValueFormat + } + return "" +} + +type SettingsGetValueResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The value of the key (encoded) + EncodedValue string `protobuf:"bytes,1,opt,name=encoded_value,json=encodedValue,proto3" json:"encoded_value,omitempty"` +} + +func (x *SettingsGetValueResponse) Reset() { + *x = SettingsGetValueResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SettingsGetValueResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SettingsGetValueResponse) ProtoMessage() {} + +func (x *SettingsGetValueResponse) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[8] + 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 SettingsGetValueResponse.ProtoReflect.Descriptor instead. +func (*SettingsGetValueResponse) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{8} +} + +func (x *SettingsGetValueResponse) GetEncodedValue() string { + if x != nil { + return x.EncodedValue + } + return "" +} + +type SettingsSetValueRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The key to change + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The new value (encoded), no objects, only scalar or array of scalars are + // allowed. + EncodedValue string `protobuf:"bytes,2,opt,name=encoded_value,json=encodedValue,proto3" json:"encoded_value,omitempty"` + // The format of the encoded_value (default is "json", allowed values are + // "json", "yaml" and "cli") + ValueFormat string `protobuf:"bytes,3,opt,name=value_format,json=valueFormat,proto3" json:"value_format,omitempty"` +} + +func (x *SettingsSetValueRequest) Reset() { + *x = SettingsSetValueRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SettingsSetValueRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SettingsSetValueRequest) ProtoMessage() {} + +func (x *SettingsSetValueRequest) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[9] + 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 SettingsSetValueRequest.ProtoReflect.Descriptor instead. +func (*SettingsSetValueRequest) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{9} +} + +func (x *SettingsSetValueRequest) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *SettingsSetValueRequest) GetEncodedValue() string { + if x != nil { + return x.EncodedValue + } + return "" +} + +func (x *SettingsSetValueRequest) GetValueFormat() string { + if x != nil { + return x.ValueFormat + } + return "" +} + +type SettingsSetValueResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SettingsSetValueResponse) Reset() { + *x = SettingsSetValueResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SettingsSetValueResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SettingsSetValueResponse) ProtoMessage() {} + +func (x *SettingsSetValueResponse) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[10] + 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 SettingsSetValueResponse.ProtoReflect.Descriptor instead. +func (*SettingsSetValueResponse) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{10} +} + +type SettingsEnumerateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *SettingsEnumerateRequest) Reset() { + *x = SettingsEnumerateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SettingsEnumerateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SettingsEnumerateRequest) ProtoMessage() {} + +func (x *SettingsEnumerateRequest) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[11] + 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 SettingsEnumerateRequest.ProtoReflect.Descriptor instead. +func (*SettingsEnumerateRequest) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{11} +} + +type SettingsEnumerateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The list of key/value pairs + Entries []*SettingsEnumerateResponse_Entry `protobuf:"bytes,1,rep,name=entries,proto3" json:"entries,omitempty"` +} + +func (x *SettingsEnumerateResponse) Reset() { + *x = SettingsEnumerateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SettingsEnumerateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SettingsEnumerateResponse) ProtoMessage() {} + +func (x *SettingsEnumerateResponse) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[12] + 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 SettingsEnumerateResponse.ProtoReflect.Descriptor instead. +func (*SettingsEnumerateResponse) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{12} +} + +func (x *SettingsEnumerateResponse) GetEntries() []*SettingsEnumerateResponse_Entry { + if x != nil { + return x.Entries + } + return nil +} + +type Configuration_Directories struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Data directory + Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + // User directory + User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` + // Downloads directory + Downloads string `protobuf:"bytes,3,opt,name=downloads,proto3" json:"downloads,omitempty"` + // The directory where the built-in resources are installed + Builtin *Configuration_Directories_Builtin `protobuf:"bytes,4,opt,name=builtin,proto3,oneof" json:"builtin,omitempty"` +} + +func (x *Configuration_Directories) Reset() { + *x = Configuration_Directories{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Configuration_Directories) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Configuration_Directories) ProtoMessage() {} + +func (x *Configuration_Directories) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[13] + 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 Configuration_Directories.ProtoReflect.Descriptor instead. +func (*Configuration_Directories) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *Configuration_Directories) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +func (x *Configuration_Directories) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *Configuration_Directories) GetDownloads() string { + if x != nil { + return x.Downloads + } + return "" +} + +func (x *Configuration_Directories) GetBuiltin() *Configuration_Directories_Builtin { + if x != nil { + return x.Builtin + } + return nil +} + +type Configuration_Network struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Extra user-agent information to be appended in network requests + ExtraUserAgent *string `protobuf:"bytes,1,opt,name=extra_user_agent,json=extraUserAgent,proto3,oneof" json:"extra_user_agent,omitempty"` + // The proxy to use for network requests + Proxy *string `protobuf:"bytes,2,opt,name=proxy,proto3,oneof" json:"proxy,omitempty"` +} + +func (x *Configuration_Network) Reset() { + *x = Configuration_Network{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Configuration_Network) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Configuration_Network) ProtoMessage() {} + +func (x *Configuration_Network) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[14] + 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 Configuration_Network.ProtoReflect.Descriptor instead. +func (*Configuration_Network) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *Configuration_Network) GetExtraUserAgent() string { + if x != nil && x.ExtraUserAgent != nil { + return *x.ExtraUserAgent + } + return "" +} + +func (x *Configuration_Network) GetProxy() string { + if x != nil && x.Proxy != nil { + return *x.Proxy + } + return "" +} + +type Configuration_Sketch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Set to true to always export binaries to the sketch directory + AlwaysExportBinaries bool `protobuf:"varint,1,opt,name=always_export_binaries,json=alwaysExportBinaries,proto3" json:"always_export_binaries,omitempty"` +} + +func (x *Configuration_Sketch) Reset() { + *x = Configuration_Sketch{} + if protoimpl.UnsafeEnabled { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Configuration_Sketch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Configuration_Sketch) ProtoMessage() {} -func (x *SettingsGetValueResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[2] +func (x *Configuration_Sketch) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -169,53 +907,46 @@ func (x *SettingsGetValueResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsGetValueResponse.ProtoReflect.Descriptor instead. -func (*SettingsGetValueResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{2} -} - -func (x *SettingsGetValueResponse) GetKey() string { - if x != nil { - return x.Key - } - return "" +// Deprecated: Use Configuration_Sketch.ProtoReflect.Descriptor instead. +func (*Configuration_Sketch) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 2} } -func (x *SettingsGetValueResponse) GetJsonData() string { +func (x *Configuration_Sketch) GetAlwaysExportBinaries() bool { if x != nil { - return x.JsonData + return x.AlwaysExportBinaries } - return "" + return false } -type SettingsSetValueRequest struct { +type Configuration_BuildCache struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The key of the setting. - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - // The setting, in JSON format. - JsonData string `protobuf:"bytes,2,opt,name=json_data,json=jsonData,proto3" json:"json_data,omitempty"` + // The minimum number of compilations before the cache is purged + CompilationsBeforePurge uint64 `protobuf:"varint,1,opt,name=compilations_before_purge,json=compilationsBeforePurge,proto3" json:"compilations_before_purge,omitempty"` + // Time to live of the cache in seconds + TtlSecs uint64 `protobuf:"varint,2,opt,name=ttl_secs,json=ttlSecs,proto3" json:"ttl_secs,omitempty"` } -func (x *SettingsSetValueRequest) Reset() { - *x = SettingsSetValueRequest{} +func (x *Configuration_BuildCache) Reset() { + *x = Configuration_BuildCache{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[3] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsSetValueRequest) String() string { +func (x *Configuration_BuildCache) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsSetValueRequest) ProtoMessage() {} +func (*Configuration_BuildCache) ProtoMessage() {} -func (x *SettingsSetValueRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[3] +func (x *Configuration_BuildCache) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -226,48 +957,51 @@ func (x *SettingsSetValueRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsSetValueRequest.ProtoReflect.Descriptor instead. -func (*SettingsSetValueRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{3} +// Deprecated: Use Configuration_BuildCache.ProtoReflect.Descriptor instead. +func (*Configuration_BuildCache) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 3} } -func (x *SettingsSetValueRequest) GetKey() string { +func (x *Configuration_BuildCache) GetCompilationsBeforePurge() uint64 { if x != nil { - return x.Key + return x.CompilationsBeforePurge } - return "" + return 0 } -func (x *SettingsSetValueRequest) GetJsonData() string { +func (x *Configuration_BuildCache) GetTtlSecs() uint64 { if x != nil { - return x.JsonData + return x.TtlSecs } - return "" + return 0 } -type SettingsGetAllRequest struct { +type Configuration_BoardManager struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Additional URLs to be used for the board manager + AdditionalUrls []string `protobuf:"bytes,1,rep,name=additional_urls,json=additionalUrls,proto3" json:"additional_urls,omitempty"` } -func (x *SettingsGetAllRequest) Reset() { - *x = SettingsGetAllRequest{} +func (x *Configuration_BoardManager) Reset() { + *x = Configuration_BoardManager{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[4] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsGetAllRequest) String() string { +func (x *Configuration_BoardManager) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsGetAllRequest) ProtoMessage() {} +func (*Configuration_BoardManager) ProtoMessage() {} -func (x *SettingsGetAllRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[4] +func (x *Configuration_BoardManager) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -278,37 +1012,44 @@ func (x *SettingsGetAllRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsGetAllRequest.ProtoReflect.Descriptor instead. -func (*SettingsGetAllRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{4} +// Deprecated: Use Configuration_BoardManager.ProtoReflect.Descriptor instead. +func (*Configuration_BoardManager) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 4} } -type SettingsGetValueRequest struct { +func (x *Configuration_BoardManager) GetAdditionalUrls() []string { + if x != nil { + return x.AdditionalUrls + } + return nil +} + +type Configuration_Daemon struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The key of the setting. - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The TCP port of the daemon + Port string `protobuf:"bytes,1,opt,name=port,proto3" json:"port,omitempty"` } -func (x *SettingsGetValueRequest) Reset() { - *x = SettingsGetValueRequest{} +func (x *Configuration_Daemon) Reset() { + *x = Configuration_Daemon{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[5] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsGetValueRequest) String() string { +func (x *Configuration_Daemon) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsGetValueRequest) ProtoMessage() {} +func (*Configuration_Daemon) ProtoMessage() {} -func (x *SettingsGetValueRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[5] +func (x *Configuration_Daemon) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -319,41 +1060,44 @@ func (x *SettingsGetValueRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsGetValueRequest.ProtoReflect.Descriptor instead. -func (*SettingsGetValueRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{5} +// Deprecated: Use Configuration_Daemon.ProtoReflect.Descriptor instead. +func (*Configuration_Daemon) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 5} } -func (x *SettingsGetValueRequest) GetKey() string { +func (x *Configuration_Daemon) GetPort() string { if x != nil { - return x.Key + return x.Port } return "" } -type SettingsMergeResponse struct { +type Configuration_Output struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Set to true to disable coloring of the output + NoColor bool `protobuf:"varint,1,opt,name=no_color,json=noColor,proto3" json:"no_color,omitempty"` } -func (x *SettingsMergeResponse) Reset() { - *x = SettingsMergeResponse{} +func (x *Configuration_Output) Reset() { + *x = Configuration_Output{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[6] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsMergeResponse) String() string { +func (x *Configuration_Output) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsMergeResponse) ProtoMessage() {} +func (*Configuration_Output) ProtoMessage() {} -func (x *SettingsMergeResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[6] +func (x *Configuration_Output) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -364,34 +1108,48 @@ func (x *SettingsMergeResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsMergeResponse.ProtoReflect.Descriptor instead. -func (*SettingsMergeResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{6} +// Deprecated: Use Configuration_Output.ProtoReflect.Descriptor instead. +func (*Configuration_Output) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 6} } -type SettingsSetValueResponse struct { +func (x *Configuration_Output) GetNoColor() bool { + if x != nil { + return x.NoColor + } + return false +} + +type Configuration_Logging struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // The logging level + Level string `protobuf:"bytes,1,opt,name=level,proto3" json:"level,omitempty"` + // The logging format + Format string `protobuf:"bytes,2,opt,name=format,proto3" json:"format,omitempty"` + // The logging file + File *string `protobuf:"bytes,3,opt,name=file,proto3,oneof" json:"file,omitempty"` } -func (x *SettingsSetValueResponse) Reset() { - *x = SettingsSetValueResponse{} +func (x *Configuration_Logging) Reset() { + *x = Configuration_Logging{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[7] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsSetValueResponse) String() string { +func (x *Configuration_Logging) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsSetValueResponse) ProtoMessage() {} +func (*Configuration_Logging) ProtoMessage() {} -func (x *SettingsSetValueResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[7] +func (x *Configuration_Logging) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -402,37 +1160,59 @@ func (x *SettingsSetValueResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsSetValueResponse.ProtoReflect.Descriptor instead. -func (*SettingsSetValueResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{7} +// Deprecated: Use Configuration_Logging.ProtoReflect.Descriptor instead. +func (*Configuration_Logging) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 7} +} + +func (x *Configuration_Logging) GetLevel() string { + if x != nil { + return x.Level + } + return "" +} + +func (x *Configuration_Logging) GetFormat() string { + if x != nil { + return x.Format + } + return "" } -type SettingsWriteRequest struct { +func (x *Configuration_Logging) GetFile() string { + if x != nil && x.File != nil { + return *x.File + } + return "" +} + +type Configuration_Library struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Path to settings file (e.g. /path/to/arduino-cli.yaml) - FilePath string `protobuf:"bytes,1,opt,name=file_path,json=filePath,proto3" json:"file_path,omitempty"` + // Set to true to enable library installation from zip archives or git + // repositories + EnableUnsafeInstall bool `protobuf:"varint,1,opt,name=enable_unsafe_install,json=enableUnsafeInstall,proto3" json:"enable_unsafe_install,omitempty"` } -func (x *SettingsWriteRequest) Reset() { - *x = SettingsWriteRequest{} +func (x *Configuration_Library) Reset() { + *x = Configuration_Library{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[8] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsWriteRequest) String() string { +func (x *Configuration_Library) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsWriteRequest) ProtoMessage() {} +func (*Configuration_Library) ProtoMessage() {} -func (x *SettingsWriteRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[8] +func (x *Configuration_Library) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -443,41 +1223,44 @@ func (x *SettingsWriteRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsWriteRequest.ProtoReflect.Descriptor instead. -func (*SettingsWriteRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{8} +// Deprecated: Use Configuration_Library.ProtoReflect.Descriptor instead. +func (*Configuration_Library) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 8} } -func (x *SettingsWriteRequest) GetFilePath() string { +func (x *Configuration_Library) GetEnableUnsafeInstall() bool { if x != nil { - return x.FilePath + return x.EnableUnsafeInstall } - return "" + return false } -type SettingsWriteResponse struct { +type Configuration_Updater struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Set to true to enable notifications for updates + EnableNotification bool `protobuf:"varint,1,opt,name=enable_notification,json=enableNotification,proto3" json:"enable_notification,omitempty"` } -func (x *SettingsWriteResponse) Reset() { - *x = SettingsWriteResponse{} +func (x *Configuration_Updater) Reset() { + *x = Configuration_Updater{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[9] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsWriteResponse) String() string { +func (x *Configuration_Updater) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsWriteResponse) ProtoMessage() {} +func (*Configuration_Updater) ProtoMessage() {} -func (x *SettingsWriteResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[9] +func (x *Configuration_Updater) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -488,37 +1271,44 @@ func (x *SettingsWriteResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsWriteResponse.ProtoReflect.Descriptor instead. -func (*SettingsWriteResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{9} +// Deprecated: Use Configuration_Updater.ProtoReflect.Descriptor instead. +func (*Configuration_Updater) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 9} +} + +func (x *Configuration_Updater) GetEnableNotification() bool { + if x != nil { + return x.EnableNotification + } + return false } -type SettingsDeleteRequest struct { +type Configuration_Directories_Builtin struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The key of the setting to delete. - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The directory where the built-in libraries are installed + Libraries *string `protobuf:"bytes,1,opt,name=libraries,proto3,oneof" json:"libraries,omitempty"` } -func (x *SettingsDeleteRequest) Reset() { - *x = SettingsDeleteRequest{} +func (x *Configuration_Directories_Builtin) Reset() { + *x = Configuration_Directories_Builtin{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[10] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsDeleteRequest) String() string { +func (x *Configuration_Directories_Builtin) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsDeleteRequest) ProtoMessage() {} +func (*Configuration_Directories_Builtin) ProtoMessage() {} -func (x *SettingsDeleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[10] +func (x *Configuration_Directories_Builtin) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -529,41 +1319,46 @@ func (x *SettingsDeleteRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsDeleteRequest.ProtoReflect.Descriptor instead. -func (*SettingsDeleteRequest) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{10} +// Deprecated: Use Configuration_Directories_Builtin.ProtoReflect.Descriptor instead. +func (*Configuration_Directories_Builtin) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{0, 0, 0} } -func (x *SettingsDeleteRequest) GetKey() string { - if x != nil { - return x.Key +func (x *Configuration_Directories_Builtin) GetLibraries() string { + if x != nil && x.Libraries != nil { + return *x.Libraries } return "" } -type SettingsDeleteResponse struct { +type SettingsEnumerateResponse_Entry struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // The key + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + // The key type + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` } -func (x *SettingsDeleteResponse) Reset() { - *x = SettingsDeleteResponse{} +func (x *SettingsEnumerateResponse_Entry) Reset() { + *x = SettingsEnumerateResponse_Entry{} if protoimpl.UnsafeEnabled { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[11] + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SettingsDeleteResponse) String() string { +func (x *SettingsEnumerateResponse_Entry) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SettingsDeleteResponse) ProtoMessage() {} +func (*SettingsEnumerateResponse_Entry) ProtoMessage() {} -func (x *SettingsDeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[11] +func (x *SettingsEnumerateResponse_Entry) ProtoReflect() protoreflect.Message { + mi := &file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -574,9 +1369,23 @@ func (x *SettingsDeleteResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SettingsDeleteResponse.ProtoReflect.Descriptor instead. -func (*SettingsDeleteResponse) Descriptor() ([]byte, []int) { - return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{11} +// Deprecated: Use SettingsEnumerateResponse_Entry.ProtoReflect.Descriptor instead. +func (*SettingsEnumerateResponse_Entry) Descriptor() ([]byte, []int) { + return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{12, 0} +} + +func (x *SettingsEnumerateResponse_Entry) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +func (x *SettingsEnumerateResponse_Entry) GetType() string { + if x != nil { + return x.Type + } + return "" } var File_cc_arduino_cli_commands_v1_settings_proto protoreflect.FileDescriptor @@ -586,45 +1395,176 @@ var file_cc_arduino_cli_commands_v1_settings_proto_rawDesc = []byte{ 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a, 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, 0x22, 0x35, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x22, 0x33, - 0x0a, 0x14, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x44, - 0x61, 0x74, 0x61, 0x22, 0x49, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, - 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6a, 0x73, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x22, 0x48, - 0x0a, 0x17, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x6a, - 0x73, 0x6f, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6a, 0x73, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x22, 0x17, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x41, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x2b, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x17, - 0x0a, 0x15, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x33, 0x0a, 0x14, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x66, - 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x66, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x17, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x57, 0x72, 0x69, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x29, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x18, 0x0a, 0x16, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 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, + 0x61, 0x6e, 0x64, 0x73, 0x2e, 0x76, 0x31, 0x22, 0xbd, 0x0d, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x57, 0x0a, 0x0b, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, + 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, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x69, 0x65, 0x73, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, + 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x31, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4e, + 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, + 0x48, 0x0a, 0x06, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x30, 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, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x6b, 0x65, 0x74, 0x63, + 0x68, 0x52, 0x06, 0x73, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x12, 0x55, 0x0a, 0x0b, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x5f, 0x63, 0x61, 0x63, 0x68, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, + 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, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, + 0x61, 0x63, 0x68, 0x65, 0x52, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x61, 0x63, 0x68, 0x65, + 0x12, 0x5b, 0x0a, 0x0d, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x5f, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, + 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x52, + 0x0c, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x48, 0x0a, + 0x06, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x52, + 0x06, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x12, 0x4b, 0x0a, 0x07, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x31, 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, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, + 0x67, 0x67, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x12, 0x4b, + 0x0a, 0x07, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x31, 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, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x62, 0x72, 0x61, + 0x72, 0x79, 0x52, 0x07, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, 0x4b, 0x0a, 0x07, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x52, + 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x06, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x65, 0x18, 0x64, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x65, 0x88, 0x01, 0x01, 0x1a, 0xf9, 0x01, 0x0a, 0x0b, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x0a, + 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x5c, 0x0a, 0x07, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3d, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x69, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x48, 0x00, 0x52, 0x07, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x88, 0x01, 0x01, 0x1a, 0x3a, 0x0a, 0x07, 0x42, 0x75, 0x69, + 0x6c, 0x74, 0x69, 0x6e, 0x12, 0x21, 0x0a, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, + 0x72, 0x69, 0x65, 0x73, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x6c, 0x69, 0x62, 0x72, + 0x61, 0x72, 0x69, 0x65, 0x73, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, + 0x6e, 0x1a, 0x72, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x2d, 0x0a, 0x10, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x55, + 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x19, 0x0a, 0x05, 0x70, + 0x72, 0x6f, 0x78, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x05, 0x70, 0x72, + 0x6f, 0x78, 0x79, 0x88, 0x01, 0x01, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, + 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x5f, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x1a, 0x3e, 0x0a, 0x06, 0x53, 0x6b, 0x65, 0x74, 0x63, 0x68, 0x12, + 0x34, 0x0a, 0x16, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, + 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x14, 0x61, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x69, 0x6e, + 0x61, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x63, 0x0a, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x61, + 0x63, 0x68, 0x65, 0x12, 0x3a, 0x0a, 0x19, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x5f, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x70, 0x75, 0x72, 0x67, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x50, 0x75, 0x72, 0x67, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x74, 0x74, 0x6c, 0x5f, 0x73, 0x65, 0x63, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x07, 0x74, 0x74, 0x6c, 0x53, 0x65, 0x63, 0x73, 0x1a, 0x37, 0x0a, 0x0c, 0x42, 0x6f, + 0x61, 0x72, 0x64, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x12, 0x27, 0x0a, 0x0f, 0x61, 0x64, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x6c, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0e, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, + 0x72, 0x6c, 0x73, 0x1a, 0x1c, 0x0a, 0x06, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x72, + 0x74, 0x1a, 0x23, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x6e, + 0x6f, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6e, + 0x6f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x1a, 0x59, 0x0a, 0x07, 0x4c, 0x6f, 0x67, 0x67, 0x69, 0x6e, + 0x67, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, + 0x17, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x04, 0x66, 0x69, 0x6c, 0x65, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x66, 0x69, 0x6c, + 0x65, 0x1a, 0x3d, 0x0a, 0x07, 0x4c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x12, 0x32, 0x0a, 0x15, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x5f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x1a, 0x3a, 0x0a, 0x07, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x13, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, + 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x6b, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, + 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 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, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x43, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x73, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x46, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x22, 0x46, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x6e, 0x63, + 0x6f, 0x64, 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x6e, 0x0a, 0x18, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x65, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x63, 0x6f, + 0x64, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x5f, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x1b, 0x0a, 0x19, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x65, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x17, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x3f, 0x0a, 0x18, 0x53, 0x65, 0x74, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x6e, + 0x63, 0x6f, 0x64, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x73, 0x0a, 0x17, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x63, 0x6f, 0x64, + 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, + 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, + 0x1a, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x2d, 0x0a, 0x05, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 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 ( @@ -639,27 +1579,53 @@ func file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP() []byte { return file_cc_arduino_cli_commands_v1_settings_proto_rawDescData } -var file_cc_arduino_cli_commands_v1_settings_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_cc_arduino_cli_commands_v1_settings_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_cc_arduino_cli_commands_v1_settings_proto_goTypes = []interface{}{ - (*SettingsGetAllResponse)(nil), // 0: cc.arduino.cli.commands.v1.SettingsGetAllResponse - (*SettingsMergeRequest)(nil), // 1: cc.arduino.cli.commands.v1.SettingsMergeRequest - (*SettingsGetValueResponse)(nil), // 2: cc.arduino.cli.commands.v1.SettingsGetValueResponse - (*SettingsSetValueRequest)(nil), // 3: cc.arduino.cli.commands.v1.SettingsSetValueRequest - (*SettingsGetAllRequest)(nil), // 4: cc.arduino.cli.commands.v1.SettingsGetAllRequest - (*SettingsGetValueRequest)(nil), // 5: cc.arduino.cli.commands.v1.SettingsGetValueRequest - (*SettingsMergeResponse)(nil), // 6: cc.arduino.cli.commands.v1.SettingsMergeResponse - (*SettingsSetValueResponse)(nil), // 7: cc.arduino.cli.commands.v1.SettingsSetValueResponse - (*SettingsWriteRequest)(nil), // 8: cc.arduino.cli.commands.v1.SettingsWriteRequest - (*SettingsWriteResponse)(nil), // 9: cc.arduino.cli.commands.v1.SettingsWriteResponse - (*SettingsDeleteRequest)(nil), // 10: cc.arduino.cli.commands.v1.SettingsDeleteRequest - (*SettingsDeleteResponse)(nil), // 11: cc.arduino.cli.commands.v1.SettingsDeleteResponse + (*Configuration)(nil), // 0: cc.arduino.cli.commands.v1.Configuration + (*ConfigurationGetRequest)(nil), // 1: cc.arduino.cli.commands.v1.ConfigurationGetRequest + (*ConfigurationGetResponse)(nil), // 2: cc.arduino.cli.commands.v1.ConfigurationGetResponse + (*ConfigurationSaveRequest)(nil), // 3: cc.arduino.cli.commands.v1.ConfigurationSaveRequest + (*ConfigurationSaveResponse)(nil), // 4: cc.arduino.cli.commands.v1.ConfigurationSaveResponse + (*ConfigurationOpenRequest)(nil), // 5: cc.arduino.cli.commands.v1.ConfigurationOpenRequest + (*ConfigurationOpenResponse)(nil), // 6: cc.arduino.cli.commands.v1.ConfigurationOpenResponse + (*SettingsGetValueRequest)(nil), // 7: cc.arduino.cli.commands.v1.SettingsGetValueRequest + (*SettingsGetValueResponse)(nil), // 8: cc.arduino.cli.commands.v1.SettingsGetValueResponse + (*SettingsSetValueRequest)(nil), // 9: cc.arduino.cli.commands.v1.SettingsSetValueRequest + (*SettingsSetValueResponse)(nil), // 10: cc.arduino.cli.commands.v1.SettingsSetValueResponse + (*SettingsEnumerateRequest)(nil), // 11: cc.arduino.cli.commands.v1.SettingsEnumerateRequest + (*SettingsEnumerateResponse)(nil), // 12: cc.arduino.cli.commands.v1.SettingsEnumerateResponse + (*Configuration_Directories)(nil), // 13: cc.arduino.cli.commands.v1.Configuration.Directories + (*Configuration_Network)(nil), // 14: cc.arduino.cli.commands.v1.Configuration.Network + (*Configuration_Sketch)(nil), // 15: cc.arduino.cli.commands.v1.Configuration.Sketch + (*Configuration_BuildCache)(nil), // 16: cc.arduino.cli.commands.v1.Configuration.BuildCache + (*Configuration_BoardManager)(nil), // 17: cc.arduino.cli.commands.v1.Configuration.BoardManager + (*Configuration_Daemon)(nil), // 18: cc.arduino.cli.commands.v1.Configuration.Daemon + (*Configuration_Output)(nil), // 19: cc.arduino.cli.commands.v1.Configuration.Output + (*Configuration_Logging)(nil), // 20: cc.arduino.cli.commands.v1.Configuration.Logging + (*Configuration_Library)(nil), // 21: cc.arduino.cli.commands.v1.Configuration.Library + (*Configuration_Updater)(nil), // 22: cc.arduino.cli.commands.v1.Configuration.Updater + (*Configuration_Directories_Builtin)(nil), // 23: cc.arduino.cli.commands.v1.Configuration.Directories.Builtin + (*SettingsEnumerateResponse_Entry)(nil), // 24: cc.arduino.cli.commands.v1.SettingsEnumerateResponse.Entry } var file_cc_arduino_cli_commands_v1_settings_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 13, // 0: cc.arduino.cli.commands.v1.Configuration.directories:type_name -> cc.arduino.cli.commands.v1.Configuration.Directories + 14, // 1: cc.arduino.cli.commands.v1.Configuration.network:type_name -> cc.arduino.cli.commands.v1.Configuration.Network + 15, // 2: cc.arduino.cli.commands.v1.Configuration.sketch:type_name -> cc.arduino.cli.commands.v1.Configuration.Sketch + 16, // 3: cc.arduino.cli.commands.v1.Configuration.build_cache:type_name -> cc.arduino.cli.commands.v1.Configuration.BuildCache + 17, // 4: cc.arduino.cli.commands.v1.Configuration.board_manager:type_name -> cc.arduino.cli.commands.v1.Configuration.BoardManager + 18, // 5: cc.arduino.cli.commands.v1.Configuration.daemon:type_name -> cc.arduino.cli.commands.v1.Configuration.Daemon + 19, // 6: cc.arduino.cli.commands.v1.Configuration.output:type_name -> cc.arduino.cli.commands.v1.Configuration.Output + 20, // 7: cc.arduino.cli.commands.v1.Configuration.logging:type_name -> cc.arduino.cli.commands.v1.Configuration.Logging + 21, // 8: cc.arduino.cli.commands.v1.Configuration.library:type_name -> cc.arduino.cli.commands.v1.Configuration.Library + 22, // 9: cc.arduino.cli.commands.v1.Configuration.updater:type_name -> cc.arduino.cli.commands.v1.Configuration.Updater + 0, // 10: cc.arduino.cli.commands.v1.ConfigurationGetResponse.configuration:type_name -> cc.arduino.cli.commands.v1.Configuration + 24, // 11: cc.arduino.cli.commands.v1.SettingsEnumerateResponse.entries:type_name -> cc.arduino.cli.commands.v1.SettingsEnumerateResponse.Entry + 23, // 12: cc.arduino.cli.commands.v1.Configuration.Directories.builtin:type_name -> cc.arduino.cli.commands.v1.Configuration.Directories.Builtin + 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 + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_cc_arduino_cli_commands_v1_settings_proto_init() } @@ -669,7 +1635,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } if !protoimpl.UnsafeEnabled { file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsGetAllResponse); i { + switch v := v.(*Configuration); i { case 0: return &v.state case 1: @@ -681,7 +1647,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsMergeRequest); i { + switch v := v.(*ConfigurationGetRequest); i { case 0: return &v.state case 1: @@ -693,7 +1659,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsGetValueResponse); i { + switch v := v.(*ConfigurationGetResponse); i { case 0: return &v.state case 1: @@ -705,7 +1671,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsSetValueRequest); i { + switch v := v.(*ConfigurationSaveRequest); i { case 0: return &v.state case 1: @@ -717,7 +1683,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsGetAllRequest); i { + switch v := v.(*ConfigurationSaveResponse); i { case 0: return &v.state case 1: @@ -729,7 +1695,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsGetValueRequest); i { + switch v := v.(*ConfigurationOpenRequest); i { case 0: return &v.state case 1: @@ -741,7 +1707,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsMergeResponse); i { + switch v := v.(*ConfigurationOpenResponse); i { case 0: return &v.state case 1: @@ -753,7 +1719,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsSetValueResponse); i { + switch v := v.(*SettingsGetValueRequest); i { case 0: return &v.state case 1: @@ -765,7 +1731,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsWriteRequest); i { + switch v := v.(*SettingsGetValueResponse); i { case 0: return &v.state case 1: @@ -777,7 +1743,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsWriteResponse); i { + switch v := v.(*SettingsSetValueRequest); i { case 0: return &v.state case 1: @@ -789,7 +1755,7 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsDeleteRequest); i { + switch v := v.(*SettingsSetValueResponse); i { case 0: return &v.state case 1: @@ -801,7 +1767,163 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SettingsDeleteResponse); i { + switch v := v.(*SettingsEnumerateRequest); 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_settings_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SettingsEnumerateResponse); 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_settings_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Directories); 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_settings_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Network); 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_settings_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Sketch); 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_settings_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_BuildCache); 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_settings_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_BoardManager); 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_settings_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Daemon); 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_settings_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Output); 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_settings_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Logging); 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_settings_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Library); 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_settings_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Updater); 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_settings_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Configuration_Directories_Builtin); 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_settings_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SettingsEnumerateResponse_Entry); i { case 0: return &v.state case 1: @@ -813,13 +1935,18 @@ func file_cc_arduino_cli_commands_v1_settings_proto_init() { } } } + file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[13].OneofWrappers = []interface{}{} + file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[14].OneofWrappers = []interface{}{} + file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[20].OneofWrappers = []interface{}{} + file_cc_arduino_cli_commands_v1_settings_proto_msgTypes[23].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cc_arduino_cli_commands_v1_settings_proto_rawDesc, NumEnums: 0, - NumMessages: 12, + NumMessages: 25, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/cc/arduino/cli/commands/v1/settings.proto b/rpc/cc/arduino/cli/commands/v1/settings.proto index 05a6ea16a22..71631e56b99 100644 --- a/rpc/cc/arduino/cli/commands/v1/settings.proto +++ b/rpc/cc/arduino/cli/commands/v1/settings.proto @@ -19,51 +19,145 @@ package cc.arduino.cli.commands.v1; option go_package = "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1;commands"; -message SettingsGetAllResponse { - // The settings, in JSON format. - string json_data = 1; +// Configuration to apply to the given instance. +// Any missing field will be kept at the default value. +message Configuration { + message Directories { + message Builtin { + // The directory where the built-in libraries are installed + optional string libraries = 1; + } + // Data directory + string data = 1; + // User directory + string user = 2; + // Downloads directory + string downloads = 3; + // The directory where the built-in resources are installed + optional Builtin builtin = 4; + }; + message Network { + // Extra user-agent information to be appended in network requests + optional string extra_user_agent = 1; + // The proxy to use for network requests + optional string proxy = 2; + }; + message Sketch { + // Set to true to always export binaries to the sketch directory + bool always_export_binaries = 1; + } + message BuildCache { + // The minimum number of compilations before the cache is purged + uint64 compilations_before_purge = 1; + // Time to live of the cache in seconds + uint64 ttl_secs = 2; + } + message BoardManager { + // Additional URLs to be used for the board manager + repeated string additional_urls = 1; + } + message Daemon { + // The TCP port of the daemon + string port = 1; + } + message Output { + // Set to true to disable coloring of the output + bool no_color = 1; + } + message Logging { + // The logging level + string level = 1; + // The logging format + string format = 2; + // The logging file + optional string file = 3; + } + message Library { + // Set to true to enable library installation from zip archives or git + // repositories + bool enable_unsafe_install = 1; + } + message Updater { + // Set to true to enable notifications for updates + bool enable_notification = 1; + } + + Directories directories = 1; + Network network = 2; + Sketch sketch = 3; + BuildCache build_cache = 4; + BoardManager board_manager = 5; + Daemon daemon = 6; + Output output = 7; + Logging logging = 8; + Library library = 9; + Updater updater = 10; + + optional string locale = 100; } -message SettingsMergeRequest { - // The settings, in JSON format. - string json_data = 1; +message ConfigurationGetRequest {} + +message ConfigurationGetResponse { + // The current configuration + Configuration configuration = 1; } -message SettingsGetValueResponse { - // The key of the setting. - string key = 1; - // The setting, in JSON format. - string json_data = 2; +message ConfigurationSaveRequest { + // The format of the encoded settings, allowed values are "json" and "yaml" + string settings_format = 1; } -message SettingsSetValueRequest { - // The key of the setting. - string key = 1; - // The setting, in JSON format. - string json_data = 2; +message ConfigurationSaveResponse { + // The encoded settings + string encoded_settings = 1; +} + +message ConfigurationOpenRequest { + // The encoded settings + string encoded_settings = 1; + // The format of the encoded settings, allowed values are "json" and "yaml" + string settings_format = 2; } -message SettingsGetAllRequest {} +message ConfigurationOpenResponse {} message SettingsGetValueRequest { - // The key of the setting. + // The key to get string key = 1; + // The format of the encoded_value (default is "json", allowed values are + // "json" and "yaml) + string value_format = 2; } -message SettingsMergeResponse {} +message SettingsGetValueResponse { + // The value of the key (encoded) + string encoded_value = 1; +} + +message SettingsSetValueRequest { + // The key to change + string key = 1; + // The new value (encoded), no objects, only scalar or array of scalars are + // allowed. + string encoded_value = 2; + // The format of the encoded_value (default is "json", allowed values are + // "json", "yaml" and "cli") + string value_format = 3; +} message SettingsSetValueResponse {} -message SettingsWriteRequest { - // Path to settings file (e.g. /path/to/arduino-cli.yaml) - string file_path = 1; -} +message SettingsEnumerateRequest {} -message SettingsWriteResponse {} +message SettingsEnumerateResponse { + message Entry { + // The key + string key = 1; + // The key type + string type = 2; + } -message SettingsDeleteRequest { - // The key of the setting to delete. - string key = 1; + // The list of key/value pairs + repeated Entry entries = 1; } - -message SettingsDeleteResponse {} diff --git a/rpc/internal/client_example/main.go b/rpc/internal/client_example/main.go index dd23b0ec8d5..eabf6bfd2d9 100644 --- a/rpc/internal/client_example/main.go +++ b/rpc/internal/client_example/main.go @@ -23,7 +23,6 @@ import ( "io" "log" "os" - "path" "path/filepath" "strings" "time" @@ -245,84 +244,84 @@ func callVersion(client rpc.ArduinoCoreServiceClient) { } func callSetValue(client rpc.ArduinoCoreServiceClient) { - _, err := client.SettingsSetValue(context.Background(), - &rpc.SettingsSetValueRequest{ - Key: "directories", - JsonData: `{"data": "` + dataDir + `", "downloads": "` + path.Join(dataDir, "staging") + `", "user": "` + path.Join(dataDir, "sketchbook") + `"}`, - }) + // _, err := client.SettingsSetValue(context.Background(), + // &rpc.SettingsSetValueRequest{ + // Key: "directories", + // JsonData: `{"data": "` + dataDir + `", "downloads": "` + path.Join(dataDir, "staging") + `", "user": "` + path.Join(dataDir, "sketchbook") + `"}`, + // }) - if err != nil { - log.Fatalf("Error setting settings value: %s", err) - } + // if err != nil { + // log.Fatalf("Error setting settings value: %s", err) + // } } func callSetProxy(client rpc.ArduinoCoreServiceClient) { - _, err := client.SettingsSetValue(context.Background(), - &rpc.SettingsSetValueRequest{ - Key: "network.proxy", - JsonData: `"http://localhost:3128"`, - }) + // _, err := client.SettingsSetValue(context.Background(), + // &rpc.SettingsSetValueRequest{ + // Key: "network.proxy", + // JsonData: `"http://localhost:3128"`, + // }) - if err != nil { - log.Fatalf("Error setting settings value: %s", err) - } + // if err != nil { + // log.Fatalf("Error setting settings value: %s", err) + // } } func callUnsetProxy(client rpc.ArduinoCoreServiceClient) { - _, err := client.SettingsSetValue(context.Background(), - &rpc.SettingsSetValueRequest{ - Key: "network.proxy", - JsonData: `""`, - }) + // _, err := client.SettingsSetValue(context.Background(), + // &rpc.SettingsSetValueRequest{ + // Key: "network.proxy", + // JsonData: `""`, + // }) - if err != nil { - log.Fatalf("Error setting settings value: %s", err) - } + // if err != nil { + // log.Fatalf("Error setting settings value: %s", err) + // } } func callMerge(client rpc.ArduinoCoreServiceClient, jsonData string) { - _, err := client.SettingsMerge(context.Background(), - &rpc.SettingsMergeRequest{ - JsonData: jsonData, - }) + // _, err := client.SettingsMerge(context.Background(), + // &rpc.SettingsMergeRequest{ + // JsonData: jsonData, + // }) - if err != nil { - log.Fatalf("Error merging settings: %s", err) - } + // if err != nil { + // log.Fatalf("Error merging settings: %s", err) + // } } func callGetValue(client rpc.ArduinoCoreServiceClient) { - getValueResp, err := client.SettingsGetValue(context.Background(), - &rpc.SettingsGetValueRequest{ - Key: "foo", - }) + // getValueResp, err := client.SettingsGetValue(context.Background(), + // &rpc.SettingsGetValueRequest{ + // Key: "foo", + // }) - if err != nil { - log.Fatalf("Error getting settings value: %s", err) - } + // if err != nil { + // log.Fatalf("Error getting settings value: %s", err) + // } - log.Printf("Value: %s: %s", getValueResp.GetKey(), getValueResp.GetJsonData()) + // log.Printf("Value: %s: %s", getValueResp.GetKey(), getValueResp.GetJsonData()) } func callGetAll(client rpc.ArduinoCoreServiceClient) { - getAllResp, err := client.SettingsGetAll(context.Background(), &rpc.SettingsGetAllRequest{}) + // getAllResp, err := client.SettingsGetAll(context.Background(), &rpc.SettingsGetAllRequest{}) - if err != nil { - log.Fatalf("Error getting settings: %s", err) - } + // if err != nil { + // log.Fatalf("Error getting settings: %s", err) + // } - log.Printf("Settings: %s", getAllResp.GetJsonData()) + // log.Printf("Settings: %s", getAllResp.GetJsonData()) } func callWrite(client rpc.ArduinoCoreServiceClient) { - _, err := client.SettingsWrite(context.Background(), - &rpc.SettingsWriteRequest{ - FilePath: path.Join(dataDir, "written-rpc.Settingsyml"), - }) + // _, err := client.SettingsWrite(context.Background(), + // &rpc.SettingsWriteRequest{ + // FilePath: path.Join(dataDir, "written-rpc.Settingsyml"), + // }) - if err != nil { - log.Fatalf("Error writing settings: %s", err) - } + // if err != nil { + // log.Fatalf("Error writing settings: %s", err) + // } } func createInstance(client rpc.ArduinoCoreServiceClient) *rpc.Instance { From 04536776396d55bc6185c41e2bdc50cc1cc3ef52 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 22 Apr 2024 14:41:41 +0200 Subject: [PATCH 33/56] Use custom type to avoid context-values collisions --- internal/cli/cli.go | 2 +- internal/cli/config/config.go | 18 +++++++++++++++++- internal/cli/config/init.go | 2 +- main.go | 4 ++-- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 5467e617fc7..aa59dfe36ba 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -117,7 +117,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { preRun(verbose, outputFormat, logLevel, logFile, logFormat, noColor, settings) // Log the configuration file used - if configFile := ctx.Value("config_file").(string); configFile != "" { + if configFile := config.GetConfigFile(ctx); configFile != "" { logrus.Infof("Using config file: %s", configFile) } else { logrus.Info("Config file not found, using default values") diff --git a/internal/cli/config/config.go b/internal/cli/config/config.go index 8c69e8e3f44..df71ea93634 100644 --- a/internal/cli/config/config.go +++ b/internal/cli/config/config.go @@ -64,6 +64,22 @@ func getAllArraySettingsKeys(ctx context.Context, srv rpc.ArduinoCoreServiceServ return arrayKeys } +type ctxValue string + +// GetConfigFile returns the configuration file path from the context +func GetConfigFile(ctx context.Context) string { + res := ctx.Value(ctxValue("config_file")) + if res == nil { + return "" + } + return res.(string) +} + +// SetConfigFile sets the configuration file path in the context +func SetConfigFile(ctx context.Context, configFile string) context.Context { + return context.WithValue(ctx, ctxValue("config_file"), configFile) +} + func saveConfiguration(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { var outConfig []byte if res, err := srv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"}); err != nil { @@ -72,7 +88,7 @@ func saveConfiguration(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { outConfig = []byte(res.GetEncodedSettings()) } - configFile := ctx.Value("config_file").(string) + configFile := GetConfigFile(ctx) if err := paths.New(configFile).WriteFile(outConfig); err != nil { feedback.Fatal(tr("Error writing to file: %v", err), feedback.ErrGeneric) } diff --git a/internal/cli/config/init.go b/internal/cli/config/init.go index 65f514dfe39..5fe25273bd4 100644 --- a/internal/cli/config/init.go +++ b/internal/cli/config/init.go @@ -83,7 +83,7 @@ func runInitCommand(srv rpc.ArduinoCoreServiceServer) { configFileAbsPath = configFileDir.Join(defaultFileName) default: - configFileAbsPath = paths.New(ctx.Value("config_file").(string)) + configFileAbsPath = paths.New(GetConfigFile(ctx)) configFileDir = configFileAbsPath.Parent() } diff --git a/main.go b/main.go index 56c58ea36d5..6d49b0e4933 100644 --- a/main.go +++ b/main.go @@ -22,6 +22,7 @@ import ( "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli" + "github.com/arduino/arduino-cli/internal/cli/config" "github.com/arduino/arduino-cli/internal/cli/configuration" "github.com/arduino/arduino-cli/internal/cli/feedback" "github.com/arduino/arduino-cli/internal/i18n" @@ -35,8 +36,7 @@ func main() { // Search for the configuration file in the command line arguments and in the environment configFile := configuration.FindConfigFileInArgsFallbackOnEnv(os.Args) - ctx := context.Background() - ctx = context.WithValue(ctx, "config_file", configFile) + ctx := config.SetConfigFile(context.Background(), configFile) // Read the settings from the configuration file openReq := &rpc.ConfigurationOpenRequest{SettingsFormat: "yaml"} From 61b66a7092ddfd1f958a5c0ceee2fd5634772af3 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Apr 2024 09:24:49 +0200 Subject: [PATCH 34/56] Fixed test --- commands/service_platform_search_test.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/commands/service_platform_search_test.go b/commands/service_platform_search_test.go index dc7df5f190c..0e98b28fe59 100644 --- a/commands/service_platform_search_test.go +++ b/commands/service_platform_search_test.go @@ -38,12 +38,7 @@ func TestPlatformSearch(t *testing.T) { ctx := context.Background() srv := NewArduinoCoreServer() - conf, err := paths.TempDir().Join("test", "arduino-cli.yaml").ReadFile() - require.NoError(t, err) - _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{ - SettingsFormat: "yaml", - EncodedSettings: string(conf), - }) + _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{SettingsFormat: "yaml"}) require.NoError(t, err) createResp, err := srv.Create(ctx, &rpc.CreateRequest{}) @@ -347,12 +342,7 @@ func TestPlatformSearchSorting(t *testing.T) { ctx := context.Background() srv := NewArduinoCoreServer() - conf, err := paths.TempDir().Join("test", "arduino-cli.yaml").ReadFile() - require.NoError(t, err) - _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{ - SettingsFormat: "yaml", - EncodedSettings: string(conf), - }) + _, err = srv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{SettingsFormat: "yaml"}) require.NoError(t, err) createResp, err := srv.Create(ctx, &rpc.CreateRequest{}) From 087a6f56e5460d99400e1f81a9178b16ca344819 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Apr 2024 12:06:19 +0200 Subject: [PATCH 35/56] Fixed FindConfigFileInArgsFallbackOnEnv unit test --- internal/cli/configuration/configuration_test.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/cli/configuration/configuration_test.go b/internal/cli/configuration/configuration_test.go index 68d6ab682d4..23af3a964e1 100644 --- a/internal/cli/configuration/configuration_test.go +++ b/internal/cli/configuration/configuration_test.go @@ -16,6 +16,7 @@ package configuration import ( + "path/filepath" "testing" "github.com/stretchr/testify/require" @@ -41,8 +42,9 @@ func TestInit(t *testing.T) { } func TestFindConfigFile(t *testing.T) { + defaultConfigFile := filepath.Join(getDefaultArduinoDataDir(), "arduino-cli.yaml") configFile := FindConfigFileInArgsFallbackOnEnv([]string{"--config-file"}) - require.Equal(t, "", configFile) + require.Equal(t, defaultConfigFile, configFile) configFile = FindConfigFileInArgsFallbackOnEnv([]string{"--config-file", "some/path/to/config"}) require.Equal(t, "some/path/to/config", configFile) @@ -51,7 +53,7 @@ func TestFindConfigFile(t *testing.T) { require.Equal(t, "some/path/to/config/arduino-cli.yaml", configFile) configFile = FindConfigFileInArgsFallbackOnEnv([]string{}) - require.Equal(t, "", configFile) + require.Equal(t, defaultConfigFile, configFile) t.Setenv("ARDUINO_CONFIG_FILE", "some/path/to/config") configFile = FindConfigFileInArgsFallbackOnEnv([]string{}) From 9cd9c979b3dc1d0dab661b0bf3ee6cd67d0a8c4d Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Apr 2024 12:07:53 +0200 Subject: [PATCH 36/56] Fixed TestUserAgentHeader and TestProxy --- .golangci.yml | 2 ++ internal/cli/configuration/defaults.go | 4 ++++ internal/cli/configuration/network_test.go | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index a4057e492c6..a80fe164d7e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -134,5 +134,7 @@ issues: - path-except: internal/cli/ linters: - forbidigo + - path: internal/cli/.*_test.go + linters: [forbidigo] - path: internal/cli/feedback/ linters: [forbidigo] diff --git a/internal/cli/configuration/defaults.go b/internal/cli/configuration/defaults.go index a47538dd298..50e0faf771b 100644 --- a/internal/cli/configuration/defaults.go +++ b/internal/cli/configuration/defaults.go @@ -64,6 +64,10 @@ func SetDefaults(settings *Settings) { // updater settings setDefaultValueAndKeyTypeSchema("updater.enable_notification", true) + + // network settings + setKeyTypeSchema("network.proxy", "") + setKeyTypeSchema("network.user_agent_ext", "") } // InjectEnvVars change settings based on the environment variables values diff --git a/internal/cli/configuration/network_test.go b/internal/cli/configuration/network_test.go index ba713394d34..6c8a7def80d 100644 --- a/internal/cli/configuration/network_test.go +++ b/internal/cli/configuration/network_test.go @@ -33,7 +33,7 @@ func TestUserAgentHeader(t *testing.T) { defer ts.Close() settings := configuration.NewSettings() - settings.Set("network.user_agent_ext", "test-user-agent") + require.NoError(t, settings.Set("network.user_agent_ext", "test-user-agent")) client, err := settings.NewHttpClient() require.NoError(t, err) @@ -46,6 +46,7 @@ func TestUserAgentHeader(t *testing.T) { b, err := io.ReadAll(response.Body) require.NoError(t, err) + fmt.Println("RESPONSE:", string(b)) require.Contains(t, string(b), "test-user-agent") } From 384c30c86c39a85b5cb24f7dfe8c1411edbf88ba Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 21 Apr 2024 18:01:18 +0200 Subject: [PATCH 37/56] Improved error message --- internal/go-configmap/configuration.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/go-configmap/configuration.go b/internal/go-configmap/configuration.go index fa504a272bd..5ea74eac983 100644 --- a/internal/go-configmap/configuration.go +++ b/internal/go-configmap/configuration.go @@ -109,7 +109,12 @@ func tryConversion(current any, desiredType reflect.Type) (any, error) { } return currentArray, nil } - return nil, fmt.Errorf("invalid conversion, got %T but want %v", current, desiredType) + + currentTypeString := currentType.String() + if currentTypeString == "[]interface {}" { + currentTypeString = "array" + } + return nil, fmt.Errorf("invalid conversion, got %s but want %v", currentTypeString, desiredType) } func (c Map) set(keys []string, value any) { From 6aa742ff40997e0c1df5361bc09e046914f46db6 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 21 Apr 2024 18:02:18 +0200 Subject: [PATCH 38/56] Config set adds only unique values --- internal/algorithms/slices.go | 14 ++++++++++++++ internal/cli/config/set.go | 5 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/internal/algorithms/slices.go b/internal/algorithms/slices.go index ab904a97f94..90ea3d1984b 100644 --- a/internal/algorithms/slices.go +++ b/internal/algorithms/slices.go @@ -71,3 +71,17 @@ func NotEquals[T comparable](value T) Matcher[T] { return x != value } } + +// Uniq return a copy of the input array with all duplicates removed +func Uniq[T comparable](in []T) []T { + have := map[T]bool{} + var out []T + for _, v := range in { + if have[v] { + continue + } + out = append(out, v) + have[v] = true + } + return out +} diff --git a/internal/cli/config/set.go b/internal/cli/config/set.go index dd219ba1918..a722f3f176b 100644 --- a/internal/cli/config/set.go +++ b/internal/cli/config/set.go @@ -20,6 +20,7 @@ import ( "encoding/json" "os" + f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/sirupsen/logrus" @@ -59,8 +60,8 @@ func runSetCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args [ req.EncodedValue = args[1] req.ValueFormat = "cli" } else { - // Array - jsonValues, err := json.Marshal(args[1:]) + // Uniq Array + jsonValues, err := json.Marshal(f.Uniq(args[1:])) if err != nil { feedback.Fatal(tr("Error setting value: %v", err), feedback.ErrGeneric) } From 0aafda3a00f5d986cceb989e5512a56072ac4b28 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 21 Apr 2024 18:04:07 +0200 Subject: [PATCH 39/56] Fixed initialization sequence for 'config init' command --- internal/cli/cli.go | 16 +------- internal/cli/config/config.go | 2 +- internal/cli/config/init.go | 70 +++++++++++++++++++++++++++++------ 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index aa59dfe36ba..de4832318f5 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -17,7 +17,6 @@ package cli import ( "context" - "encoding/json" "fmt" "io" "os" @@ -81,6 +80,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { defaultLogFile := settings.GetLogging().GetFile() defaultLogFormat := settings.GetLogging().GetFormat() + defaultLogLevel := settings.GetLogging().GetLevel() defaultAdditionalURLs := settings.GetBoardManager().GetAdditionalUrls() defaultOutputNoColor := settings.GetOutput().GetNoColor() @@ -92,18 +92,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { PersistentPreRun: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() - // Override server settings with the flags from the command line - set := func(key string, value any) { - if valueJson, err := json.Marshal(value); err != nil { - feedback.Fatal(tr("Error setting value %s: %v", key, err), feedback.ErrGeneric) - } else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{Key: key, EncodedValue: string(valueJson)}); err != nil { - feedback.Fatal(tr("Error setting value %s: %v", key, err), feedback.ErrGeneric) - } - } - set("logging.level", logLevel) - set("logging.file", logFile) - set("board_manager.additional_urls", additionalUrls) - set("output.no_color", noColor) + config.ApplyGlobalFlagsToConfiguration(ctx, cmd, srv) if jsonOutput { outputFormat = "json" @@ -178,7 +167,6 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { cmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, tr("Print the logs on the standard output.")) cmd.Flag("verbose").Hidden = true cmd.PersistentFlags().BoolVar(&verbose, "log", false, tr("Print the logs on the standard output.")) - defaultLogLevel := settings.GetLogging().GetLevel() validLogLevels := []string{"trace", "debug", "info", "warn", "error", "fatal", "panic"} cmd.PersistentFlags().StringVar(&logLevel, "log-level", defaultLogLevel, tr("Messages with this level and above will be logged. Valid levels are: %s", strings.Join(validLogLevels, ", "))) cmd.RegisterFlagCompletionFunc("log-level", cobra.FixedCompletions(validLogLevels, cobra.ShellCompDirectiveDefault)) diff --git a/internal/cli/config/config.go b/internal/cli/config/config.go index df71ea93634..2662befe322 100644 --- a/internal/cli/config/config.go +++ b/internal/cli/config/config.go @@ -42,7 +42,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) * configCommand.AddCommand(initDeleteCommand(srv)) configCommand.AddCommand(initDumpCommand(srv)) configCommand.AddCommand(initGetCommand(srv)) - configCommand.AddCommand(initInitCommand(srv)) + configCommand.AddCommand(initInitCommand()) configCommand.AddCommand(initRemoveCommand(srv)) configCommand.AddCommand(initSetCommand(srv)) diff --git a/internal/cli/config/init.go b/internal/cli/config/init.go index 5fe25273bd4..4e297fda7c5 100644 --- a/internal/cli/config/init.go +++ b/internal/cli/config/init.go @@ -17,8 +17,11 @@ package config import ( "context" + "encoding/json" "os" + "strings" + "github.com/arduino/arduino-cli/commands" "github.com/arduino/arduino-cli/internal/cli/arguments" "github.com/arduino/arduino-cli/internal/cli/feedback" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" @@ -35,7 +38,7 @@ var ( const defaultFileName = "arduino-cli.yaml" -func initInitCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { +func initInitCommand() *cobra.Command { initCommand := &cobra.Command{ Use: "init", Short: tr("Writes current configuration to a configuration file."), @@ -50,7 +53,7 @@ func initInitCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { arguments.CheckFlagsConflicts(cmd, "dest-file", "dest-dir") }, Run: func(cmd *cobra.Command, args []string) { - runInitCommand(srv) + runInitCommand(cmd.Context(), cmd) }, } initCommand.Flags().StringVar(&destDir, "dest-dir", "", tr("Sets where to save the configuration file.")) @@ -59,9 +62,8 @@ func initInitCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return initCommand } -func runInitCommand(srv rpc.ArduinoCoreServiceServer) { +func runInitCommand(ctx context.Context, cmd *cobra.Command) { logrus.Info("Executing `arduino-cli config init`") - ctx := context.Background() var configFileAbsPath *paths.Path var configFileDir *paths.Path @@ -97,14 +99,22 @@ func runInitCommand(srv rpc.ArduinoCoreServiceServer) { feedback.Fatal(tr("Cannot create config file directory: %v", err), feedback.ErrGeneric) } - // for _, url := range newSettings.GetStringSlice("board_manager.additional_urls") { - // if strings.Contains(url, ",") { - // feedback.Fatal(tr("Urls cannot contain commas. Separate multiple urls exported as env var with a space:\n%s", url), - // feedback.ErrGeneric) - // } - // } + tmpSrv := commands.NewArduinoCoreServer() - resp, err := srv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"}) + if _, err := tmpSrv.ConfigurationOpen(ctx, &rpc.ConfigurationOpenRequest{SettingsFormat: "yaml", EncodedSettings: ""}); err != nil { + feedback.Fatal(tr("Error creating configuration: %v", err), feedback.ErrGeneric) + } + + // Ensure to always output an empty array for additional urls + if _, err := tmpSrv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{ + Key: "board_manager.additional_urls", EncodedValue: "[]", + }); err != nil { + feedback.Fatal(tr("Error creating configuration: %v", err), feedback.ErrGeneric) + } + + ApplyGlobalFlagsToConfiguration(ctx, cmd, tmpSrv) + + resp, err := tmpSrv.ConfigurationSave(ctx, &rpc.ConfigurationSaveRequest{SettingsFormat: "yaml"}) if err != nil { feedback.Fatal(tr("Error creating configuration: %v", err), feedback.ErrGeneric) } @@ -116,6 +126,44 @@ func runInitCommand(srv rpc.ArduinoCoreServiceServer) { feedback.PrintResult(initResult{ConfigFileAbsPath: configFileAbsPath}) } +// ApplyGlobalFlagsToConfiguration overrides server settings with the flags from the command line +func ApplyGlobalFlagsToConfiguration(ctx context.Context, cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { + set := func(k string, v any) { + if jsonValue, err := json.Marshal(v); err != nil { + feedback.Fatal(tr("Error creating configuration: %v", err), feedback.ErrGeneric) + } else if _, err := srv.SettingsSetValue(ctx, &rpc.SettingsSetValueRequest{ + Key: k, EncodedValue: string(jsonValue), + }); err != nil { + feedback.Fatal(tr("Error creating configuration: %v", err), feedback.ErrGeneric) + } + + } + + if f := cmd.Flags().Lookup("log-level"); f.Changed { + logLevel, _ := cmd.Flags().GetString("log-level") + set("logging.level", logLevel) + } + if f := cmd.Flags().Lookup("log-file"); f.Changed { + logFile, _ := cmd.Flags().GetString("log-file") + set("logging.file", logFile) + } + if f := cmd.Flags().Lookup("no-color"); f.Changed { + noColor, _ := cmd.Flags().GetBool("no-color") + set("output.no_color", noColor) + } + if f := cmd.Flags().Lookup("additional-urls"); f.Changed { + urls, _ := cmd.Flags().GetStringSlice("additional-urls") + for _, url := range urls { + if strings.Contains(url, ",") { + feedback.Fatal( + tr("Urls cannot contain commas. Separate multiple urls exported as env var with a space:\n%s", url), + feedback.ErrBadArgument) + } + } + set("board_manager.additional_urls", urls) + } +} + // output from this command requires special formatting, let's create a dedicated // feedback.Result implementation type initResult struct { From 921fa61acaca0a11035b292b16fcc7116927b1f0 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 21 Apr 2024 18:04:59 +0200 Subject: [PATCH 40/56] Config search now looks into ARDUINO_DIRECTORIES_DATA env too --- internal/cli/configuration/configuration.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/cli/configuration/configuration.go b/internal/cli/configuration/configuration.go index 672cbb466df..5176acc9a28 100644 --- a/internal/cli/configuration/configuration.go +++ b/internal/cli/configuration/configuration.go @@ -109,5 +109,11 @@ func FindConfigFileInArgsFallbackOnEnv(args []string) string { if p, ok := os.LookupEnv("ARDUINO_CONFIG_FILE"); ok { return p } + if p, ok := os.LookupEnv("ARDUINO_DIRECTORIES_DATA"); ok { + return filepath.Join(p, "arduino-cli.yaml") + } + if p, ok := os.LookupEnv("ARDUINO_DATA_DIR"); ok { + return filepath.Join(p, "arduino-cli.yaml") + } return filepath.Join(getDefaultArduinoDataDir(), "arduino-cli.yaml") } From ad8dbd9e7d1edf60ee95b97d47fe16ea1066e78a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 21 Apr 2024 18:05:23 +0200 Subject: [PATCH 41/56] Fixed all config* integration test --- internal/cli/configuration/defaults.go | 3 + .../integrationtest/config/config_test.go | 111 ++++++++---------- 2 files changed, 54 insertions(+), 60 deletions(-) diff --git a/internal/cli/configuration/defaults.go b/internal/cli/configuration/defaults.go index 50e0faf771b..46961e6979e 100644 --- a/internal/cli/configuration/defaults.go +++ b/internal/cli/configuration/defaults.go @@ -68,6 +68,9 @@ func SetDefaults(settings *Settings) { // network settings setKeyTypeSchema("network.proxy", "") setKeyTypeSchema("network.user_agent_ext", "") + + // locale + setDefaultValueAndKeyTypeSchema("locale", "en") } // InjectEnvVars change settings based on the environment variables values diff --git a/internal/integrationtest/config/config_test.go b/internal/integrationtest/config/config_test.go index 107141ccfb4..2742a7205f3 100644 --- a/internal/integrationtest/config/config_test.go +++ b/internal/integrationtest/config/config_test.go @@ -50,15 +50,6 @@ func TestInitWithExistingCustomConfig(t *testing.T) { err = yaml.Unmarshal(configFile, config) require.NoError(t, err) require.Equal(t, config["board_manager"]["additional_urls"].([]interface{})[0].(string), "https://example.com") - require.Equal(t, config["daemon"]["port"].(string), "50051") - require.Equal(t, config["directories"]["data"].(string), cli.DataDir().String()) - require.Equal(t, config["directories"]["downloads"].(string), cli.DownloadDir().String()) - require.Equal(t, config["directories"]["user"].(string), cli.SketchbookDir().String()) - require.Empty(t, config["logging"]["file"]) - require.Equal(t, config["logging"]["format"].(string), "text") - require.Equal(t, config["logging"]["level"].(string), "info") - require.Equal(t, config["metrics"]["addr"].(string), ":9090") - require.True(t, config["metrics"]["enabled"].(bool)) configFilePath := cli.WorkingDir().Join("config", "test", "config.yaml") require.NoFileExists(t, configFilePath.String()) @@ -71,15 +62,6 @@ func TestInitWithExistingCustomConfig(t *testing.T) { err = yaml.Unmarshal(configFile, config) require.NoError(t, err) require.Empty(t, config["board_manager"]["additional_urls"]) - require.Equal(t, config["daemon"]["port"].(string), "50051") - require.Equal(t, config["directories"]["data"].(string), cli.DataDir().String()) - require.Equal(t, config["directories"]["downloads"].(string), cli.DownloadDir().String()) - require.Equal(t, config["directories"]["user"].(string), cli.SketchbookDir().String()) - require.Empty(t, config["logging"]["file"]) - require.Equal(t, config["logging"]["format"].(string), "text") - require.Equal(t, config["logging"]["level"].(string), "info") - require.Equal(t, config["metrics"]["addr"].(string), ":9090") - require.True(t, config["metrics"]["enabled"].(bool)) } func TestInitOverwriteExistingCustomFile(t *testing.T) { @@ -96,15 +78,6 @@ func TestInitOverwriteExistingCustomFile(t *testing.T) { err = yaml.Unmarshal(configFile, config) require.NoError(t, err) require.Equal(t, config["board_manager"]["additional_urls"].([]interface{})[0].(string), "https://example.com") - require.Equal(t, config["daemon"]["port"].(string), "50051") - require.Equal(t, config["directories"]["data"].(string), cli.DataDir().String()) - require.Equal(t, config["directories"]["downloads"].(string), cli.DownloadDir().String()) - require.Equal(t, config["directories"]["user"].(string), cli.SketchbookDir().String()) - require.Empty(t, config["logging"]["file"]) - require.Equal(t, config["logging"]["format"].(string), "text") - require.Equal(t, config["logging"]["level"].(string), "info") - require.Equal(t, config["metrics"]["addr"].(string), ":9090") - require.True(t, config["metrics"]["enabled"].(bool)) stdout, _, err = cli.Run("config", "init", "--overwrite") require.NoError(t, err) @@ -115,15 +88,6 @@ func TestInitOverwriteExistingCustomFile(t *testing.T) { err = yaml.Unmarshal(configFile, config) require.NoError(t, err) require.Empty(t, config["board_manager"]["additional_urls"]) - require.Equal(t, config["daemon"]["port"].(string), "50051") - require.Equal(t, config["directories"]["data"].(string), cli.DataDir().String()) - require.Equal(t, config["directories"]["downloads"].(string), cli.DownloadDir().String()) - require.Equal(t, config["directories"]["user"].(string), cli.SketchbookDir().String()) - require.Empty(t, config["logging"]["file"]) - require.Equal(t, config["logging"]["format"].(string), "text") - require.Equal(t, config["logging"]["level"].(string), "info") - require.Equal(t, config["metrics"]["addr"].(string), ":9090") - require.True(t, config["metrics"]["enabled"].(bool)) } func TestInitDestAbsolutePath(t *testing.T) { @@ -289,21 +253,37 @@ func TestAddRemoveSetDeleteOnUnexistingKey(t *testing.T) { _, _, err := cli.Run("config", "init", "--dest-dir", ".") require.NoError(t, err) - _, stderr, err := cli.Run("config", "add", "some.key", "some_value", "--config-file", "arduino-cli.yaml") - require.Error(t, err) - require.Contains(t, string(stderr), "Settings key doesn't exist") + j, _, err := cli.Run("config", "dump", "--format", "json", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + requirejson.Contains(t, j, `{"config":{ "board_manager": {"additional_urls":[]} } }`) - _, stderr, err = cli.Run("config", "remove", "some.key", "some_value", "--config-file", "arduino-cli.yaml") - require.Error(t, err) - require.Contains(t, string(stderr), "Settings key doesn't exist") + // Delete array key + _, _, err = cli.Run("config", "delete", "board_manager.additional_urls", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + j, _, err = cli.Run("config", "dump", "--format", "json", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + requirejson.NotContains(t, j, `{"config":{ "board_manager": {"additional_urls":[]} } }`) - _, stderr, err = cli.Run("config", "set", "some.key", "some_value", "--config-file", "arduino-cli.yaml") - require.Error(t, err) - require.Contains(t, string(stderr), "Settings key doesn't exist") + // Add to non-existing array key + _, _, err = cli.Run("config", "add", "board_manager.additional_urls", "some_value", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + j, _, err = cli.Run("config", "dump", "--format", "json", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + requirejson.Contains(t, j, `{"config":{ "board_manager": {"additional_urls":["some_value"]} } }`) - _, stderr, err = cli.Run("config", "delete", "some.key", "--config-file", "arduino-cli.yaml") - require.Error(t, err) - require.Contains(t, string(stderr), "Cannot delete the key some.key: key not found in settings\n") + // Remove from non-existing array key + _, _, err = cli.Run("config", "remove", "board_manager.additional_urls", "some_value", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + j, _, err = cli.Run("config", "dump", "--format", "json", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + requirejson.NotContains(t, j, `{"config":{ "board_manager": {"additional_urls":["some_value"]} } }`) + + // Set on non-existing key + _, _, err = cli.Run("config", "set", "board_manager.additional_urls", "some_value", "other_value", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + j, _, err = cli.Run("config", "dump", "--format", "json", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) + requirejson.Contains(t, j, `{"config":{ "board_manager": {"additional_urls":["some_value","other_value"]} } }`) } func TestAddSingleArgument(t *testing.T) { @@ -434,6 +414,8 @@ func TestAddOnUnsupportedKey(t *testing.T) { // Create a config file _, _, err := cli.Run("config", "init", "--dest-dir", ".") require.NoError(t, err) + _, _, err = cli.Run("config", "set", "daemon.port", "50051", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) // Verifies default value stdout, _, err := cli.Run("config", "dump", "--json", "--config-file", "arduino-cli.yaml") @@ -542,6 +524,8 @@ func TestRemoveOnUnsupportedKey(t *testing.T) { // Create a config file _, _, err := cli.Run("config", "init", "--dest-dir", ".") require.NoError(t, err) + _, _, err = cli.Run("config", "set", "daemon.port", "50051", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) // Verifies default value stdout, _, err := cli.Run("config", "dump", "--json", "--config-file", "arduino-cli.yaml") @@ -700,7 +684,7 @@ func TestSetStringWithSingleArgument(t *testing.T) { // Verifies default state stdout, _, err := cli.Run("config", "dump", "--json", "--config-file", "arduino-cli.yaml") require.NoError(t, err) - requirejson.Query(t, stdout, ".config | .logging | .level", "\"info\"") + requirejson.NotContains(t, stdout, `{"config":{"logging":{"level"}}}`) // Changes value _, _, err = cli.Run("config", "set", "logging.level", "trace", "--config-file", "arduino-cli.yaml") @@ -723,12 +707,12 @@ func TestSetStringWithMultipleArguments(t *testing.T) { // Verifies default state stdout, _, err := cli.Run("config", "dump", "--json", "--config-file", "arduino-cli.yaml") require.NoError(t, err) - requirejson.Query(t, stdout, ".config | .logging | .level", "\"info\"") + requirejson.NotContains(t, stdout, `{"config":{"logging":{"level"}}}`) // Tries to change value _, stderr, err := cli.Run("config", "set", "logging.level", "trace", "debug") require.Error(t, err) - require.Contains(t, string(stderr), "Can't set multiple values in key logging.level") + require.Contains(t, string(stderr), "Error setting value: invalid type for key 'logging.level': invalid conversion, got array but want string") } func TestSetBoolWithSingleArgument(t *testing.T) { @@ -742,7 +726,7 @@ func TestSetBoolWithSingleArgument(t *testing.T) { // Verifies default state stdout, _, err := cli.Run("config", "dump", "--json", "--config-file", "arduino-cli.yaml") require.NoError(t, err) - requirejson.Query(t, stdout, ".config | .library | .enable_unsafe_install", "false") + requirejson.NotContains(t, stdout, `{"config": {"library": {"enable_unsafe_install"}}}`) // Changes value _, _, err = cli.Run("config", "set", "library.enable_unsafe_install", "true", "--config-file", "arduino-cli.yaml") @@ -761,6 +745,8 @@ func TestSetBoolWithMultipleArguments(t *testing.T) { // Create a config file _, _, err := cli.Run("config", "init", "--dest-dir", ".") require.NoError(t, err) + _, _, err = cli.Run("config", "set", "library.enable_unsafe_install", "false", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) // Verifies default state stdout, _, err := cli.Run("config", "dump", "--json", "--config-file", "arduino-cli.yaml") @@ -770,7 +756,7 @@ func TestSetBoolWithMultipleArguments(t *testing.T) { // Changes value _, stderr, err := cli.Run("config", "set", "library.enable_unsafe_install", "true", "foo", "--config-file", "arduino-cli.yaml") require.Error(t, err) - require.Contains(t, string(stderr), "Can't set multiple values in key library.enable_unsafe_install") + require.Contains(t, string(stderr), "Error setting value: invalid type for key 'library.enable_unsafe_install': invalid conversion, got array but want bool") } func TestDelete(t *testing.T) { @@ -780,6 +766,8 @@ func TestDelete(t *testing.T) { // Create a config file _, _, err := cli.Run("config", "init", "--dest-dir", ".") require.NoError(t, err) + _, _, err = cli.Run("config", "set", "library.enable_unsafe_install", "false", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) // Verifies default state stdout, _, err := cli.Run("config", "dump", "--json", "--config-file", "arduino-cli.yaml") @@ -824,6 +812,8 @@ func TestGet(t *testing.T) { // Create a config file _, _, err := cli.Run("config", "init", "--dest-dir", ".") require.NoError(t, err) + _, _, err = cli.Run("config", "set", "daemon.port", "50051", "--config-file", "arduino-cli.yaml") + require.NoError(t, err) // Verifies default state stdout, _, err := cli.Run("config", "dump", "--json", "--config-file", "arduino-cli.yaml") @@ -843,7 +833,7 @@ func TestGet(t *testing.T) { // Get undefined key _, stderr, err := cli.Run("config", "get", "foo", "--json", "--config-file", "arduino-cli.yaml") require.Error(t, err) - requirejson.Contains(t, stderr, `{"error":"Cannot get the configuration key foo: key not found in settings"}`) + requirejson.Contains(t, stderr, `{"error":"Cannot get the configuration key foo: key foo not found"}`) } func TestInitializationOrderOfConfigThroughFlagAndEnv(t *testing.T) { @@ -851,9 +841,10 @@ func TestInitializationOrderOfConfigThroughFlagAndEnv(t *testing.T) { defer env.CleanUp() tmp := t.TempDir() - cliConfig, envConfig := paths.New(filepath.Join(tmp, "cli.yaml")), paths.New(filepath.Join(tmp, "env.yaml")) - cliConfig.WriteFile([]byte(`cli-test: "test"`)) - envConfig.WriteFile([]byte(`env-test: "test"`)) + cliConfig := paths.New(filepath.Join(tmp, "cli.yaml")) + cliConfig.WriteFile([]byte(`locale: "test"`)) + envConfig := paths.New(filepath.Join(tmp, "env.yaml")) + envConfig.WriteFile([]byte(`locale: "test2"`)) // No flag nor env specified. stdout, _, err := cli.Run("config", "dump", "--json") @@ -863,16 +854,16 @@ func TestInitializationOrderOfConfigThroughFlagAndEnv(t *testing.T) { // Flag specified stdout, _, err = cli.Run("config", "dump", "--config-file", cliConfig.String(), "--json") require.NoError(t, err) - requirejson.Contains(t, stdout, `{"config":{ "cli-test": "test" }}`) + requirejson.Contains(t, stdout, `{"config":{ "locale": "test" }}`) // Env specified customEnv := map[string]string{"ARDUINO_CONFIG_FILE": envConfig.String()} stdout, _, err = cli.RunWithCustomEnv(customEnv, "config", "dump", "--json") require.NoError(t, err) - requirejson.Contains(t, stdout, `{"config":{ "env-test": "test" }}`) + requirejson.Contains(t, stdout, `{"config":{ "locale": "test2" }}`) // Flag and env specified, flag takes precedence stdout, _, err = cli.RunWithCustomEnv(customEnv, "config", "dump", "--config-file", cliConfig.String(), "--json") require.NoError(t, err) - requirejson.Contains(t, stdout, `{"config":{ "cli-test": "test" }}`) + requirejson.Contains(t, stdout, `{"config":{ "locale": "test" }}`) } From 4061131fff567b11eb19e725d4e59a6de8c68f8b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sun, 21 Apr 2024 23:34:28 +0200 Subject: [PATCH 42/56] Added missing type schema --- internal/cli/configuration/defaults.go | 1 + internal/integrationtest/daemon/daemon_test.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/cli/configuration/defaults.go b/internal/cli/configuration/defaults.go index 46961e6979e..8c05b793d19 100644 --- a/internal/cli/configuration/defaults.go +++ b/internal/cli/configuration/defaults.go @@ -46,6 +46,7 @@ func SetDefaults(settings *Settings) { setDefaultValueAndKeyTypeSchema("directories.data", getDefaultArduinoDataDir()) setDefaultValueAndKeyTypeSchema("directories.downloads", "") setDefaultValueAndKeyTypeSchema("directories.user", getDefaultUserDir()) + setKeyTypeSchema("directories.builtin.libraries", "") // Sketch compilation setDefaultValueAndKeyTypeSchema("sketch.always_export_binaries", false) diff --git a/internal/integrationtest/daemon/daemon_test.go b/internal/integrationtest/daemon/daemon_test.go index f994813b69e..08e60cffccf 100644 --- a/internal/integrationtest/daemon/daemon_test.go +++ b/internal/integrationtest/daemon/daemon_test.go @@ -357,7 +357,7 @@ func TestDaemonBundleLibInstall(t *testing.T) { } // Un-Set builtin libraries dir - err := cli.SetValue("directories.builtin.libraries", `""`) + err := cli.SetValue("directories.builtin.libraries", "") require.NoError(t, err) // Re-init From fa835de3bd81d9e73eb466469aafed9f9c3dddae Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 23 Apr 2024 12:40:53 +0200 Subject: [PATCH 43/56] Added docs --- docs/UPGRADING.md | 163 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md index 8e5f0967ffc..f30e270530b 100644 --- a/docs/UPGRADING.md +++ b/docs/UPGRADING.md @@ -4,6 +4,169 @@ Here you can find a list of migration guides to handle breaking changes between ## 0.36.0 +### gRPC Setting API important changes + +The Settings API has been heavily refactored. Here a quick recap of the new methods: + +- `SettingsGetValue` returns the value of a setting given the key. The returned value is a string encoded in JSON, or + YAML + + ```proto + message SettingsGetValueRequest { + // The key to get + string key = 1; + // The format of the encoded_value (default is + // "json", allowed values are "json" and "yaml) + string value_format = 2; + } + + message SettingsGetValueResponse { + // The value of the key (encoded) + string encoded_value = 1; + } + ``` + +- `SettingsSetValue` change the value of a setting. The value may be specified in JSON, YAML, or as a command-line + argument. If `encoded_value` is an empty string the setting is deleted. + + ```proto + message SettingsSetValueRequest { + // The key to change + string key = 1; + // The new value (encoded), no objects, + // only scalar, or array of scalars are + // allowed. + string encoded_value = 2; + // The format of the encoded_value (default is + // "json", allowed values are "json", "yaml", + // and "cli") + string value_format = 3; + } + ``` + +- `SettingsEnumerate` returns all the available keys and their type (`string`, `int`, `[]string`...) +- `ConfigurationOpen` replaces the current configuration with the one passed as argument. Differently from + `SettingsSetValue`, this call replaces the whole configuration. +- `ConfigurationSave` outputs the current configuration in the specified format. The configuration is not saved in a + file, this call returns just the content, it's a duty of the caller to store the content in a file. +- `ConfigurationGet` return the current configuration in a structured gRPC message `Configuration`. + +The previous gRPC Setting rpc call may be replaced as follows: + +- The old `SettingsMerge` rpc call can now be done trough `SettingsSetValue`. +- The old `SettingsDelete` rpc call can now be done trough `SettingsSetValue` passing the `key` to delete with an empty + `value`. +- The old `SettingsGetAll` rpc call has been replaced by `ConfigurationGet` that returns a structured message + `Configuration` with all the settings populated. +- The old `SettingsWrite` rpc call has been removed. It is partially replaced by `ConfigurationSave` but the actual file + save must be performed by the caller. + +### golang: importing `arduino-cli` as a library now requires the creation of a gRPC service. + +Previously the methods implementing the Arduino business logic were available in the global namespace +`github.com/arduino/arduino-cli/commands/*` and could be called directly. + +The above is no more true. All the global `commands.*` functions have been converted to methods of the +`arduinoCoreServerImpl` struct that implements the gRPC `ArduinoCoreServer` interface. The configuration is now part of +the server internal state. Developers may create a "daemon-less" server by calling the `commands.NewArduinoCoreServer()` +function and can use the returned object to call all the needed gRPC functions. + +The methods of the `ArduinoCoreServer` are generated through the gRPC protobuf definitions, some of those methods are +gRPC "streaming" methods and requires a streaming object to be passed as argument, we provided helper methods to create +these objects. + +For example if previously we could call `commands.Init` like this: + +```go +// old Init signature +func Init(req *rpc.InitRequest, responseCallback func(r *rpc.InitResponse)) error { ... } + +// ... + +// Initialize instance +if err := commands.Init(&rpc.InitRequest{Instance: req.GetInstance()}, respCB); err != nil { + return err +} +``` + +now the `responseCallback` must be wrapped into an `rpc.ArduinoCoreService_InitServer`, and we provided a method exactly +for that: + +```go +// new Init method +func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCoreService_InitServer) error { ... } + +/// ... + +// Initialize instance +initStream := InitStreamResponseToCallbackFunction(ctx, respCB) +if err := srv.Init(&rpc.InitRequest{Instance: req.GetInstance()}, initStream); err != nil { + return err +} +``` + +Each gRPC method has an helper method to obtain the corresponding `ArduinoCoreService_*Server` parameter. Here a simple, +but complete, example: + +```go +package main + +import ( + "context" + "fmt" + "io" + "log" + + "github.com/arduino/arduino-cli/commands" + rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" + "github.com/sirupsen/logrus" +) + +func main() { + // Create a new ArduinoCoreServer + srv := commands.NewArduinoCoreServer() + + // Disable logging + logrus.SetOutput(io.Discard) + + // Create a new instance in the server + ctx := context.Background() + resp, err := srv.Create(ctx, &rpc.CreateRequest{}) + if err != nil { + log.Fatal("Error creating instance:", err) + } + instance := resp.GetInstance() + + // Defer the destruction of the instance + defer func() { + if _, err := srv.Destroy(ctx, &rpc.DestroyRequest{Instance: instance}); err != nil { + log.Fatal("Error destroying instance:", err) + } + fmt.Println("Instance successfully destroyed") + }() + + // Initialize the instance + initStream := commands.InitStreamResponseToCallbackFunction(ctx, func(r *rpc.InitResponse) error { + fmt.Println("INIT> ", r) + return nil + }) + if err := srv.Init(&rpc.InitRequest{Instance: instance}, initStream); err != nil { + log.Fatal("Error during initialization:", err) + } + + // Search for platforms and output the result + searchResp, err := srv.PlatformSearch(ctx, &rpc.PlatformSearchRequest{Instance: instance}) + if err != nil { + log.Fatal("Error searching for platforms:", err) + } + for _, platformSummary := range searchResp.GetSearchOutput() { + installed := platformSummary.GetInstalledRelease() + meta := platformSummary.GetMetadata() + fmt.Printf("%30s %8s %s\n", meta.GetId(), installed.GetVersion(), installed.GetName()) + } +} +``` + ### YAML output format is no more supported The `yaml` option of the `--format` flag is no more supported. Use `--format json` if machine parsable output is needed. From 72e05eeb805e89ac11b7bc26f51c71059320c424 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 30 Apr 2024 01:14:28 +0200 Subject: [PATCH 44/56] Updated documentation about configuration file format --- docs/UPGRADING.md | 4 ++++ docs/configuration.md | 24 ++++-------------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md index f30e270530b..1273fa0a455 100644 --- a/docs/UPGRADING.md +++ b/docs/UPGRADING.md @@ -4,6 +4,10 @@ Here you can find a list of migration guides to handle breaking changes between ## 0.36.0 +### Configuration file now supports only YAML format. + +The Arduino CLI configuration file now supports only the YAML format. + ### gRPC Setting API important changes The Settings API has been heavily refactored. Here a quick recap of the new methods: diff --git a/docs/configuration.md b/docs/configuration.md index 57bda320635..bfde1372dac 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -97,8 +97,7 @@ $ export ARDUINO_BOARD_MANAGER_ADDITIONAL_URLS="https://downloads.arduino.cc/pac ### Configuration file -[`arduino-cli config init`][arduino-cli config init] creates or updates a configuration file with the current -configuration settings. +[`arduino-cli config init`][arduino-cli config init] creates a new empty configuration file. This allows saving the options set by command line flags or environment variables. For example: @@ -106,29 +105,14 @@ This allows saving the options set by command line flags or environment variable arduino-cli config init --additional-urls https://downloads.arduino.cc/packages/package_staging_index.json ``` -#### File name - -The configuration file must be named `arduino-cli`, with the appropriate file extension for the file's format. - -#### Supported formats - -`arduino-cli config init` creates a YAML file, however a variety of common formats are supported: - -- [JSON] -- [TOML] -- [YAML] -- [Java properties file] -- [HCL] -- envfile -- [INI] - #### Locations -Configuration files in the following locations are recognized by Arduino CLI: +The default configuration file is named `arduino-cli.yaml`. The configuration file is searched in the following +locations, in order of priority: 1. Location specified by the [`--config-file`][arduino cli command reference] command line flag 1. Location specified by the `ARDUINO_CONFIG_FILE` environment variable -1. Arduino CLI data directory (as configured by `directories.data`) +1. Location specified by the `ARDUINO_DIRECTORIES_DATA` environment variable If multiple configuration files are present, the one highest on the above list is used. Configuration files are not combined. From 89a79cba60561ab16f22654e9bdb230bcae56dbe Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 30 Apr 2024 17:39:47 +0200 Subject: [PATCH 45/56] Fixed a small imperfection in test --- internal/integrationtest/core/core_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/integrationtest/core/core_test.go b/internal/integrationtest/core/core_test.go index 864e45ab710..fbda8da1c0c 100644 --- a/internal/integrationtest/core/core_test.go +++ b/internal/integrationtest/core/core_test.go @@ -101,7 +101,7 @@ func TestCoreSearch(t *testing.T) { checkPlatformIsInJSONOutput := func(stdout []byte, id, version string) { jqquery := fmt.Sprintf(`{"platforms":[{id:"%s", releases:{"%s":{}}}]}`, id, version) - requirejson.Contains(t, out, jqquery, "platform %s@%s is missing from the output", id, version) + requirejson.Contains(t, stdout, jqquery, "platform %s@%s is missing from the output", id, version) } // Search all Retrokit platforms From 240c8b3e5a87aafc6255afdc943326e3ca1a8dc3 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 30 Apr 2024 17:46:39 +0200 Subject: [PATCH 46/56] Pass context in upload and burn-bootloader --- commands/service_upload.go | 7 +++---- commands/service_upload_burnbootloader.go | 1 + commands/service_upload_test.go | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/commands/service_upload.go b/commands/service_upload.go index 2c01f7edaef..6dcacf1d3e5 100644 --- a/commands/service_upload.go +++ b/commands/service_upload.go @@ -188,9 +188,8 @@ func (s *arduinoCoreServerImpl) Upload(req *rpc.UploadRequest, stream rpc.Arduin }) }) defer errStream.Close() - // TODO: inject context - // ctx := stream.Context() updatedPort, err := runProgramAction( + stream.Context(), pme, sk, req.GetImportFile(), @@ -259,7 +258,7 @@ func (s *arduinoCoreServerImpl) UploadUsingProgrammer(req *rpc.UploadUsingProgra }, streamAdapter) } -func runProgramAction(pme *packagemanager.Explorer, +func runProgramAction(ctx context.Context, pme *packagemanager.Explorer, sk *sketch.Sketch, importFile, importDir, fqbnIn string, userPort *rpc.Port, programmerID string, @@ -447,7 +446,7 @@ func runProgramAction(pme *packagemanager.Explorer, } // This context is kept alive for the entire duration of the upload - uploadCtx, uploadCompleted := context.WithCancel(context.Background()) + uploadCtx, uploadCompleted := context.WithCancel(ctx) defer uploadCompleted() // Start the upload port change detector. diff --git a/commands/service_upload_burnbootloader.go b/commands/service_upload_burnbootloader.go index 96352e57fd5..448618b164c 100644 --- a/commands/service_upload_burnbootloader.go +++ b/commands/service_upload_burnbootloader.go @@ -73,6 +73,7 @@ func (s *arduinoCoreServerImpl) BurnBootloader(req *rpc.BurnBootloaderRequest, s defer release() if _, err := runProgramAction( + stream.Context(), pme, nil, // sketch "", // importFile diff --git a/commands/service_upload_test.go b/commands/service_upload_test.go index 7d55f95b48b..d350b5a6470 100644 --- a/commands/service_upload_test.go +++ b/commands/service_upload_test.go @@ -17,6 +17,7 @@ package commands import ( "bytes" + "context" "fmt" "strings" "testing" @@ -186,6 +187,7 @@ func TestUploadPropertiesComposition(t *testing.T) { outStream := &bytes.Buffer{} errStream := &bytes.Buffer{} _, err := runProgramAction( + context.Background(), pme, nil, // sketch "", // importFile From 24ac040537cf2e8dcab1ef788b4af646d8038433 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 30 Apr 2024 18:24:40 +0200 Subject: [PATCH 47/56] Pass down context in all places where it's needed --- commands/instances.go | 8 +++----- internal/arduino/builder/builder.go | 4 ++++ .../builder/internal/detector/detector.go | 12 ++++++++---- .../preprocessor/arduino_preprocessor.go | 5 +++-- .../builder/internal/preprocessor/ctags.go | 9 +++++---- .../arduino/builder/internal/preprocessor/gcc.go | 3 ++- internal/arduino/builder/preprocess_sketch.go | 1 + .../arduino/cores/packagemanager/profiles.go | 13 +++++++------ internal/arduino/resources/index.go | 4 ++-- internal/arduino/resources/resources_test.go | 6 ++++-- internal/cli/arguments/completion.go | 6 +++--- internal/cli/arguments/fqbn.go | 8 ++++---- internal/cli/arguments/port.go | 16 ++++++++-------- internal/cli/arguments/profiles.go | 4 +--- internal/cli/arguments/programmer.go | 6 +++--- internal/cli/board/attach.go | 8 ++++---- internal/cli/board/details.go | 7 +++---- internal/cli/board/list.go | 13 ++++++------- internal/cli/board/listall.go | 7 +++---- internal/cli/board/search.go | 7 +++---- internal/cli/burnbootloader/burnbootloader.go | 9 ++++----- internal/cli/cache/clean.go | 6 +++--- internal/cli/cli.go | 2 +- internal/cli/compile/compile.go | 7 +++---- internal/cli/config/get.go | 5 ++--- internal/cli/core/download.go | 7 +++---- internal/cli/core/install.go | 7 +++---- internal/cli/core/list.go | 5 ++--- internal/cli/core/search.go | 5 ++--- internal/cli/core/uninstall.go | 7 +++---- internal/cli/core/update_index.go | 5 ++--- internal/cli/core/upgrade.go | 5 ++--- internal/cli/debug/debug.go | 13 ++++++------- internal/cli/debug/debug_check.go | 11 +++++------ internal/cli/lib/check_deps.go | 7 +++---- internal/cli/lib/download.go | 7 +++---- internal/cli/lib/examples.go | 7 +++---- internal/cli/lib/install.go | 7 +++---- internal/cli/lib/list.go | 2 +- internal/cli/lib/search.go | 5 ++--- internal/cli/lib/uninstall.go | 7 +++---- internal/cli/lib/update_index.go | 5 ++--- internal/cli/lib/upgrade.go | 5 ++--- internal/cli/monitor/monitor.go | 9 ++++----- internal/cli/outdated/outdated.go | 5 ++--- internal/cli/sketch/archive.go | 5 ++--- internal/cli/sketch/new.go | 5 ++--- internal/cli/update/update.go | 5 ++--- internal/cli/upgrade/upgrade.go | 5 ++--- internal/cli/upload/upload.go | 10 ++++------ internal/cli/version/version.go | 6 +++--- 51 files changed, 161 insertions(+), 182 deletions(-) diff --git a/commands/instances.go b/commands/instances.go index 58156465322..30fe31ba783 100644 --- a/commands/instances.go +++ b/commands/instances.go @@ -251,7 +251,7 @@ func (s *arduinoCoreServerImpl) Init(req *rpc.InitRequest, stream rpc.ArduinoCor } } else { // Load platforms from profile - errs := pmb.LoadHardwareForProfile(profile, true, downloadCallback, taskCallback, s.settings) + errs := pmb.LoadHardwareForProfile(ctx, profile, true, downloadCallback, taskCallback, s.settings) for _, err := range errs { s := &cmderrors.PlatformLoadingError{Cause: err} responseError(s.GRPCStatus()) @@ -497,13 +497,11 @@ func (s *arduinoCoreServerImpl) UpdateLibrariesIndex(req *rpc.UpdateLibrariesInd } // Perform index update - // TODO: pass context - // ctx := stream.Context() config, err := s.settings.DownloaderConfig() if err != nil { return err } - if err := globals.LibrariesIndexResource.Download(indexDir, downloadCB, config); err != nil { + if err := globals.LibrariesIndexResource.Download(stream.Context(), indexDir, downloadCB, config); err != nil { resultCB(rpc.IndexUpdateReport_STATUS_FAILED) return err } @@ -621,7 +619,7 @@ func (s *arduinoCoreServerImpl) UpdateIndex(req *rpc.UpdateIndexRequest, stream indexResource.SignatureURL, _ = url.Parse(u) // should not fail because we already parsed it indexResource.SignatureURL.Path += ".sig" } - if err := indexResource.Download(indexpath, downloadCB, config); err != nil { + if err := indexResource.Download(stream.Context(), indexpath, downloadCB, config); err != nil { failed = true result.UpdatedIndexes = append(result.GetUpdatedIndexes(), report(URL, rpc.IndexUpdateReport_STATUS_FAILED)) } else { diff --git a/internal/arduino/builder/builder.go b/internal/arduino/builder/builder.go index ad6af436128..1727556b846 100644 --- a/internal/arduino/builder/builder.go +++ b/internal/arduino/builder/builder.go @@ -44,6 +44,8 @@ var ErrSketchCannotBeLocatedInBuildPath = errors.New("sketch cannot be located i // Builder is a Sketch builder. type Builder struct { + ctx context.Context + sketch *sketch.Sketch buildProperties *properties.Map @@ -198,6 +200,7 @@ func NewBuilder( diagnosticStore := diagnostics.NewStore() b := &Builder{ + ctx: ctx, sketch: sk, buildProperties: buildProperties, buildPath: buildPath, @@ -305,6 +308,7 @@ func (b *Builder) preprocess() error { b.logIfVerbose(false, tr("Detecting libraries used...")) err := b.libsDetector.FindIncludes( + b.ctx, b.buildPath, b.buildProperties.GetPath("build.core.path"), b.buildProperties.GetPath("build.variant.path"), diff --git a/internal/arduino/builder/internal/detector/detector.go b/internal/arduino/builder/internal/detector/detector.go index 46fa991a132..98d497d475c 100644 --- a/internal/arduino/builder/internal/detector/detector.go +++ b/internal/arduino/builder/internal/detector/detector.go @@ -17,6 +17,7 @@ package detector import ( "bytes" + "context" "encoding/json" "errors" "fmt" @@ -196,6 +197,7 @@ func (l *SketchLibrariesDetector) appendIncludeFolder( // FindIncludes todo func (l *SketchLibrariesDetector) FindIncludes( + ctx context.Context, buildPath *paths.Path, buildCorePath *paths.Path, buildVariantPath *paths.Path, @@ -205,7 +207,7 @@ func (l *SketchLibrariesDetector) FindIncludes( buildProperties *properties.Map, platformArch string, ) error { - err := l.findIncludes(buildPath, buildCorePath, buildVariantPath, sketchBuildPath, sketch, librariesBuildPath, buildProperties, platformArch) + err := l.findIncludes(ctx, buildPath, buildCorePath, buildVariantPath, sketchBuildPath, sketch, librariesBuildPath, buildProperties, platformArch) if err != nil && l.onlyUpdateCompilationDatabase { l.logger.Info( fmt.Sprintf( @@ -220,6 +222,7 @@ func (l *SketchLibrariesDetector) FindIncludes( } func (l *SketchLibrariesDetector) findIncludes( + ctx context.Context, buildPath *paths.Path, buildCorePath *paths.Path, buildVariantPath *paths.Path, @@ -269,7 +272,7 @@ func (l *SketchLibrariesDetector) findIncludes( } for !sourceFileQueue.empty() { - err := l.findIncludesUntilDone(cache, sourceFileQueue, buildProperties, sketchBuildPath, librariesBuildPath, platformArch) + err := l.findIncludesUntilDone(ctx, cache, sourceFileQueue, buildProperties, sketchBuildPath, librariesBuildPath, platformArch) if err != nil { cachePath.Remove() return err @@ -297,6 +300,7 @@ func (l *SketchLibrariesDetector) findIncludes( } func (l *SketchLibrariesDetector) findIncludesUntilDone( + ctx context.Context, cache *includeCache, sourceFileQueue *uniqueSourceFileQueue, buildProperties *properties.Map, @@ -350,7 +354,7 @@ func (l *SketchLibrariesDetector) findIncludesUntilDone( l.logger.Info(tr("Using cached library dependencies for file: %[1]s", sourcePath)) } } else { - preprocFirstResult, preprocErr = preprocessor.GCC(sourcePath, targetFilePath, includeFolders, buildProperties) + preprocFirstResult, preprocErr = preprocessor.GCC(ctx, sourcePath, targetFilePath, includeFolders, buildProperties) if l.logger.Verbose() { l.logger.WriteStdout(preprocFirstResult.Stdout()) } @@ -381,7 +385,7 @@ func (l *SketchLibrariesDetector) findIncludesUntilDone( // Library could not be resolved, show error if preprocErr == nil || preprocFirstResult.Stderr() == nil { // Filename came from cache, so run preprocessor to obtain error to show - result, err := preprocessor.GCC(sourcePath, targetFilePath, includeFolders, buildProperties) + result, err := preprocessor.GCC(ctx, sourcePath, targetFilePath, includeFolders, buildProperties) if l.logger.Verbose() { l.logger.WriteStdout(result.Stdout()) } diff --git a/internal/arduino/builder/internal/preprocessor/arduino_preprocessor.go b/internal/arduino/builder/internal/preprocessor/arduino_preprocessor.go index da8cde2adfc..399ca34f742 100644 --- a/internal/arduino/builder/internal/preprocessor/arduino_preprocessor.go +++ b/internal/arduino/builder/internal/preprocessor/arduino_preprocessor.go @@ -31,6 +31,7 @@ import ( // PreprocessSketchWithArduinoPreprocessor performs preprocessing of the arduino sketch // using arduino-preprocessor (https://github.com/arduino/arduino-preprocessor). func PreprocessSketchWithArduinoPreprocessor( + ctx context.Context, sk *sketch.Sketch, buildPath *paths.Path, includeFolders paths.PathList, lineOffset int, buildProperties *properties.Map, onlyUpdateCompilationDatabase bool, ) (*Result, error) { @@ -42,7 +43,7 @@ func PreprocessSketchWithArduinoPreprocessor( sourceFile := buildPath.Join("sketch", sk.MainFile.Base()+".cpp") targetFile := buildPath.Join("preproc", "sketch_merged.cpp") - gccResult, err := GCC(sourceFile, targetFile, includeFolders, buildProperties) + gccResult, err := GCC(ctx, sourceFile, targetFile, includeFolders, buildProperties) verboseOut.Write(gccResult.Stdout()) verboseOut.Write(gccResult.Stderr()) if err != nil { @@ -78,7 +79,7 @@ func PreprocessSketchWithArduinoPreprocessor( } verboseOut.WriteString(commandLine) - commandStdOut, commandStdErr, err := command.RunAndCaptureOutput(context.Background()) + commandStdOut, commandStdErr, err := command.RunAndCaptureOutput(ctx) verboseOut.Write(commandStdErr) if err != nil { return &Result{args: gccResult.Args(), stdout: verboseOut.Bytes(), stderr: normalOut.Bytes()}, err diff --git a/internal/arduino/builder/internal/preprocessor/ctags.go b/internal/arduino/builder/internal/preprocessor/ctags.go index 4a0cf783b45..73b60f80c49 100644 --- a/internal/arduino/builder/internal/preprocessor/ctags.go +++ b/internal/arduino/builder/internal/preprocessor/ctags.go @@ -41,6 +41,7 @@ var DebugPreprocessor bool // PreprocessSketchWithCtags performs preprocessing of the arduino sketch using CTags. func PreprocessSketchWithCtags( + ctx context.Context, sketch *sketch.Sketch, buildPath *paths.Path, includes paths.PathList, lineOffset int, buildProperties *properties.Map, onlyUpdateCompilationDatabase, verbose bool, @@ -57,7 +58,7 @@ func PreprocessSketchWithCtags( // Run GCC preprocessor sourceFile := buildPath.Join("sketch", sketch.MainFile.Base()+".cpp") - result, err := GCC(sourceFile, ctagsTarget, includes, buildProperties) + result, err := GCC(ctx, sourceFile, ctagsTarget, includes, buildProperties) stdout.Write(result.Stdout()) stderr.Write(result.Stderr()) if err != nil { @@ -84,7 +85,7 @@ func PreprocessSketchWithCtags( } // Run CTags on gcc-preprocessed source - ctagsOutput, ctagsStdErr, err := RunCTags(ctagsTarget, buildProperties) + ctagsOutput, ctagsStdErr, err := RunCTags(ctx, ctagsTarget, buildProperties) if verbose { stderr.Write(ctagsStdErr) } @@ -179,7 +180,7 @@ func isFirstFunctionOutsideOfSource(firstFunctionLine int, sourceRows []string) } // RunCTags performs a run of ctags on the given source file. Returns the ctags output and the stderr contents. -func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, []byte, error) { +func RunCTags(ctx context.Context, sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, []byte, error) { ctagsBuildProperties := properties.NewMap() ctagsBuildProperties.Set("tools.ctags.path", "{runtime.tools.ctags.path}") ctagsBuildProperties.Set("tools.ctags.cmd.path", "{path}/ctags") @@ -202,7 +203,7 @@ func RunCTags(sourceFile *paths.Path, buildProperties *properties.Map) ([]byte, if err != nil { return nil, nil, err } - stdout, stderr, err := proc.RunAndCaptureOutput(context.Background()) + stdout, stderr, err := proc.RunAndCaptureOutput(ctx) // Append ctags arguments to stderr args := fmt.Sprintln(strings.Join(parts, " ")) diff --git a/internal/arduino/builder/internal/preprocessor/gcc.go b/internal/arduino/builder/internal/preprocessor/gcc.go index d9cf1c446ea..f97426c2df8 100644 --- a/internal/arduino/builder/internal/preprocessor/gcc.go +++ b/internal/arduino/builder/internal/preprocessor/gcc.go @@ -30,6 +30,7 @@ import ( // GCC performs a run of the gcc preprocess (macro/includes expansion). The function outputs the result // to targetFilePath. Returns the stdout/stderr of gcc if any. func GCC( + ctx context.Context, sourceFilePath, targetFilePath *paths.Path, includes paths.PathList, buildProperties *properties.Map, ) (Result, error) { @@ -75,7 +76,7 @@ func GCC( if err != nil { return Result{}, err } - stdout, stderr, err := proc.RunAndCaptureOutput(context.Background()) + stdout, stderr, err := proc.RunAndCaptureOutput(ctx) // Append gcc arguments to stdout stdout = append([]byte(fmt.Sprintln(strings.Join(args, " "))), stdout...) diff --git a/internal/arduino/builder/preprocess_sketch.go b/internal/arduino/builder/preprocess_sketch.go index d7fd6e32e72..86d7bd7e7e9 100644 --- a/internal/arduino/builder/preprocess_sketch.go +++ b/internal/arduino/builder/preprocess_sketch.go @@ -24,6 +24,7 @@ import ( func (b *Builder) preprocessSketch(includes paths.PathList) error { // In the future we might change the preprocessor result, err := preprocessor.PreprocessSketchWithCtags( + b.ctx, b.sketch, b.buildPath, includes, b.lineOffset, b.buildProperties, b.onlyUpdateCompilationDatabase, b.logger.Verbose(), ) diff --git a/internal/arduino/cores/packagemanager/profiles.go b/internal/arduino/cores/packagemanager/profiles.go index 598d1cdc959..9d3bfba047a 100644 --- a/internal/arduino/cores/packagemanager/profiles.go +++ b/internal/arduino/cores/packagemanager/profiles.go @@ -16,6 +16,7 @@ package packagemanager import ( + "context" "fmt" "net/url" @@ -32,7 +33,7 @@ import ( // LoadHardwareForProfile load the hardware platforms for the given profile. // If installMissing is true then possibly missing tools and platforms will be downloaded and installed. -func (pmb *Builder) LoadHardwareForProfile(p *sketch.Profile, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, settings *configuration.Settings) []error { +func (pmb *Builder) LoadHardwareForProfile(ctx context.Context, p *sketch.Profile, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, settings *configuration.Settings) []error { pmb.profile = p // Load required platforms @@ -40,7 +41,7 @@ func (pmb *Builder) LoadHardwareForProfile(p *sketch.Profile, installMissing boo var platformReleases []*cores.PlatformRelease indexURLs := map[string]*url.URL{} for _, platformRef := range p.Platforms { - if platformRelease, err := pmb.loadProfilePlatform(platformRef, installMissing, downloadCB, taskCB, settings); err != nil { + if platformRelease, err := pmb.loadProfilePlatform(ctx, platformRef, installMissing, downloadCB, taskCB, settings); err != nil { merr = append(merr, fmt.Errorf("%s: %w", tr("loading required platform %s", platformRef), err)) logrus.WithField("platform", platformRef).WithError(err).Debugf("Error loading platform for profile") } else { @@ -68,7 +69,7 @@ func (pmb *Builder) LoadHardwareForProfile(p *sketch.Profile, installMissing boo return merr } -func (pmb *Builder) loadProfilePlatform(platformRef *sketch.ProfilePlatformReference, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, settings *configuration.Settings) (*cores.PlatformRelease, error) { +func (pmb *Builder) loadProfilePlatform(ctx context.Context, platformRef *sketch.ProfilePlatformReference, installMissing bool, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB, settings *configuration.Settings) (*cores.PlatformRelease, error) { targetPackage := pmb.packages.GetOrCreatePackage(platformRef.Packager) platform := targetPackage.GetOrCreatePlatform(platformRef.Architecture) release := platform.GetOrCreateRelease(platformRef.Version) @@ -77,14 +78,14 @@ func (pmb *Builder) loadProfilePlatform(platformRef *sketch.ProfilePlatformRefer destDir := settings.ProfilesCacheDir().Join(uid) if !destDir.IsDir() && installMissing { // Try installing the missing platform - if err := pmb.installMissingProfilePlatform(platformRef, destDir, downloadCB, taskCB); err != nil { + if err := pmb.installMissingProfilePlatform(ctx, platformRef, destDir, downloadCB, taskCB); err != nil { return nil, err } } return release, pmb.loadPlatformRelease(release, destDir) } -func (pmb *Builder) installMissingProfilePlatform(platformRef *sketch.ProfilePlatformReference, destDir *paths.Path, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { +func (pmb *Builder) installMissingProfilePlatform(ctx context.Context, platformRef *sketch.ProfilePlatformReference, destDir *paths.Path, downloadCB rpc.DownloadProgressCB, taskCB rpc.TaskProgressCB) error { // Instantiate a temporary package manager only for platform installation _ = pmb.tempDir.MkdirAll() tmp, err := paths.MkTempDir(pmb.tempDir.String(), "") @@ -103,7 +104,7 @@ func (pmb *Builder) installMissingProfilePlatform(platformRef *sketch.ProfilePla } for _, indexURL := range indexesToDownload { indexResource := resources.IndexResource{URL: indexURL} - if err := indexResource.Download(tmpPmb.IndexDir, downloadCB, pmb.downloaderConfig); err != nil { + if err := indexResource.Download(ctx, tmpPmb.IndexDir, downloadCB, pmb.downloaderConfig); err != nil { taskCB(&rpc.TaskProgress{Name: tr("Error downloading %s", indexURL)}) return &cmderrors.FailedDownloadError{Message: tr("Error downloading %s", indexURL), Cause: err} } diff --git a/internal/arduino/resources/index.go b/internal/arduino/resources/index.go index fb05f55d776..e9198905e5e 100644 --- a/internal/arduino/resources/index.go +++ b/internal/arduino/resources/index.go @@ -58,7 +58,7 @@ func (res *IndexResource) IndexFileName() (string, error) { // Download will download the index and possibly check the signature using the Arduino's public key. // If the file is in .gz format it will be unpacked first. -func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadProgressCB, config downloader.Config) error { +func (res *IndexResource) Download(ctx context.Context, destDir *paths.Path, downloadCB rpc.DownloadProgressCB, config downloader.Config) error { // Create destination directory if err := destDir.MkdirAll(); err != nil { return &cmderrors.PermissionDeniedError{Message: tr("Can't create data directory %s", destDir), Cause: err} @@ -100,7 +100,7 @@ func (res *IndexResource) Download(destDir *paths.Path, downloadCB rpc.DownloadP defer f.Close() tmpArchivePath := tmp.Join("archive") _ = tmpArchivePath.MkdirAll() - if err := extract.Bz2(context.Background(), f, tmpArchivePath.String(), nil); err != nil { + if err := extract.Bz2(ctx, f, tmpArchivePath.String(), nil); err != nil { return &cmderrors.PermissionDeniedError{Message: tr("Error extracting %s", tmpIndexPath), Cause: err} } diff --git a/internal/arduino/resources/resources_test.go b/internal/arduino/resources/resources_test.go index ee987ddcea6..3e218c1f89d 100644 --- a/internal/arduino/resources/resources_test.go +++ b/internal/arduino/resources/resources_test.go @@ -16,6 +16,7 @@ package resources import ( + "context" "crypto" "encoding/hex" "fmt" @@ -116,6 +117,7 @@ func TestDownloadAndChecksums(t *testing.T) { } func TestIndexDownloadAndSignatureWithinArchive(t *testing.T) { + ctx := context.Background() // Spawn test webserver mux := http.NewServeMux() fs := http.FileServer(http.Dir("testdata")) @@ -132,7 +134,7 @@ func TestIndexDownloadAndSignatureWithinArchive(t *testing.T) { destDir, err := paths.MkTempDir("", "") require.NoError(t, err) defer destDir.RemoveAll() - err = idxResource.Download(destDir, func(curr *rpc.DownloadProgress) {}, downloader.GetDefaultConfig()) + err = idxResource.Download(ctx, destDir, func(curr *rpc.DownloadProgress) {}, downloader.GetDefaultConfig()) require.NoError(t, err) require.True(t, destDir.Join("package_index.json").Exist()) require.True(t, destDir.Join("package_index.json.sig").Exist()) @@ -143,7 +145,7 @@ func TestIndexDownloadAndSignatureWithinArchive(t *testing.T) { invDestDir, err := paths.MkTempDir("", "") require.NoError(t, err) defer invDestDir.RemoveAll() - err = invIdxResource.Download(invDestDir, func(curr *rpc.DownloadProgress) {}, downloader.GetDefaultConfig()) + err = invIdxResource.Download(ctx, invDestDir, func(curr *rpc.DownloadProgress) {}, downloader.GetDefaultConfig()) require.Error(t, err) require.Contains(t, err.Error(), "invalid signature") require.False(t, invDestDir.Join("package_index.json").Exist()) diff --git a/internal/cli/arguments/completion.go b/internal/cli/arguments/completion.go index c42e817cc0f..a8867c51cf2 100644 --- a/internal/cli/arguments/completion.go +++ b/internal/cli/arguments/completion.go @@ -29,7 +29,7 @@ import ( func GetInstalledBoards(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { inst := instance.CreateAndInit(ctx, srv) - list, _ := srv.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ + list, _ := srv.BoardListAll(ctx, &rpc.BoardListAllRequest{ Instance: inst, SearchArgs: nil, IncludeHiddenBoards: false, @@ -53,7 +53,7 @@ func GetInstalledProgrammers(ctx context.Context, srv rpc.ArduinoCoreServiceServ SearchArgs: nil, IncludeHiddenBoards: false, } - list, _ := srv.BoardListAll(context.Background(), listAllReq) + list, _ := srv.BoardListAll(ctx, listAllReq) installedProgrammers := make(map[string]string) for _, board := range list.GetBoards() { @@ -149,7 +149,7 @@ func getLibraries(ctx context.Context, srv rpc.ArduinoCoreServiceServer, all boo func GetInstallableLibs(ctx context.Context, srv rpc.ArduinoCoreServiceServer) []string { inst := instance.CreateAndInit(ctx, srv) - libs, _ := srv.LibrarySearch(context.Background(), &rpc.LibrarySearchRequest{ + libs, _ := srv.LibrarySearch(ctx, &rpc.LibrarySearchRequest{ Instance: inst, SearchArgs: "", // if no query is specified all the libs are returned }) diff --git a/internal/cli/arguments/fqbn.go b/internal/cli/arguments/fqbn.go index 6369cca6bab..e1cb338c77d 100644 --- a/internal/cli/arguments/fqbn.go +++ b/internal/cli/arguments/fqbn.go @@ -37,7 +37,7 @@ type Fqbn struct { func (f *Fqbn) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&f.fqbn, "fqbn", "b", "", tr("Fully Qualified Board Name, e.g.: arduino:avr:uno")) cmd.RegisterFlagCompletionFunc("fqbn", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetInstalledBoards(context.Background(), srv), cobra.ShellCompDirectiveDefault + return GetInstalledBoards(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }) cmd.Flags().StringSliceVar(&f.boardOptions, "board-options", []string{}, tr("List of board options separated by commas. Or can be used multiple times for multiple options.")) @@ -70,7 +70,7 @@ func (f *Fqbn) Set(fqbn string) { // - the port is not found, in this case nil is returned // - the FQBN autodetection fail, in this case the function prints an error and // terminates the execution -func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultFQBN, defaultAddress, defaultProtocol string) (string, *rpc.Port) { +func CalculateFQBNAndPort(ctx context.Context, portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultFQBN, defaultAddress, defaultProtocol string) (string, *rpc.Port) { fqbn := fqbnArg.String() if fqbn == "" { fqbn = defaultFQBN @@ -79,14 +79,14 @@ func CalculateFQBNAndPort(portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, if portArgs == nil || portArgs.address == "" { feedback.FatalError(&cmderrors.MissingFQBNError{}, feedback.ErrGeneric) } - fqbn, port := portArgs.DetectFQBN(instance, srv) + fqbn, port := portArgs.DetectFQBN(ctx, instance, srv) if fqbn == "" { feedback.FatalError(&cmderrors.MissingFQBNError{}, feedback.ErrGeneric) } return fqbn, port } - port, err := portArgs.GetPort(instance, srv, defaultAddress, defaultProtocol) + port, err := portArgs.GetPort(ctx, instance, srv, defaultAddress, defaultProtocol) if err != nil { feedback.Fatal(tr("Error getting port metadata: %v", err), feedback.ErrGeneric) } diff --git a/internal/cli/arguments/port.go b/internal/cli/arguments/port.go index e3566699b0f..1d138043fbc 100644 --- a/internal/cli/arguments/port.go +++ b/internal/cli/arguments/port.go @@ -42,11 +42,11 @@ type Port struct { func (p *Port) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&p.address, "port", "p", "", tr("Upload port address, e.g.: COM3 or /dev/ttyACM2")) cmd.RegisterFlagCompletionFunc("port", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return f.Map(GetAvailablePorts(context.Background(), srv), (*rpc.Port).GetAddress), cobra.ShellCompDirectiveDefault + return f.Map(GetAvailablePorts(cmd.Context(), srv), (*rpc.Port).GetAddress), cobra.ShellCompDirectiveDefault }) cmd.Flags().StringVarP(&p.protocol, "protocol", "l", "", tr("Upload port protocol, e.g: serial")) cmd.RegisterFlagCompletionFunc("protocol", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return f.Map(GetAvailablePorts(context.Background(), srv), (*rpc.Port).GetProtocol), cobra.ShellCompDirectiveDefault + return f.Map(GetAvailablePorts(cmd.Context(), srv), (*rpc.Port).GetProtocol), cobra.ShellCompDirectiveDefault }) p.timeout.AddToCommand(cmd) } @@ -56,12 +56,12 @@ func (p *Port) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer // This method allows will bypass the discoveries if: // - a nil instance is passed: in this case the plain port and protocol arguments are returned (even if empty) // - a protocol is specified: in this case the discoveries are not needed to autodetect the protocol. -func (p *Port) GetPortAddressAndProtocol(instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string) (string, string, error) { +func (p *Port) GetPortAddressAndProtocol(ctx context.Context, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string) (string, string, error) { if p.protocol != "" || instance == nil { return p.address, p.protocol, nil } - port, err := p.GetPort(instance, srv, defaultAddress, defaultProtocol) + port, err := p.GetPort(ctx, instance, srv, defaultAddress, defaultProtocol) if err != nil { return "", "", err } @@ -70,7 +70,7 @@ func (p *Port) GetPortAddressAndProtocol(instance *rpc.Instance, srv rpc.Arduino // GetPort returns the Port obtained by parsing command line arguments. // The extra metadata for the ports is obtained using the pluggable discoveries. -func (p *Port) GetPort(instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string) (*rpc.Port, error) { +func (p *Port) GetPort(ctx context.Context, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string) (*rpc.Port, error) { address := p.address protocol := p.protocol if address == "" && (defaultAddress != "" || defaultProtocol != "") { @@ -88,7 +88,7 @@ func (p *Port) GetPort(instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, } logrus.WithField("port", address).Tracef("Upload port") - ctx, cancel := context.WithCancel(context.Background()) + ctx, cancel := context.WithCancel(ctx) defer cancel() stream, watcher := commands.BoardListWatchProxyToChan(ctx) @@ -131,8 +131,8 @@ func (p *Port) GetSearchTimeout() time.Duration { // DetectFQBN tries to identify the board connected to the port and returns the // discovered Port object together with the FQBN. If the port does not match // exactly 1 board, -func (p *Port) DetectFQBN(inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer) (string, *rpc.Port) { - detectedPorts, err := srv.BoardList(context.Background(), &rpc.BoardListRequest{ +func (p *Port) DetectFQBN(ctx context.Context, inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer) (string, *rpc.Port) { + detectedPorts, err := srv.BoardList(ctx, &rpc.BoardListRequest{ Instance: inst, Timeout: p.timeout.Get().Milliseconds(), }) diff --git a/internal/cli/arguments/profiles.go b/internal/cli/arguments/profiles.go index 1631fe35d9f..59d56656fa6 100644 --- a/internal/cli/arguments/profiles.go +++ b/internal/cli/arguments/profiles.go @@ -16,8 +16,6 @@ package arguments import ( - "context" - rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/spf13/cobra" ) @@ -37,7 +35,7 @@ func (f *Profile) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceSer if len(args) > 0 { sketchProfile = args[0] } - return GetSketchProfiles(context.Background(), srv, sketchProfile), cobra.ShellCompDirectiveDefault + return GetSketchProfiles(cmd.Context(), srv, sketchProfile), cobra.ShellCompDirectiveDefault }) } diff --git a/internal/cli/arguments/programmer.go b/internal/cli/arguments/programmer.go index c17ec739816..6f590b85164 100644 --- a/internal/cli/arguments/programmer.go +++ b/internal/cli/arguments/programmer.go @@ -33,20 +33,20 @@ type Programmer struct { func (p *Programmer) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer) { cmd.Flags().StringVarP(&p.programmer, "programmer", "P", "", tr("Programmer to use, e.g: atmel_ice")) cmd.RegisterFlagCompletionFunc("programmer", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return GetInstalledProgrammers(context.Background(), srv), cobra.ShellCompDirectiveDefault + return GetInstalledProgrammers(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }) } // String returns the programmer specified by the user, or the default programmer // for the given board if defined. -func (p *Programmer) String(inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer, fqbn string) string { +func (p *Programmer) String(ctx context.Context, inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer, fqbn string) string { if p.programmer != "" { return p.programmer } if inst == nil || fqbn == "" { return "" } - details, err := srv.BoardDetails(context.Background(), &rpc.BoardDetailsRequest{ + details, err := srv.BoardDetails(ctx, &rpc.BoardDetailsRequest{ Instance: inst, Fqbn: fqbn, }) diff --git a/internal/cli/board/attach.go b/internal/cli/board/attach.go index 9c5a8dc268e..c8b8dca3e28 100644 --- a/internal/cli/board/attach.go +++ b/internal/cli/board/attach.go @@ -40,11 +40,12 @@ func initAttachCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " board attach -P atmel_ice", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { + ctx := cmd.Context() sketchPath := "" if len(args) > 0 { sketchPath = args[0] } - runAttachCommand(srv, sketchPath, &port, fqbn.String(), &programmer) + runAttachCommand(ctx, srv, sketchPath, &port, fqbn.String(), &programmer) }, } fqbn.AddToCommand(attachCommand, srv) @@ -54,11 +55,10 @@ func initAttachCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return attachCommand } -func runAttachCommand(srv rpc.ArduinoCoreServiceServer, path string, port *arguments.Port, fqbn string, programmer *arguments.Programmer) { - ctx := context.Background() +func runAttachCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, path string, port *arguments.Port, fqbn string, programmer *arguments.Programmer) { sketchPath := arguments.InitSketchPath(path) - portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(nil, srv, "", "") + portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(ctx, nil, srv, "", "") newDefaults, err := srv.SetSketchDefaults(ctx, &rpc.SetSketchDefaultsRequest{ SketchPath: sketchPath.String(), DefaultFqbn: fqbn, diff --git a/internal/cli/board/details.go b/internal/cli/board/details.go index 49fb5aea2b6..4e7d8579f19 100644 --- a/internal/cli/board/details.go +++ b/internal/cli/board/details.go @@ -43,7 +43,7 @@ func initDetailsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " board details -b arduino:avr:nano", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runDetailsCommand(srv, fqbn.String(), showFullDetails, listProgrammers, showProperties) + runDetailsCommand(cmd.Context(), srv, fqbn.String(), showFullDetails, listProgrammers, showProperties) }, } @@ -55,8 +55,7 @@ func initDetailsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return detailsCommand } -func runDetailsCommand(srv rpc.ArduinoCoreServiceServer, fqbn string, showFullDetails, listProgrammers bool, showProperties arguments.ShowProperties) { - ctx := context.Background() +func runDetailsCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, fqbn string, showFullDetails, listProgrammers bool, showProperties arguments.ShowProperties) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli board details`") @@ -65,7 +64,7 @@ func runDetailsCommand(srv rpc.ArduinoCoreServiceServer, fqbn string, showFullDe if err != nil { feedback.Fatal(err.Error(), feedback.ErrBadArgument) } - res, err := srv.BoardDetails(context.Background(), &rpc.BoardDetailsRequest{ + res, err := srv.BoardDetails(ctx, &rpc.BoardDetailsRequest{ Instance: inst, Fqbn: fqbn, DoNotExpandBuildProperties: showPropertiesMode == arguments.ShowPropertiesUnexpanded, diff --git a/internal/cli/board/list.go b/internal/cli/board/list.go index 882de46aaa5..20001f2ad82 100644 --- a/internal/cli/board/list.go +++ b/internal/cli/board/list.go @@ -46,7 +46,7 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " board list --discovery-timeout 10s", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runListCommand(srv, watch, timeoutArg.Get().Milliseconds(), fqbn.String()) + runListCommand(cmd.Context(), srv, watch, timeoutArg.Get().Milliseconds(), fqbn.String()) }, } @@ -57,18 +57,17 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } // runListCommand detects and lists the connected arduino boards -func runListCommand(srv rpc.ArduinoCoreServiceServer, watch bool, timeout int64, fqbn string) { - ctx := context.Background() +func runListCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, watch bool, timeout int64, fqbn string) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli board list`") if watch { - watchList(inst, srv) + watchList(ctx, inst, srv) return } - list, err := srv.BoardList(context.Background(), &rpc.BoardListRequest{ + list, err := srv.BoardList(ctx, &rpc.BoardListRequest{ Instance: inst, Timeout: timeout, Fqbn: fqbn, @@ -89,8 +88,8 @@ func runListCommand(srv rpc.ArduinoCoreServiceServer, watch bool, timeout int64, feedback.PrintResult(listResult{result.NewDetectedPorts(ports)}) } -func watchList(inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer) { - stream, eventsChan := commands.BoardListWatchProxyToChan(context.Background()) +func watchList(ctx context.Context, inst *rpc.Instance, srv rpc.ArduinoCoreServiceServer) { + stream, eventsChan := commands.BoardListWatchProxyToChan(ctx) err := srv.BoardListWatch(&rpc.BoardListWatchRequest{Instance: inst}, stream) if err != nil { feedback.Fatal(tr("Error detecting boards: %v", err), feedback.ErrNetwork) diff --git a/internal/cli/board/listall.go b/internal/cli/board/listall.go index 8eaa2c9392b..55381ba2ffc 100644 --- a/internal/cli/board/listall.go +++ b/internal/cli/board/listall.go @@ -43,7 +43,7 @@ for a specific board if you specify the board name`), " " + os.Args[0] + " board listall zero", Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { - runListAllCommand(args, srv) + runListAllCommand(cmd.Context(), args, srv) }, } listAllCommand.Flags().BoolVarP(&showHiddenBoard, "show-hidden", "a", false, tr("Show also boards marked as 'hidden' in the platform")) @@ -51,13 +51,12 @@ for a specific board if you specify the board name`), } // runListAllCommand list all installed boards -func runListAllCommand(args []string, srv rpc.ArduinoCoreServiceServer) { - ctx := context.Background() +func runListAllCommand(ctx context.Context, args []string, srv rpc.ArduinoCoreServiceServer) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli board listall`") - list, err := srv.BoardListAll(context.Background(), &rpc.BoardListAllRequest{ + list, err := srv.BoardListAll(ctx, &rpc.BoardListAllRequest{ Instance: inst, SearchArgs: args, IncludeHiddenBoards: showHiddenBoard, diff --git a/internal/cli/board/search.go b/internal/cli/board/search.go index 057026a23b2..42b85785788 100644 --- a/internal/cli/board/search.go +++ b/internal/cli/board/search.go @@ -41,20 +41,19 @@ func initSearchCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " board search zero", Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { - runSearchCommand(srv, args) + runSearchCommand(cmd.Context(), srv, args) }, } searchCommand.Flags().BoolVarP(&showHiddenBoard, "show-hidden", "a", false, tr("Show also boards marked as 'hidden' in the platform")) return searchCommand } -func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string) { - ctx := context.Background() +func runSearchCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli board search`") - res, err := srv.BoardSearch(context.Background(), &rpc.BoardSearchRequest{ + res, err := srv.BoardSearch(ctx, &rpc.BoardSearchRequest{ Instance: inst, SearchArgs: strings.Join(args, " "), IncludeHiddenBoards: showHiddenBoard, diff --git a/internal/cli/burnbootloader/burnbootloader.go b/internal/cli/burnbootloader/burnbootloader.go index c17a822b3f4..7c8f4c16896 100644 --- a/internal/cli/burnbootloader/burnbootloader.go +++ b/internal/cli/burnbootloader/burnbootloader.go @@ -50,7 +50,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " burn-bootloader -b arduino:avr:uno -P atmel_ice", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runBootloaderCommand(srv) + runBootloaderCommand(cmd.Context(), srv) }, } @@ -65,14 +65,13 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return burnBootloaderCommand } -func runBootloaderCommand(srv rpc.ArduinoCoreServiceServer) { - ctx := context.Background() +func runBootloaderCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli burn-bootloader`") // We don't need a Sketch to upload a board's bootloader - discoveryPort, err := port.GetPort(instance, srv, "", "") + discoveryPort, err := port.GetPort(ctx, instance, srv, "", "") if err != nil { feedback.Fatal(tr("Error during Upload: %v", err), feedback.ErrGeneric) } @@ -85,7 +84,7 @@ func runBootloaderCommand(srv rpc.ArduinoCoreServiceServer) { Port: discoveryPort, Verbose: verbose, Verify: verify, - Programmer: programmer.String(instance, srv, fqbn.String()), + Programmer: programmer.String(ctx, instance, srv, fqbn.String()), DryRun: dryRun, }, stream); err != nil { errcode := feedback.ErrGeneric diff --git a/internal/cli/cache/clean.go b/internal/cli/cache/clean.go index a55b9c8309b..184d2e65b90 100644 --- a/internal/cli/cache/clean.go +++ b/internal/cli/cache/clean.go @@ -33,16 +33,16 @@ func initCleanCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " cache clean", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runCleanCommand(srv) + runCleanCommand(cmd.Context(), srv) }, } return cleanCommand } -func runCleanCommand(srv rpc.ArduinoCoreServiceServer) { +func runCleanCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli cache clean`") - _, err := srv.CleanDownloadCacheDirectory(context.Background(), &rpc.CleanDownloadCacheDirectoryRequest{}) + _, err := srv.CleanDownloadCacheDirectory(ctx, &rpc.CleanDownloadCacheDirectoryRequest{}) if err != nil { feedback.Fatal(tr("Error cleaning caches: %v", err), feedback.ErrGeneric) } diff --git a/internal/cli/cli.go b/internal/cli/cli.go index de4832318f5..e2ad85cc9e2 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -115,7 +115,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { if cmd.Name() != "version" { updaterMessageChan = make(chan *semver.Version) go func() { - res, err := srv.CheckForArduinoCLIUpdates(context.Background(), &rpc.CheckForArduinoCLIUpdatesRequest{}) + res, err := srv.CheckForArduinoCLIUpdates(ctx, &rpc.CheckForArduinoCLIUpdatesRequest{}) if err != nil { logrus.Warnf("Error checking for updates: %v", err) updaterMessageChan <- nil diff --git a/internal/cli/compile/compile.go b/internal/cli/compile/compile.go index 4b4ad4164bd..f04f01e8fc7 100644 --- a/internal/cli/compile/compile.go +++ b/internal/cli/compile/compile.go @@ -16,7 +16,6 @@ package compile import ( - "context" "encoding/json" "errors" "fmt" @@ -141,7 +140,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configuration) * func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli compile`") - ctx := context.Background() + ctx := cmd.Context() if profileArg.Get() != "" { if len(libraries) > 0 { @@ -178,7 +177,7 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer fqbnArg.Set(profile.GetFqbn()) } - fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) + fqbn, port := arguments.CalculateFQBNAndPort(ctx, &portArgs, &fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) if keysKeychain != "" || signKey != "" || encryptKey != "" { arguments.CheckFlagsMandatory(cmd, "keys-keychain", "sign-key", "encrypt-key") @@ -274,7 +273,7 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer prog := profile.GetProgrammer() if prog == "" || programmer.GetProgrammer() != "" { - prog = programmer.String(inst, srv, fqbn) + prog = programmer.String(ctx, inst, srv, fqbn) } if prog == "" { prog = sk.GetDefaultProgrammer() diff --git a/internal/cli/config/get.go b/internal/cli/config/get.go index 3061333366c..3dfb5345c20 100644 --- a/internal/cli/config/get.go +++ b/internal/cli/config/get.go @@ -39,7 +39,7 @@ func initGetCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " config get board_manager.additional_urls", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runGetCommand(srv, args) + runGetCommand(cmd.Context(), srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { ctx := cmd.Context() @@ -49,9 +49,8 @@ func initGetCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return getCommand } -func runGetCommand(srv rpc.ArduinoCoreServiceServer, args []string) { +func runGetCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli config get`") - ctx := context.Background() for _, toGet := range args { resp, err := srv.SettingsGetValue(ctx, &rpc.SettingsGetValueRequest{Key: toGet}) diff --git a/internal/cli/core/download.go b/internal/cli/core/download.go index 790945fa3c7..fb5fe3f3818 100644 --- a/internal/cli/core/download.go +++ b/internal/cli/core/download.go @@ -39,17 +39,16 @@ func initDownloadCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " core download arduino:samd@1.6.9 # " + tr("download a specific version (in this case 1.6.9)."), Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runDownloadCommand(srv, args) + runDownloadCommand(cmd.Context(), srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableCores(context.Background(), srv), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableCores(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }, } return downloadCommand } -func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { - ctx := context.Background() +func runDownloadCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli core download`") diff --git a/internal/cli/core/install.go b/internal/cli/core/install.go index 18dfe910d51..988602fc2ac 100644 --- a/internal/cli/core/install.go +++ b/internal/cli/core/install.go @@ -45,10 +45,10 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { arguments.CheckFlagsConflicts(cmd, "run-post-install", "skip-post-install") }, Run: func(cmd *cobra.Command, args []string) { - runInstallCommand(srv, args, scriptFlags, noOverwrite) + runInstallCommand(cmd.Context(), srv, args, scriptFlags, noOverwrite) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableCores(context.Background(), srv), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableCores(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }, } scriptFlags.AddToCommand(installCommand) @@ -56,9 +56,8 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return installCommand } -func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, scriptFlags arguments.PrePostScriptsFlags, noOverwrite bool) { +func runInstallCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, scriptFlags arguments.PrePostScriptsFlags, noOverwrite bool) { logrus.Info("Executing `arduino-cli core install`") - ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) platformsRefs, err := arguments.ParseReferences(ctx, srv, args) diff --git a/internal/cli/core/list.go b/internal/cli/core/list.go index ec926240fea..3c2dd954818 100644 --- a/internal/cli/core/list.go +++ b/internal/cli/core/list.go @@ -38,7 +38,7 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " core list", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runListCommand(srv, all, updatableOnly) + runListCommand(cmd.Context(), srv, all, updatableOnly) }, } listCommand.Flags().BoolVar(&updatableOnly, "updatable", false, tr("List updatable platforms.")) @@ -46,8 +46,7 @@ func initListCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return listCommand } -func runListCommand(srv rpc.ArduinoCoreServiceServer, all bool, updatableOnly bool) { - ctx := context.Background() +func runListCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, all bool, updatableOnly bool) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli core list`") List(ctx, srv, inst, all, updatableOnly) diff --git a/internal/cli/core/search.go b/internal/cli/core/search.go index 6ec72e4246f..8a58cbf5a57 100644 --- a/internal/cli/core/search.go +++ b/internal/cli/core/search.go @@ -41,7 +41,7 @@ func initSearchCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " core search MKRZero -a -v", Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { - runSearchCommand(srv, args, allVersions) + runSearchCommand(cmd.Context(), srv, args, allVersions) }, } searchCommand.Flags().BoolVarP(&allVersions, "all", "a", false, tr("Show all available core versions.")) @@ -52,8 +52,7 @@ func initSearchCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { // indexUpdateInterval specifies the time threshold over which indexes are updated const indexUpdateInterval = 24 * time.Hour -func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, allVersions bool) { - ctx := context.Background() +func runSearchCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, allVersions bool) { inst := instance.CreateAndInit(ctx, srv) stream, res := commands.UpdateIndexStreamResponseToCallbackFunction(ctx, feedback.ProgressBar()) diff --git a/internal/cli/core/uninstall.go b/internal/cli/core/uninstall.go index e06f630bf31..a5df772935c 100644 --- a/internal/cli/core/uninstall.go +++ b/internal/cli/core/uninstall.go @@ -38,19 +38,18 @@ func initUninstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " core uninstall arduino:samd\n", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runUninstallCommand(srv, args, preUninstallFlags) + runUninstallCommand(cmd.Context(), srv, args, preUninstallFlags) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetUninstallableCores(context.Background(), srv), cobra.ShellCompDirectiveDefault + return arguments.GetUninstallableCores(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }, } preUninstallFlags.AddToCommand(uninstallCommand) return uninstallCommand } -func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, preUninstallFlags arguments.PrePostScriptsFlags) { +func runUninstallCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, preUninstallFlags arguments.PrePostScriptsFlags) { logrus.Info("Executing `arduino-cli core uninstall`") - ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) platformsRefs, err := arguments.ParseReferences(ctx, srv, args) diff --git a/internal/cli/core/update_index.go b/internal/cli/core/update_index.go index 01cecd4fd9a..c7f0129291b 100644 --- a/internal/cli/core/update_index.go +++ b/internal/cli/core/update_index.go @@ -36,15 +36,14 @@ func initUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " core update-index", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runUpdateIndexCommand(srv) + runUpdateIndexCommand(cmd.Context(), srv) }, } return updateIndexCommand } -func runUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) { +func runUpdateIndexCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli core update-index`") - ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) resp := UpdateIndex(ctx, srv, inst) diff --git a/internal/cli/core/upgrade.go b/internal/cli/core/upgrade.go index 3d831d0a8db..03185784536 100644 --- a/internal/cli/core/upgrade.go +++ b/internal/cli/core/upgrade.go @@ -43,16 +43,15 @@ func initUpgradeCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " # " + tr("upgrade arduino:samd to the latest version") + "\n" + " " + os.Args[0] + " core upgrade arduino:samd", Run: func(cmd *cobra.Command, args []string) { - runUpgradeCommand(srv, args, postInstallFlags.DetectSkipPostInstallValue(), postInstallFlags.DetectSkipPreUninstallValue()) + runUpgradeCommand(cmd.Context(), srv, args, postInstallFlags.DetectSkipPostInstallValue(), postInstallFlags.DetectSkipPreUninstallValue()) }, } postInstallFlags.AddToCommand(upgradeCommand) return upgradeCommand } -func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, args []string, skipPostInstall bool, skipPreUninstall bool) { +func runUpgradeCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, skipPostInstall bool, skipPreUninstall bool) { logrus.Info("Executing `arduino-cli core upgrade`") - ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) Upgrade(ctx, srv, inst, args, skipPostInstall, skipPreUninstall) } diff --git a/internal/cli/debug/debug.go b/internal/cli/debug/debug.go index cb0f37fce58..3da3c125371 100644 --- a/internal/cli/debug/debug.go +++ b/internal/cli/debug/debug.go @@ -56,7 +56,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " debug -b arduino:samd:mkr1000 -P atmel_ice /home/user/Arduino/MySketch", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runDebugCommand(srv, args, &portArgs, &fqbnArg, interpreter, importDir, &programmer, printInfo, &profileArg) + runDebugCommand(cmd.Context(), srv, args, &portArgs, &fqbnArg, interpreter, importDir, &programmer, printInfo, &profileArg) }, } @@ -72,10 +72,9 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return debugCommand } -func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, +func runDebugCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, importDir string, programmer *arguments.Programmer, printInfo bool, profileArg *arguments.Profile) { logrus.Info("Executing `arduino-cli debug`") - ctx := context.Background() path := "" if len(args) > 0 { @@ -103,11 +102,11 @@ func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs * fqbnArg.Set(profile.GetFqbn()) } - fqbn, port := arguments.CalculateFQBNAndPort(portArgs, fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) + fqbn, port := arguments.CalculateFQBNAndPort(ctx, portArgs, fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol()) prog := profile.GetProgrammer() if prog == "" || programmer.GetProgrammer() != "" { - prog = programmer.String(inst, srv, fqbn) + prog = programmer.String(ctx, inst, srv, fqbn) } if prog == "" { prog = sk.GetDefaultProgrammer() @@ -125,7 +124,7 @@ func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs * if printInfo { - if res, err := commands.GetDebugConfig(context.Background(), debugConfigRequested); err != nil { + if res, err := commands.GetDebugConfig(ctx, debugConfigRequested); err != nil { errcode := feedback.ErrBadArgument if errors.Is(err, &cmderrors.MissingProgrammerError{}) { errcode = feedback.ErrMissingProgrammer @@ -145,7 +144,7 @@ func runDebugCommand(srv rpc.ArduinoCoreServiceServer, args []string, portArgs * if err != nil { feedback.FatalError(err, feedback.ErrBadArgument) } - if _, err := commands.Debug(context.Background(), debugConfigRequested, in, out, ctrlc); err != nil { + if _, err := commands.Debug(ctx, debugConfigRequested, in, out, ctrlc); err != nil { errcode := feedback.ErrGeneric if errors.Is(err, &cmderrors.MissingProgrammerError{}) { errcode = feedback.ErrMissingProgrammer diff --git a/internal/cli/debug/debug_check.go b/internal/cli/debug/debug_check.go index 81cc70cb1d5..c16bb13cc25 100644 --- a/internal/cli/debug/debug_check.go +++ b/internal/cli/debug/debug_check.go @@ -41,7 +41,7 @@ func newDebugCheckCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Short: tr("Check if the given board/programmer combination supports debugging."), Example: " " + os.Args[0] + " debug check -b arduino:samd:mkr1000 -P atmel_ice", Run: func(cmd *cobra.Command, args []string) { - runDebugCheckCommand(srv, &portArgs, &fqbnArg, interpreter, &programmer) + runDebugCheckCommand(cmd.Context(), srv, &portArgs, &fqbnArg, interpreter, &programmer) }, } fqbnArg.AddToCommand(debugCheckCommand, srv) @@ -51,22 +51,21 @@ func newDebugCheckCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return debugCheckCommand } -func runDebugCheckCommand(srv rpc.ArduinoCoreServiceServer, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, programmerArg *arguments.Programmer) { - ctx := context.Background() +func runDebugCheckCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, interpreter string, programmerArg *arguments.Programmer) { instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli debug`") - port, err := portArgs.GetPort(instance, srv, "", "") + port, err := portArgs.GetPort(ctx, instance, srv, "", "") if err != nil { feedback.FatalError(err, feedback.ErrBadArgument) } fqbn := fqbnArg.String() - resp, err := commands.IsDebugSupported(context.Background(), &rpc.IsDebugSupportedRequest{ + resp, err := commands.IsDebugSupported(ctx, &rpc.IsDebugSupportedRequest{ Instance: instance, Fqbn: fqbn, Port: port, Interpreter: interpreter, - Programmer: programmerArg.String(instance, srv, fqbn), + Programmer: programmerArg.String(ctx, instance, srv, fqbn), }) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) diff --git a/internal/cli/lib/check_deps.go b/internal/cli/lib/check_deps.go index 26cd954739c..8e18e800515 100644 --- a/internal/cli/lib/check_deps.go +++ b/internal/cli/lib/check_deps.go @@ -42,18 +42,17 @@ func initDepsCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " lib deps AudioZero@1.0.0 # " + tr("for the specific version."), Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - runDepsCommand(srv, args, noOverwrite) + runDepsCommand(cmd.Context(), srv, args, noOverwrite) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstalledLibraries(context.Background(), srv), cobra.ShellCompDirectiveDefault + return arguments.GetInstalledLibraries(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }, } depsCommand.Flags().BoolVar(&noOverwrite, "no-overwrite", false, tr("Do not try to update library dependencies if already installed.")) return depsCommand } -func runDepsCommand(srv rpc.ArduinoCoreServiceServer, args []string, noOverwrite bool) { - ctx := context.Background() +func runDepsCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, noOverwrite bool) { instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib deps`") diff --git a/internal/cli/lib/download.go b/internal/cli/lib/download.go index b20877bea01..562f8b07bb9 100644 --- a/internal/cli/lib/download.go +++ b/internal/cli/lib/download.go @@ -39,18 +39,17 @@ func initDownloadCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " lib download AudioZero@1.0.0 # " + tr("for a specific version."), Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runDownloadCommand(srv, args) + runDownloadCommand(cmd.Context(), srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableLibs(context.Background(), srv), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableLibs(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }, } return downloadCommand } -func runDownloadCommand(srv rpc.ArduinoCoreServiceServer, args []string) { +func runDownloadCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib download`") - ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) refs, err := ParseLibraryReferenceArgsAndAdjustCase(ctx, srv, instance, args) diff --git a/internal/cli/lib/examples.go b/internal/cli/lib/examples.go index 3b5921f8ea0..ff24e3616cb 100644 --- a/internal/cli/lib/examples.go +++ b/internal/cli/lib/examples.go @@ -45,19 +45,18 @@ func initExamplesCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " lib examples Wire", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runExamplesCommand(srv, args) + runExamplesCommand(cmd.Context(), srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstalledLibraries(context.Background(), srv), cobra.ShellCompDirectiveDefault + return arguments.GetInstalledLibraries(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }, } fqbn.AddToCommand(examplesCommand, srv) return examplesCommand } -func runExamplesCommand(srv rpc.ArduinoCoreServiceServer, args []string) { +func runExamplesCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib examples`") - ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) name := "" diff --git a/internal/cli/lib/install.go b/internal/cli/lib/install.go index 7465b4f4fbd..fbde0cf8a6b 100644 --- a/internal/cli/lib/install.go +++ b/internal/cli/lib/install.go @@ -52,10 +52,10 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configur " " + os.Args[0] + " lib install --zip-path /path/to/WiFi101.zip /path/to/ArduinoBLE.zip\n", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runInstallCommand(srv, args, noDeps, noOverwrite, gitURL, zipPath, useBuiltinLibrariesDir, enableUnsafeInstall) + runInstallCommand(cmd.Context(), srv, args, noDeps, noOverwrite, gitURL, zipPath, useBuiltinLibrariesDir, enableUnsafeInstall) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetInstallableLibs(context.Background(), srv), cobra.ShellCompDirectiveDefault + return arguments.GetInstallableLibs(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }, } installCommand.Flags().BoolVar(&noDeps, "no-deps", false, tr("Do not install dependencies.")) @@ -66,8 +66,7 @@ func initInstallCommand(srv rpc.ArduinoCoreServiceServer, settings *rpc.Configur return installCommand } -func runInstallCommand(srv rpc.ArduinoCoreServiceServer, args []string, noDeps bool, noOverwrite bool, gitURL bool, zipPath bool, useBuiltinLibrariesDir bool, enableUnsafeInstall bool) { - ctx := context.Background() +func runInstallCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, noDeps bool, noOverwrite bool, gitURL bool, zipPath bool, useBuiltinLibrariesDir bool, enableUnsafeInstall bool) { instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib install`") diff --git a/internal/cli/lib/list.go b/internal/cli/lib/list.go index 8d743bb3ba3..f764df4985c 100644 --- a/internal/cli/lib/list.go +++ b/internal/cli/lib/list.go @@ -45,7 +45,7 @@ not listed, they can be listed by adding the --all flag.`), Example: " " + os.Args[0] + " lib list", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - ctx := context.Background() + ctx := cmd.Context() instance := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib list`") List(ctx, srv, instance, args, all, updatable) diff --git a/internal/cli/lib/search.go b/internal/cli/lib/search.go index 4bfa3c06a7c..94780be95c4 100644 --- a/internal/cli/lib/search.go +++ b/internal/cli/lib/search.go @@ -90,7 +90,7 @@ In addition to the fields listed above, QV terms can use these qualifiers: " " + os.Args[0] + " lib search dependencies=IRremote # " + tr("libraries that depend only on \"IRremote\"") + "\n", Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { - runSearchCommand(srv, args, namesOnly, omitReleasesDetails) + runSearchCommand(cmd.Context(), srv, args, namesOnly, omitReleasesDetails) }, } searchCommand.Flags().BoolVar(&namesOnly, "names", false, tr("Show library names only.")) @@ -101,8 +101,7 @@ In addition to the fields listed above, QV terms can use these qualifiers: // indexUpdateInterval specifies the time threshold over which indexes are updated const indexUpdateInterval = 60 * time.Minute -func runSearchCommand(srv rpc.ArduinoCoreServiceServer, args []string, namesOnly bool, omitReleasesDetails bool) { - ctx := context.Background() +func runSearchCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, namesOnly bool, omitReleasesDetails bool) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib search`") diff --git a/internal/cli/lib/uninstall.go b/internal/cli/lib/uninstall.go index d8129ec42db..07ca7248db2 100644 --- a/internal/cli/lib/uninstall.go +++ b/internal/cli/lib/uninstall.go @@ -37,18 +37,17 @@ func initUninstallCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " lib uninstall AudioZero", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - runUninstallCommand(srv, args) + runUninstallCommand(cmd.Context(), srv, args) }, ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - return arguments.GetUninstallableLibraries(context.Background(), srv), cobra.ShellCompDirectiveDefault + return arguments.GetUninstallableLibraries(cmd.Context(), srv), cobra.ShellCompDirectiveDefault }, } return uninstallCommand } -func runUninstallCommand(srv rpc.ArduinoCoreServiceServer, args []string) { +func runUninstallCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib uninstall`") - ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) refs, err := ParseLibraryReferenceArgsAndAdjustCase(ctx, srv, instance, args) diff --git a/internal/cli/lib/update_index.go b/internal/cli/lib/update_index.go index f5f5c62cea8..a9c93240b10 100644 --- a/internal/cli/lib/update_index.go +++ b/internal/cli/lib/update_index.go @@ -36,14 +36,13 @@ func initUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " lib update-index", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runUpdateIndexCommand(srv) + runUpdateIndexCommand(cmd.Context(), srv) }, } return updateIndexCommand } -func runUpdateIndexCommand(srv rpc.ArduinoCoreServiceServer) { - ctx := context.Background() +func runUpdateIndexCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli lib update-index`") diff --git a/internal/cli/lib/upgrade.go b/internal/cli/lib/upgrade.go index 6c612eb0089..bb0da0caaea 100644 --- a/internal/cli/lib/upgrade.go +++ b/internal/cli/lib/upgrade.go @@ -38,15 +38,14 @@ func initUpgradeCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " lib upgrade Audio ArduinoJson", Args: cobra.ArbitraryArgs, Run: func(cmd *cobra.Command, args []string) { - runUpgradeCommand(srv, args) + runUpgradeCommand(cmd.Context(), srv, args) }, } return upgradeCommand } -func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, args []string) { +func runUpgradeCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string) { logrus.Info("Executing `arduino-cli lib upgrade`") - ctx := context.Background() instance := instance.CreateAndInit(ctx, srv) Upgrade(ctx, srv, instance, args) } diff --git a/internal/cli/monitor/monitor.go b/internal/cli/monitor/monitor.go index 1e9eddbde53..eb237521445 100644 --- a/internal/cli/monitor/monitor.go +++ b/internal/cli/monitor/monitor.go @@ -66,7 +66,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { if len(args) > 0 { sketchPath = args[0] } - runMonitorCmd(srv, &portArgs, &fqbnArg, &profileArg, sketchPath, configs, describe, timestamp, quiet, raw) + runMonitorCmd(cmd.Context(), srv, &portArgs, &fqbnArg, &profileArg, sketchPath, configs, describe, timestamp, quiet, raw) }, } portArgs.AddToCommand(monitorCommand, srv) @@ -81,12 +81,11 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { } func runMonitorCmd( - srv rpc.ArduinoCoreServiceServer, + ctx context.Context, srv rpc.ArduinoCoreServiceServer, portArgs *arguments.Port, fqbnArg *arguments.Fqbn, profileArg *arguments.Profile, sketchPathArg string, configs []string, describe, timestamp, quiet, raw bool, ) { logrus.Info("Executing `arduino-cli monitor`") - ctx := context.Background() if !feedback.HasConsole() { quiet = true @@ -139,10 +138,10 @@ func runMonitorCmd( case sketch.GetDefaultFqbn() != "": fqbn = sketch.GetDefaultFqbn() default: - fqbn, _ = portArgs.DetectFQBN(inst, srv) + fqbn, _ = portArgs.DetectFQBN(ctx, inst, srv) } - portAddress, portProtocol, err := portArgs.GetPortAddressAndProtocol(inst, srv, defaultPort, defaultProtocol) + portAddress, portProtocol, err := portArgs.GetPortAddressAndProtocol(ctx, inst, srv, defaultPort, defaultProtocol) if err != nil { feedback.FatalError(err, feedback.ErrGeneric) } diff --git a/internal/cli/outdated/outdated.go b/internal/cli/outdated/outdated.go index 54d1aec70b7..7ca0a442e06 100644 --- a/internal/cli/outdated/outdated.go +++ b/internal/cli/outdated/outdated.go @@ -46,15 +46,14 @@ that can be upgraded. If nothing needs to be updated the output is empty.`), Example: " " + os.Args[0] + " outdated\n", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runOutdatedCommand(srv) + runOutdatedCommand(cmd.Context(), srv) }, } return outdatedCommand } -func runOutdatedCommand(srv rpc.ArduinoCoreServiceServer) { +func runOutdatedCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli outdated`") - ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) Outdated(ctx, srv, inst) } diff --git a/internal/cli/sketch/archive.go b/internal/cli/sketch/archive.go index 2de1cd0ddaf..19b2a280651 100644 --- a/internal/cli/sketch/archive.go +++ b/internal/cli/sketch/archive.go @@ -43,7 +43,7 @@ func initArchiveCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { " " + os.Args[0] + " archive /home/user/Arduino/MySketch /home/user/MySketchArchive.zip", Args: cobra.MaximumNArgs(2), Run: func(cmd *cobra.Command, args []string) { - runArchiveCommand(srv, args, includeBuildDir, overwrite) + runArchiveCommand(cmd.Context(), srv, args, includeBuildDir, overwrite) }, } @@ -53,9 +53,8 @@ func initArchiveCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return archiveCommand } -func runArchiveCommand(srv rpc.ArduinoCoreServiceServer, args []string, includeBuildDir bool, overwrite bool) { +func runArchiveCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, includeBuildDir bool, overwrite bool) { logrus.Info("Executing `arduino-cli sketch archive`") - ctx := context.Background() sketchPathArg := "" if len(args) > 0 { sketchPathArg = args[0] diff --git a/internal/cli/sketch/new.go b/internal/cli/sketch/new.go index 5be99e4308b..79dfcccc373 100644 --- a/internal/cli/sketch/new.go +++ b/internal/cli/sketch/new.go @@ -38,7 +38,7 @@ func initNewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " sketch new MultiBlinker", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - runNewCommand(srv, args, overwrite) + runNewCommand(cmd.Context(), srv, args, overwrite) }, } @@ -47,8 +47,7 @@ func initNewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return newCommand } -func runNewCommand(srv rpc.ArduinoCoreServiceServer, args []string, overwrite bool) { - ctx := context.Background() +func runNewCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, overwrite bool) { logrus.Info("Executing `arduino-cli sketch new`") // Trim to avoid issues if user creates a sketch adding the .ino extesion to the name inputSketchName := args[0] diff --git a/internal/cli/update/update.go b/internal/cli/update/update.go index 82b94135f74..6fd4e7c91e0 100644 --- a/internal/cli/update/update.go +++ b/internal/cli/update/update.go @@ -41,16 +41,15 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " update", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runUpdateCommand(srv, showOutdated) + runUpdateCommand(cmd.Context(), srv, showOutdated) }, } updateCommand.Flags().BoolVar(&showOutdated, "show-outdated", false, tr("Show outdated cores and libraries after index update")) return updateCommand } -func runUpdateCommand(srv rpc.ArduinoCoreServiceServer, showOutdated bool) { +func runUpdateCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, showOutdated bool) { logrus.Info("Executing `arduino-cli update`") - ctx := context.Background() inst := instance.CreateAndInit(ctx, srv) lib.UpdateIndex(ctx, srv, inst) diff --git a/internal/cli/upgrade/upgrade.go b/internal/cli/upgrade/upgrade.go index 1fee19a4443..4c311201dab 100644 --- a/internal/cli/upgrade/upgrade.go +++ b/internal/cli/upgrade/upgrade.go @@ -41,15 +41,14 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " upgrade", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runUpgradeCommand(srv, postInstallFlags.DetectSkipPostInstallValue(), postInstallFlags.DetectSkipPreUninstallValue()) + runUpgradeCommand(cmd.Context(), srv, postInstallFlags.DetectSkipPostInstallValue(), postInstallFlags.DetectSkipPreUninstallValue()) }, } postInstallFlags.AddToCommand(upgradeCommand) return upgradeCommand } -func runUpgradeCommand(srv rpc.ArduinoCoreServiceServer, skipPostInstall bool, skipPreUninstall bool) { - ctx := context.Background() +func runUpgradeCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, skipPostInstall bool, skipPreUninstall bool) { inst := instance.CreateAndInit(ctx, srv) logrus.Info("Executing `arduino-cli upgrade`") lib.Upgrade(ctx, srv, inst, []string{}) diff --git a/internal/cli/upload/upload.go b/internal/cli/upload/upload.go index b3d89259817..752a1a5ccc4 100644 --- a/internal/cli/upload/upload.go +++ b/internal/cli/upload/upload.go @@ -63,7 +63,7 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { arguments.CheckFlagsConflicts(cmd, "input-file", "input-dir") }, Run: func(cmd *cobra.Command, args []string) { - runUploadCommand(srv, args, uploadFields) + runUploadCommand(cmd.Context(), srv, args, uploadFields) }, } @@ -81,11 +81,9 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { return uploadCommand } -func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFieldsArgs map[string]string) { +func runUploadCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args []string, uploadFieldsArgs map[string]string) { logrus.Info("Executing `arduino-cli upload`") - ctx := context.Background() - path := "" if len(args) > 0 { path = args[0] @@ -116,7 +114,7 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie defaultFQBN := sketch.GetDefaultFqbn() defaultAddress := sketch.GetDefaultPort() defaultProtocol := sketch.GetDefaultProtocol() - fqbn, port := arguments.CalculateFQBNAndPort(&portArgs, &fqbnArg, inst, srv, defaultFQBN, defaultAddress, defaultProtocol) + fqbn, port := arguments.CalculateFQBNAndPort(ctx, &portArgs, &fqbnArg, inst, srv, defaultFQBN, defaultAddress, defaultProtocol) userFieldRes, err := srv.SupportedUserFields(ctx, &rpc.SupportedUserFieldsRequest{ Instance: inst, @@ -179,7 +177,7 @@ func runUploadCommand(srv rpc.ArduinoCoreServiceServer, args []string, uploadFie prog := profile.GetProgrammer() if prog == "" || programmer.GetProgrammer() != "" { - prog = programmer.String(inst, srv, fqbn) + prog = programmer.String(ctx, inst, srv, fqbn) } if prog == "" { prog = sketch.GetDefaultProgrammer() diff --git a/internal/cli/version/version.go b/internal/cli/version/version.go index 9c8633aeee1..8c5d8eec4c1 100644 --- a/internal/cli/version/version.go +++ b/internal/cli/version/version.go @@ -40,13 +40,13 @@ func NewCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command { Example: " " + os.Args[0] + " version", Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - runVersionCommand(srv) + runVersionCommand(cmd.Context(), srv) }, } return versionCommand } -func runVersionCommand(srv rpc.ArduinoCoreServiceServer) { +func runVersionCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer) { logrus.Info("Executing `arduino-cli version`") info := version.VersionInfo @@ -58,7 +58,7 @@ func runVersionCommand(srv rpc.ArduinoCoreServiceServer) { } latestVersion := "" - res, err := srv.CheckForArduinoCLIUpdates(context.Background(), &rpc.CheckForArduinoCLIUpdatesRequest{}) + res, err := srv.CheckForArduinoCLIUpdates(ctx, &rpc.CheckForArduinoCLIUpdatesRequest{}) if err != nil { feedback.Warning("Failed to check for updates: " + err.Error()) } else { From 6cf4eb7d20bcb1bc7372648bc76b721f50df005f Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 30 Apr 2024 18:25:19 +0200 Subject: [PATCH 48/56] Removed unused parameter --- internal/arduino/builder/internal/detector/detector.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/arduino/builder/internal/detector/detector.go b/internal/arduino/builder/internal/detector/detector.go index 98d497d475c..8f9a305cea4 100644 --- a/internal/arduino/builder/internal/detector/detector.go +++ b/internal/arduino/builder/internal/detector/detector.go @@ -272,7 +272,7 @@ func (l *SketchLibrariesDetector) findIncludes( } for !sourceFileQueue.empty() { - err := l.findIncludesUntilDone(ctx, cache, sourceFileQueue, buildProperties, sketchBuildPath, librariesBuildPath, platformArch) + err := l.findIncludesUntilDone(ctx, cache, sourceFileQueue, buildProperties, librariesBuildPath, platformArch) if err != nil { cachePath.Remove() return err @@ -304,7 +304,6 @@ func (l *SketchLibrariesDetector) findIncludesUntilDone( cache *includeCache, sourceFileQueue *uniqueSourceFileQueue, buildProperties *properties.Map, - sketchBuildPath *paths.Path, librariesBuildPath *paths.Path, platformArch string, ) error { From 27e9c3e4dcb31961ca60911032b89bb90c59a642 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 2 May 2024 15:00:53 +0200 Subject: [PATCH 49/56] Tolerate errors in invalid config files, and report them as warnings --- commands/service_settings.go | 14 ++- internal/go-configmap/errors.go | 54 ++++++++++++ internal/go-configmap/yaml.go | 5 +- .../integrationtest/config/config_test.go | 27 ++++++ main.go | 6 +- rpc/cc/arduino/cli/commands/v1/settings.pb.go | 87 +++++++++++-------- rpc/cc/arduino/cli/commands/v1/settings.proto | 6 +- 7 files changed, 155 insertions(+), 44 deletions(-) create mode 100644 internal/go-configmap/errors.go diff --git a/commands/service_settings.go b/commands/service_settings.go index 82bdb030aeb..2871844b8b8 100644 --- a/commands/service_settings.go +++ b/commands/service_settings.go @@ -22,7 +22,9 @@ import ( "reflect" "github.com/arduino/arduino-cli/commands/cmderrors" + f "github.com/arduino/arduino-cli/internal/algorithms" "github.com/arduino/arduino-cli/internal/cli/configuration" + "github.com/arduino/arduino-cli/internal/go-configmap" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "google.golang.org/protobuf/proto" "gopkg.in/yaml.v3" @@ -187,15 +189,21 @@ func (s *arduinoCoreServerImpl) ConfigurationSave(ctx context.Context, req *rpc. // SettingsReadFromFile read settings from a YAML file and replace the settings currently stored in memory. func (s *arduinoCoreServerImpl) ConfigurationOpen(ctx context.Context, req *rpc.ConfigurationOpenRequest) (*rpc.ConfigurationOpenResponse, error) { + warnings := []string{} + switch req.GetSettingsFormat() { case "yaml": err := yaml.Unmarshal([]byte(req.GetEncodedSettings()), s.settings) - if err != nil { + if errs, ok := err.(*configmap.UnmarshalErrors); ok { + warnings = f.Map(errs.WrappedErrors(), (error).Error) + } else if err != nil { return nil, fmt.Errorf("error unmarshalling settings: %v", err) } case "json": err := json.Unmarshal([]byte(req.GetEncodedSettings()), s.settings) - if err != nil { + if errs, ok := err.(*configmap.UnmarshalErrors); ok { + warnings = f.Map(errs.WrappedErrors(), (error).Error) + } else if err != nil { return nil, fmt.Errorf("error unmarshalling settings: %v", err) } default: @@ -203,7 +211,7 @@ func (s *arduinoCoreServerImpl) ConfigurationOpen(ctx context.Context, req *rpc. } configuration.InjectEnvVars(s.settings) - return &rpc.ConfigurationOpenResponse{}, nil + return &rpc.ConfigurationOpenResponse{Warnings: warnings}, nil } // SettingsEnumerate returns the list of all the settings keys. diff --git a/internal/go-configmap/errors.go b/internal/go-configmap/errors.go new file mode 100644 index 00000000000..2ad42f3e129 --- /dev/null +++ b/internal/go-configmap/errors.go @@ -0,0 +1,54 @@ +// This file is part of arduino-cli. +// +// Copyright 2024 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 configmap + +import "strings" + +// UnmarshalErrors is a collection of errors that occurred during unmarshalling. +// Do not return this type directly, but use its result() method instead. +type UnmarshalErrors struct { + wrapped []error +} + +func (e *UnmarshalErrors) append(err error) { + e.wrapped = append(e.wrapped, err) +} + +func (e *UnmarshalErrors) result() error { + if len(e.wrapped) == 0 { + return nil + } + return e +} + +func (e *UnmarshalErrors) Error() string { + if len(e.wrapped) == 1 { + return e.wrapped[0].Error() + } + errs := []string{"multiple errors:"} + for _, err := range e.wrapped { + errs = append(errs, "- "+err.Error()) + } + return strings.Join(errs, "\n") +} + +// WrappedErrors returns the list of errors that occurred during unmarshalling. +func (e *UnmarshalErrors) WrappedErrors() []error { + if e == nil { + return nil + } + return e.wrapped +} diff --git a/internal/go-configmap/yaml.go b/internal/go-configmap/yaml.go index 214e12ba727..e58f8f31ecf 100644 --- a/internal/go-configmap/yaml.go +++ b/internal/go-configmap/yaml.go @@ -29,10 +29,11 @@ func (c *Map) UnmarshalYAML(node *yaml.Node) error { return err } + errs := &UnmarshalErrors{} for k, v := range flattenMap(in) { if err := c.Set(k, v); err != nil { - return err + errs.append(err) } } - return nil + return errs.result() } diff --git a/internal/integrationtest/config/config_test.go b/internal/integrationtest/config/config_test.go index 2742a7205f3..d180ea5699e 100644 --- a/internal/integrationtest/config/config_test.go +++ b/internal/integrationtest/config/config_test.go @@ -17,6 +17,7 @@ package config_test import ( "path/filepath" + "strings" "testing" "github.com/arduino/arduino-cli/internal/integrationtest" @@ -867,3 +868,29 @@ func TestInitializationOrderOfConfigThroughFlagAndEnv(t *testing.T) { require.NoError(t, err) requirejson.Contains(t, stdout, `{"config":{ "locale": "test" }}`) } + +func TestConfigLoadWithUnknownOrInvalidKeys(t *testing.T) { + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + tmp := t.TempDir() + unkwnownConfig := paths.New(filepath.Join(tmp, "unknown.yaml")) + unkwnownConfig.WriteFile([]byte(` +unk: "test" +build.unk: 123 +`)) + t.Cleanup(func() { unkwnownConfig.Remove() }) + + // Run "config get" with a configuration containing an unknown key + out, _, err := cli.Run("config", "get", "locale", "--config-file", unkwnownConfig.String()) + require.NoError(t, err) + require.Equal(t, "en", strings.TrimSpace(string(out))) + + // Run "config get" with a configuration containing an invalid key + invalidConfig := paths.New(filepath.Join(tmp, "invalid.yaml")) + invalidConfig.WriteFile([]byte(`locale: 123`)) + t.Cleanup(func() { invalidConfig.Remove() }) + out, _, err = cli.Run("config", "get", "locale", "--config-file", invalidConfig.String()) + require.NoError(t, err) + require.Equal(t, "en", strings.TrimSpace(string(out))) +} diff --git a/main.go b/main.go index 6d49b0e4933..52499c7ae1d 100644 --- a/main.go +++ b/main.go @@ -45,8 +45,12 @@ func main() { } else if !os.IsNotExist(err) { feedback.FatalError(fmt.Errorf("couldn't read configuration file: %w", err), feedback.ErrGeneric) } - if _, err := srv.ConfigurationOpen(ctx, openReq); err != nil { + if resp, err := srv.ConfigurationOpen(ctx, openReq); err != nil { feedback.FatalError(fmt.Errorf("couldn't load configuration: %w", err), feedback.ErrGeneric) + } else if warnings := resp.GetWarnings(); len(warnings) > 0 { + for _, warning := range warnings { + feedback.Warning(warning) + } } // Get the current settings from the server diff --git a/rpc/cc/arduino/cli/commands/v1/settings.pb.go b/rpc/cc/arduino/cli/commands/v1/settings.pb.go index 13765e459b7..e367998c9ab 100644 --- a/rpc/cc/arduino/cli/commands/v1/settings.pb.go +++ b/rpc/cc/arduino/cli/commands/v1/settings.pb.go @@ -407,6 +407,10 @@ type ConfigurationOpenResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Warnings that occurred while opening the configuration (e.g. unknown keys, + // or invalid values) + Warnings []string `protobuf:"bytes,1,rep,name=warnings,proto3" json:"warnings,omitempty"` } func (x *ConfigurationOpenResponse) Reset() { @@ -441,6 +445,13 @@ func (*ConfigurationOpenResponse) Descriptor() ([]byte, []int) { return file_cc_arduino_cli_commands_v1_settings_proto_rawDescGZIP(), []int{6} } +func (x *ConfigurationOpenResponse) GetWarnings() []string { + if x != nil { + return x.Warnings + } + return nil +} + type SettingsGetValueRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1527,44 +1538,46 @@ var file_cc_arduino_cli_commands_v1_settings_proto_rawDesc = []byte{ 0x28, 0x09, 0x52, 0x0f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x1b, 0x0a, 0x19, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x37, 0x0a, 0x19, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x65, - 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x0a, 0x17, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, - 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x3f, 0x0a, 0x18, 0x53, 0x65, 0x74, - 0x74, 0x69, 0x6e, 0x67, 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, - 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x6e, - 0x63, 0x6f, 0x64, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x73, 0x0a, 0x17, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x63, 0x6f, 0x64, - 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, - 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, - 0x1a, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x53, - 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x55, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 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, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x2d, 0x0a, 0x05, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 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, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x4e, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x3f, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x47, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, + 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x73, 0x0a, 0x17, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x6e, 0x63, 0x6f, + 0x64, 0x65, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0x1a, 0x0a, 0x18, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x53, 0x65, 0x74, 0x74, 0x69, + 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x19, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x55, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x3b, 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, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x1a, 0x2d, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 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 ( diff --git a/rpc/cc/arduino/cli/commands/v1/settings.proto b/rpc/cc/arduino/cli/commands/v1/settings.proto index 71631e56b99..c55a2c122f3 100644 --- a/rpc/cc/arduino/cli/commands/v1/settings.proto +++ b/rpc/cc/arduino/cli/commands/v1/settings.proto @@ -120,7 +120,11 @@ message ConfigurationOpenRequest { string settings_format = 2; } -message ConfigurationOpenResponse {} +message ConfigurationOpenResponse { + // Warnings that occurred while opening the configuration (e.g. unknown keys, + // or invalid values) + repeated string warnings = 1; +} message SettingsGetValueRequest { // The key to get From 7658db6d637c75f3b1372294e1cd6387c96c2ba2 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 2 May 2024 15:01:23 +0200 Subject: [PATCH 50/56] Improved handling of incomplete configs array --- internal/go-configmap/configuration.go | 2 +- internal/integrationtest/config/config_test.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/go-configmap/configuration.go b/internal/go-configmap/configuration.go index 5ea74eac983..ad0f41bdb1a 100644 --- a/internal/go-configmap/configuration.go +++ b/internal/go-configmap/configuration.go @@ -97,7 +97,7 @@ func tryConversion(current any, desiredType reflect.Type) (any, error) { } case reflect.Array, reflect.Slice: currentArray, ok := current.([]any) - if !ok { + if !ok && current != nil { break } for i, elem := range currentArray { diff --git a/internal/integrationtest/config/config_test.go b/internal/integrationtest/config/config_test.go index d180ea5699e..5ed5145dd62 100644 --- a/internal/integrationtest/config/config_test.go +++ b/internal/integrationtest/config/config_test.go @@ -893,4 +893,12 @@ build.unk: 123 out, _, err = cli.Run("config", "get", "locale", "--config-file", invalidConfig.String()) require.NoError(t, err) require.Equal(t, "en", strings.TrimSpace(string(out))) + + // Run "config get" with a configuration containing a null array + nullArrayConfig := paths.New(filepath.Join(tmp, "null_array.yaml")) + nullArrayConfig.WriteFile([]byte(`board_manager.additional_urls:`)) + t.Cleanup(func() { nullArrayConfig.Remove() }) + out, _, err = cli.Run("config", "get", "locale", "--config-file", invalidConfig.String()) + require.NoError(t, err) + require.Equal(t, "en", strings.TrimSpace(string(out))) } From a58c3506b83d27ea84eec6b41ecaed603d04eb36 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 6 May 2024 10:23:57 +0200 Subject: [PATCH 51/56] Disable logging until it is setup in the arduino-cli pre-run --- main.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.go b/main.go index 52499c7ae1d..5b2b095b215 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ package main import ( "context" "fmt" + "io" "os" "github.com/arduino/arduino-cli/commands" @@ -28,9 +29,13 @@ import ( "github.com/arduino/arduino-cli/internal/i18n" rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" + "github.com/sirupsen/logrus" ) func main() { + // Disable logging until it is setup in the arduino-cli pre-run + logrus.SetOutput(io.Discard) + // Create a new ArduinoCoreServer srv := commands.NewArduinoCoreServer() From 9585728ef6811f5bdc7b374088d7de9637f5bc57 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 6 May 2024 10:39:23 +0200 Subject: [PATCH 52/56] Show config-load warning after feedback package initialization --- main.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index 5b2b095b215..fa29df9c148 100644 --- a/main.go +++ b/main.go @@ -30,6 +30,7 @@ import ( rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1" "github.com/arduino/go-paths-helper" "github.com/sirupsen/logrus" + "github.com/spf13/cobra" ) func main() { @@ -45,6 +46,7 @@ func main() { // Read the settings from the configuration file openReq := &rpc.ConfigurationOpenRequest{SettingsFormat: "yaml"} + var configFileLoadingWarnings []string if configData, err := paths.New(configFile).ReadFile(); err == nil { openReq.EncodedSettings = string(configData) } else if !os.IsNotExist(err) { @@ -53,9 +55,8 @@ func main() { if resp, err := srv.ConfigurationOpen(ctx, openReq); err != nil { feedback.FatalError(fmt.Errorf("couldn't load configuration: %w", err), feedback.ErrGeneric) } else if warnings := resp.GetWarnings(); len(warnings) > 0 { - for _, warning := range warnings { - feedback.Warning(warning) - } + // Save the warnings to show them later when the feedback package is fully initialized + configFileLoadingWarnings = warnings } // Get the current settings from the server @@ -70,6 +71,15 @@ func main() { // Setup command line parser with the server and settings arduinoCmd := cli.NewCommand(srv) + parentPreRun := arduinoCmd.PersistentPreRun + arduinoCmd.PersistentPreRun = func(cmd *cobra.Command, args []string) { + if parentPreRun != nil { + parentPreRun(cmd, args) + } + for _, warning := range configFileLoadingWarnings { + feedback.Warning(warning) + } + } // Execute the command line if err := arduinoCmd.ExecuteContext(ctx); err != nil { From b279d4b3f5de34ddb053751ccfbc0c4ab246817a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 6 May 2024 12:13:03 +0200 Subject: [PATCH 53/56] Fixed 'feedback' package initialization order --- internal/cli/cli.go | 39 +++++++++----------- internal/integrationtest/board/board_test.go | 4 +- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/internal/cli/cli.go b/internal/cli/cli.go index e2ad85cc9e2..c2333c1827b 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -203,19 +203,22 @@ func toLogLevel(s string) (t logrus.Level, found bool) { } func preRun(verbose bool, outputFormat string, logLevel, logFile, logFormat string, noColor bool, settings *rpc.Configuration) { - // initialize inventory - err := inventory.Init(settings.GetDirectories().GetData()) - if err != nil { - feedback.Fatal(fmt.Sprintf("Error: %v", err), feedback.ErrInitializingInventory) - } - - // https://no-color.org/ - color.NoColor = noColor || os.Getenv("NO_COLOR") != "" + // + // Prepare the Feedback system + // // Set default feedback output to colorable + color.NoColor = noColor || os.Getenv("NO_COLOR") != "" // https://no-color.org/ feedback.SetOut(colorable.NewColorableStdout()) feedback.SetErr(colorable.NewColorableStderr()) + // use the output format to configure the Feedback + format, ok := feedback.ParseOutputFormat(outputFormat) + if !ok { + feedback.Fatal(tr("Invalid output format: %s", outputFormat), feedback.ErrBadArgument) + } + feedback.SetFormat(format) + // // Prepare logging // @@ -260,20 +263,14 @@ func preRun(verbose bool, outputFormat string, logLevel, logFile, logFormat stri logrus.SetLevel(logrusLevel) } - // - // Prepare the Feedback system - // - - // use the output format to configure the Feedback - format, ok := feedback.ParseOutputFormat(outputFormat) - if !ok { - feedback.Fatal(tr("Invalid output format: %s", outputFormat), feedback.ErrBadArgument) - } - feedback.SetFormat(format) + // Print some status info and check command is consistent + logrus.Info(versioninfo.VersionInfo.Application + " version " + versioninfo.VersionInfo.VersionString) // - // Print some status info and check command is consistent + // Initialize inventory // - - logrus.Info(versioninfo.VersionInfo.Application + " version " + versioninfo.VersionInfo.VersionString) + err := inventory.Init(settings.GetDirectories().GetData()) + if err != nil { + feedback.Fatal(fmt.Sprintf("Error: %v", err), feedback.ErrInitializingInventory) + } } diff --git a/internal/integrationtest/board/board_test.go b/internal/integrationtest/board/board_test.go index 639a27d3a7b..0541f1a5c0f 100644 --- a/internal/integrationtest/board/board_test.go +++ b/internal/integrationtest/board/board_test.go @@ -651,7 +651,7 @@ func TestCLIStartupWithCorruptedInventory(t *testing.T) { require.NoError(t, f.Close()) // the CLI should not be able to load inventory and report it to the logs - _, stderr, err := cli.Run("core", "update-index", "-v") + stdout, _, err := cli.Run("core", "update-index", "-v") require.NoError(t, err) - require.Contains(t, string(stderr), "Error loading inventory store") + require.Contains(t, string(stdout), "Error loading inventory store") } From 278a33147e07a6ddc274d8804120cb97dfc26968 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 6 May 2024 12:34:20 +0200 Subject: [PATCH 54/56] Applied changes from code review --- internal/go-configmap/cli.go | 10 ++++------ internal/go-configmap/configuration_test.go | 8 ++------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/internal/go-configmap/cli.go b/internal/go-configmap/cli.go index 3d4313a076e..d467cfc9c32 100644 --- a/internal/go-configmap/cli.go +++ b/internal/go-configmap/cli.go @@ -83,21 +83,19 @@ func (c *Map) InjectEnvVars(env []string, prefix string) []error { envKeyToConfigKey := map[string]string{} for _, k := range c.AllKeys() { normalizedKey := prefix + strings.ToUpper(k) - normalizedKey = strings.Replace(normalizedKey, ".", "_", -1) + normalizedKey = strings.ReplaceAll(normalizedKey, ".", "_") envKeyToConfigKey[normalizedKey] = k } for _, e := range env { // Extract key and value from env - parts := strings.SplitN(e, "=", 2) - if len(parts) != 2 { + envKey, envValue, ok := strings.Cut(e, "=") + if !ok { continue } - envKey := strings.ToUpper(parts[0]) - envValue := parts[1] // Check if the configuration has a matching key - key, ok := envKeyToConfigKey[envKey] + key, ok := envKeyToConfigKey[strings.ToUpper(envKey)] if !ok { continue } diff --git a/internal/go-configmap/configuration_test.go b/internal/go-configmap/configuration_test.go index 7c213d15a6c..a1e1a0fbf78 100644 --- a/internal/go-configmap/configuration_test.go +++ b/internal/go-configmap/configuration_test.go @@ -17,7 +17,6 @@ package configmap_test import ( "encoding/json" - "fmt" "testing" "github.com/arduino/arduino-cli/internal/go-configmap" @@ -36,7 +35,6 @@ func TestConfiguration(t *testing.T) { yml, err := yaml.Marshal(c) require.NoError(t, err) - fmt.Println(string(yml)) d := configmap.New() err = yaml.Unmarshal(yml, &d) @@ -109,13 +107,11 @@ func TestMerge(t *testing.T) { f := configmap.New() f.Set("fooz.bar", 10) - require.Error(t, c.Merge(f)) - fmt.Println(c.Merge(f)) + require.EqualError(t, c.Merge(f), "invalid types for key 'bar': got string but want int") g := configmap.New() g.Set("fooz.bart", "baz") - require.Error(t, c.Merge(g)) - fmt.Println(c.Merge(g)) + require.EqualError(t, c.Merge(g), "target key do not exist: 'bart'") } func TestAllKeys(t *testing.T) { From c355478ffd6e3760983638c302eeecb275b24e13 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 6 May 2024 15:41:11 +0200 Subject: [PATCH 55/56] Updated client_example --- commands/service_settings.go | 2 +- rpc/internal/client_example/main.go | 144 +++++++++++----------------- 2 files changed, 56 insertions(+), 90 deletions(-) diff --git a/commands/service_settings.go b/commands/service_settings.go index 2871844b8b8..d38f4a95cfd 100644 --- a/commands/service_settings.go +++ b/commands/service_settings.go @@ -177,7 +177,7 @@ func (s *arduinoCoreServerImpl) ConfigurationSave(ctx context.Context, req *rpc. } return &rpc.ConfigurationSaveResponse{EncodedSettings: string(data)}, nil case "json": - data, err := json.Marshal(s.settings) + data, err := json.MarshalIndent(s.settings, "", " ") if err != nil { return nil, fmt.Errorf("error marshalling settings: %v", err) } diff --git a/rpc/internal/client_example/main.go b/rpc/internal/client_example/main.go index eabf6bfd2d9..9fe750f36ea 100644 --- a/rpc/internal/client_example/main.go +++ b/rpc/internal/client_example/main.go @@ -23,6 +23,7 @@ import ( "io" "log" "os" + "path" "path/filepath" "strings" "time" @@ -71,40 +72,24 @@ func main() { callLoadSketch(client) // Use SetValue to configure the arduino-cli directories. - log.Println("calling SetValue") - callSetValue(client) + callSetValue(client, "directories.data", `"`+dataDir+`"`) + callSetValue(client, "directories.downloads", `"`+path.Join(dataDir, "staging")+`"`) + callSetValue(client, "directories.user", `"`+path.Join(dataDir, "sketchbook")+`"`) // List all settings - log.Println("calling SettingsGetAll()") - callGetAll(client) + callConfigurationSave(client) // Merge applies multiple settings values at once. - log.Println("calling SettingsMerge()") - callMerge(client, `{"foo": {"value": "bar"}, "daemon":{"port":"422"}, "board_manager": {"additional_urls":["https://example.com"]}}`) + callSetValue(client, "daemon.port", `"422"`) + callSetValue(client, "board_manager.additional_urls", `[ "https://example.com" ]`) - log.Println("calling SettingsGetAll()") - callGetAll(client) + callConfigurationSave(client) - log.Println("calling SettingsMerge()") - callMerge(client, `{"foo": {} }`) + callSetValue(client, "daemon.port", "") + callGetValue(client, "daemon.port") + callGetValue(client, "directories.data") - log.Println("calling SettingsGetAll()") - callGetAll(client) - - log.Println("calling SettingsMerge()") - callMerge(client, `{"foo": "bar" }`) - - // Get the value of the foo key. - log.Println("calling SettingsGetValue(foo)") - callGetValue(client) - - // List all settings - log.Println("calling SettingsGetAll()") - callGetAll(client) - - // Write settings to file. - log.Println("calling Write()") - callWrite(client) + callConfigurationSave(client) // Before we can do anything with the CLI, an "instance" must be created. // We keep a reference to the created instance because we will need it to @@ -243,85 +228,66 @@ func callVersion(client rpc.ArduinoCoreServiceClient) { log.Printf("arduino-cli version: %v", versionResp.GetVersion()) } -func callSetValue(client rpc.ArduinoCoreServiceClient) { - // _, err := client.SettingsSetValue(context.Background(), - // &rpc.SettingsSetValueRequest{ - // Key: "directories", - // JsonData: `{"data": "` + dataDir + `", "downloads": "` + path.Join(dataDir, "staging") + `", "user": "` + path.Join(dataDir, "sketchbook") + `"}`, - // }) +func callSetValue(client rpc.ArduinoCoreServiceClient, key, jsonValue string) { + log.Printf("Calling SetValue: %s = %s", key, jsonValue) + _, err := client.SettingsSetValue(context.Background(), + &rpc.SettingsSetValueRequest{ + Key: key, + EncodedValue: jsonValue, + }) - // if err != nil { - // log.Fatalf("Error setting settings value: %s", err) - // } + if err != nil { + log.Fatalf("Error setting settings value: %s", err) + } } func callSetProxy(client rpc.ArduinoCoreServiceClient) { - // _, err := client.SettingsSetValue(context.Background(), - // &rpc.SettingsSetValueRequest{ - // Key: "network.proxy", - // JsonData: `"http://localhost:3128"`, - // }) + _, err := client.SettingsSetValue(context.Background(), + &rpc.SettingsSetValueRequest{ + Key: "network.proxy", + EncodedValue: `"http://localhost:3128"`, + }) - // if err != nil { - // log.Fatalf("Error setting settings value: %s", err) - // } + if err != nil { + log.Fatalf("Error setting settings value: %s", err) + } } func callUnsetProxy(client rpc.ArduinoCoreServiceClient) { - // _, err := client.SettingsSetValue(context.Background(), - // &rpc.SettingsSetValueRequest{ - // Key: "network.proxy", - // JsonData: `""`, - // }) - - // if err != nil { - // log.Fatalf("Error setting settings value: %s", err) - // } -} - -func callMerge(client rpc.ArduinoCoreServiceClient, jsonData string) { - // _, err := client.SettingsMerge(context.Background(), - // &rpc.SettingsMergeRequest{ - // JsonData: jsonData, - // }) + _, err := client.SettingsSetValue(context.Background(), + &rpc.SettingsSetValueRequest{ + Key: "network.proxy", + }) - // if err != nil { - // log.Fatalf("Error merging settings: %s", err) - // } + if err != nil { + log.Fatalf("Error setting settings value: %s", err) + } } -func callGetValue(client rpc.ArduinoCoreServiceClient) { - // getValueResp, err := client.SettingsGetValue(context.Background(), - // &rpc.SettingsGetValueRequest{ - // Key: "foo", - // }) +func callGetValue(client rpc.ArduinoCoreServiceClient, key string) { + getValueResp, err := client.SettingsGetValue(context.Background(), + &rpc.SettingsGetValueRequest{ + Key: key, + }) - // if err != nil { - // log.Fatalf("Error getting settings value: %s", err) - // } + if err != nil { + log.Fatalf("Error getting settings value: %s", err) + } - // log.Printf("Value: %s: %s", getValueResp.GetKey(), getValueResp.GetJsonData()) + log.Printf("%s = %s", key, getValueResp.GetEncodedValue()) } -func callGetAll(client rpc.ArduinoCoreServiceClient) { - // getAllResp, err := client.SettingsGetAll(context.Background(), &rpc.SettingsGetAllRequest{}) - - // if err != nil { - // log.Fatalf("Error getting settings: %s", err) - // } - - // log.Printf("Settings: %s", getAllResp.GetJsonData()) -} +func callConfigurationSave(client rpc.ArduinoCoreServiceClient) { + log.Println("calling ConfigurationSave() >>") + getAllResp, err := client.ConfigurationSave(context.Background(), &rpc.ConfigurationSaveRequest{ + SettingsFormat: "json", + }) -func callWrite(client rpc.ArduinoCoreServiceClient) { - // _, err := client.SettingsWrite(context.Background(), - // &rpc.SettingsWriteRequest{ - // FilePath: path.Join(dataDir, "written-rpc.Settingsyml"), - // }) + if err != nil { + log.Fatalf("Error getting settings: %s", err) + } - // if err != nil { - // log.Fatalf("Error writing settings: %s", err) - // } + log.Printf("Settings follow:\n\n%s", getAllResp.GetEncodedSettings()) } func createInstance(client rpc.ArduinoCoreServiceClient) *rpc.Instance { From cec1fdb86bbd130c2bb926cce6d61bf87687a707 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 6 May 2024 17:14:53 +0200 Subject: [PATCH 56/56] Improved array handling in configmap, and unit-tests --- internal/go-configmap/configuration.go | 6 +- internal/go-configmap/configuration_test.go | 70 ++++++++++++++++++--- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/internal/go-configmap/configuration.go b/internal/go-configmap/configuration.go index ad0f41bdb1a..e1a9dbb791e 100644 --- a/internal/go-configmap/configuration.go +++ b/internal/go-configmap/configuration.go @@ -100,14 +100,16 @@ func tryConversion(current any, desiredType reflect.Type) (any, error) { if !ok && current != nil { break } + + resArray := reflect.MakeSlice(desiredType, len(currentArray), len(currentArray)) for i, elem := range currentArray { newElem, err := tryConversion(elem, desiredType.Elem()) if err != nil { return nil, err } - currentArray[i] = newElem + resArray.Index(i).Set(reflect.ValueOf(newElem)) } - return currentArray, nil + return resArray.Interface(), nil } currentTypeString := currentType.String() diff --git a/internal/go-configmap/configuration_test.go b/internal/go-configmap/configuration_test.go index a1e1a0fbf78..c9c025cb3ce 100644 --- a/internal/go-configmap/configuration_test.go +++ b/internal/go-configmap/configuration_test.go @@ -146,19 +146,73 @@ func TestSchema(t *testing.T) { c.SetKeyTypeSchema("int", 15) c.SetKeyTypeSchema("obj.string", "") c.SetKeyTypeSchema("obj.int", 15) + c.SetKeyTypeSchema("uint", uint(15)) + c.SetKeyTypeSchema("obj.uint", uint(15)) + c.SetKeyTypeSchema("array", []string{}) + c.SetKeyTypeSchema("obj.array", []string{}) + + // Set array of string + require.NoError(t, c.Set("array", []string{"abc", "def"})) + require.NoError(t, c.Set("obj.array", []string{"abc", "def"})) + require.Equal(t, []string{"abc", "def"}, c.Get("array")) + require.Equal(t, []string{"abc", "def"}, c.Get("obj.array")) + // Set array of string with array of any + require.NoError(t, c.Set("array", []any{"abc", "def"})) + require.NoError(t, c.Set("obj.array", []any{"abc", "def"})) + require.Equal(t, []string{"abc", "def"}, c.Get("array")) + require.Equal(t, []string{"abc", "def"}, c.Get("obj.array")) + // Set array of string with array of int + require.EqualError(t, c.Set("array", []any{"abc", 123}), "invalid type for key 'array': invalid conversion, got int but want string") + require.EqualError(t, c.Set("obj.array", []any{"abc", 123}), "invalid type for key 'obj.array': invalid conversion, got int but want string") + + // Set string require.NoError(t, c.Set("string", "abc")) - require.Error(t, c.Set("string", 123)) - require.NoError(t, c.Set("int", 123)) - require.Error(t, c.Set("int", "abc")) + require.NoError(t, c.Set("obj.string", "abc")) require.Equal(t, "abc", c.Get("string")) + require.Equal(t, "abc", c.Get("obj.string")) + // Set string with int + require.EqualError(t, c.Set("string", 123), "invalid type for key 'string': invalid conversion, got int but want string") + require.EqualError(t, c.Set("obj.string", 123), "invalid type for key 'obj.string': invalid conversion, got int but want string") - json1 := []byte(`{"string":"abc","int":123,"obj":{"string":"abc","int":123}}`) - require.NoError(t, json.Unmarshal(json1, &c)) - require.Equal(t, "abc", c.Get("string")) + // Set int + require.NoError(t, c.Set("int", 123)) + require.NoError(t, c.Set("obj.int", 123)) require.Equal(t, 123, c.Get("int")) + require.Equal(t, 123, c.Get("obj.int")) + // Set int with string + require.EqualError(t, c.Set("int", "abc"), "invalid type for key 'int': invalid conversion, got string but want int") + require.EqualError(t, c.Set("obj.int", "abc"), "invalid type for key 'obj.int': invalid conversion, got string but want int") + + // Set uint + require.NoError(t, c.Set("uint", uint(234))) + require.NoError(t, c.Set("obj.uint", uint(234))) + require.Equal(t, uint(234), c.Get("uint")) + require.Equal(t, uint(234), c.Get("obj.uint")) + // Set uint using int + require.NoError(t, c.Set("uint", 345)) + require.NoError(t, c.Set("obj.uint", 345)) + require.Equal(t, uint(345), c.Get("uint")) + require.Equal(t, uint(345), c.Get("obj.uint")) + // Set uint using float + require.NoError(t, c.Set("uint", 456.0)) + require.NoError(t, c.Set("obj.uint", 456.0)) + require.Equal(t, uint(456), c.Get("uint")) + require.Equal(t, uint(456), c.Get("obj.uint")) + // Set uint using string + require.EqualError(t, c.Set("uint", "567"), "invalid type for key 'uint': invalid conversion, got string but want uint") + require.EqualError(t, c.Set("obj.uint", "567"), "invalid type for key 'obj.uint': invalid conversion, got string but want uint") + require.Equal(t, uint(456), c.Get("uint")) + require.Equal(t, uint(456), c.Get("obj.uint")) + + json1 := []byte(`{"string":"abcd","int":1234,"obj":{"string":"abcd","int":1234}}`) + require.NoError(t, json.Unmarshal(json1, &c)) + require.Equal(t, "abcd", c.Get("string")) + require.Equal(t, 1234, c.Get("int")) + require.Equal(t, "abcd", c.Get("obj.string")) + require.Equal(t, 1234, c.Get("obj.int")) json2 := []byte(`{"string":123,"int":123,"obj":{"string":"abc","int":123}}`) - require.Error(t, json.Unmarshal(json2, &c)) + require.EqualError(t, json.Unmarshal(json2, &c), "invalid type for key 'string': invalid conversion, got float64 but want string") json3 := []byte(`{"string":"avc","int":123,"obj":{"string":123,"int":123}}`) - require.Error(t, json.Unmarshal(json3, &c)) + require.EqualError(t, json.Unmarshal(json3, &c), "invalid type for key 'obj.string': invalid conversion, got float64 but want string") }