From f1a648137d8c0114dad2ac64efedff92fc222502 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Fri, 26 Feb 2021 14:26:53 +0100 Subject: [PATCH 1/2] Add board's platform to board listall json output --- commands/board/listall.go | 27 +++- rpc/commands/board.pb.go | 41 ++++-- rpc/commands/board.proto | 2 + rpc/commands/common.pb.go | 255 +++++++++++++++++++++++++++++++-- rpc/commands/common.proto | 34 +++++ rpc/commands/core.pb.go | 288 ++++---------------------------------- rpc/commands/core.proto | 34 ----- test/test_board.py | 85 ++++++----- 8 files changed, 413 insertions(+), 353 deletions(-) diff --git a/commands/board/listall.go b/commands/board/listall.go index 082e29fdc88..cb8baa15b36 100644 --- a/commands/board/listall.go +++ b/commands/board/listall.go @@ -48,11 +48,31 @@ func ListAll(ctx context.Context, req *rpc.BoardListAllReq) (*rpc.BoardListAllRe list := &rpc.BoardListAllResp{Boards: []*rpc.BoardListItem{}} for _, targetPackage := range pm.Packages { for _, platform := range targetPackage.Platforms { - platformRelease := pm.GetInstalledPlatformRelease(platform) - if platformRelease == nil { + installedPlatformRelease := pm.GetInstalledPlatformRelease(platform) + // We only want to list boards for installed platforms + if installedPlatformRelease == nil { continue } - for _, board := range platformRelease.Boards { + + installedVersion := installedPlatformRelease.Version.String() + + latestVersion := "" + if latestPlatformRelease := platform.GetLatestRelease(); latestPlatformRelease != nil { + latestVersion = latestPlatformRelease.Version.String() + } + + rpcPlatform := &rpc.Platform{ + ID: platform.String(), + Installed: installedVersion, + Latest: latestVersion, + Name: platform.Name, + Maintainer: platform.Package.Maintainer, + Website: platform.Package.WebsiteURL, + Email: platform.Package.Email, + ManuallyInstalled: platform.ManuallyInstalled, + } + + for _, board := range installedPlatformRelease.Boards { if !match(board.Name()) { continue } @@ -63,6 +83,7 @@ func ListAll(ctx context.Context, req *rpc.BoardListAllReq) (*rpc.BoardListAllRe Name: board.Name(), FQBN: board.FQBN(), IsHidden: board.IsHidden(), + Platform: rpcPlatform, }) } } diff --git a/rpc/commands/board.pb.go b/rpc/commands/board.pb.go index 6e297db8645..45372169c1d 100644 --- a/rpc/commands/board.pb.go +++ b/rpc/commands/board.pb.go @@ -1452,6 +1452,8 @@ type BoardListItem struct { VID string `protobuf:"bytes,4,opt,name=VID,proto3" json:"VID,omitempty"` // Product ID PID string `protobuf:"bytes,5,opt,name=PID,proto3" json:"PID,omitempty"` + // Platform this board belongs to + Platform *Platform `protobuf:"bytes,6,opt,name=platform,proto3" json:"platform,omitempty"` } func (x *BoardListItem) Reset() { @@ -1521,6 +1523,13 @@ func (x *BoardListItem) GetPID() string { return "" } +func (x *BoardListItem) GetPlatform() *Platform { + if x != nil { + return x.Platform + } + return nil +} + var File_commands_board_proto protoreflect.FileDescriptor var file_commands_board_proto_rawDesc = []byte{ @@ -1716,14 +1725,18 @@ var file_commands_board_proto_rawDesc = []byte{ 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 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, - 0x78, 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, 0x46, 0x51, 0x42, 0x4e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x46, 0x51, 0x42, 0x4e, 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, 0x10, 0x0a, 0x03, 0x56, 0x49, 0x44, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x56, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x50, 0x49, 0x44, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x50, 0x49, 0x44, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, + 0xb7, 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, 0x46, 0x51, 0x42, 0x4e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x46, 0x51, 0x42, 0x4e, 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, 0x10, 0x0a, 0x03, 0x56, 0x49, 0x44, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x56, 0x49, 0x44, 0x12, 0x10, 0x0a, 0x03, 0x50, 0x49, 0x44, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x50, 0x49, 0x44, 0x12, 0x3d, 0x0a, 0x08, 0x70, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 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, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, + 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x42, 0x2d, 0x5a, 0x2b, 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, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, @@ -1767,6 +1780,7 @@ var file_commands_board_proto_goTypes = []interface{}{ (*Instance)(nil), // 21: cc.arduino.cli.commands.Instance (*Programmer)(nil), // 22: cc.arduino.cli.commands.Programmer (*TaskProgress)(nil), // 23: cc.arduino.cli.commands.TaskProgress + (*Platform)(nil), // 24: cc.arduino.cli.commands.Platform } var file_commands_board_proto_depIdxs = []int32{ 21, // 0: cc.arduino.cli.commands.BoardDetailsReq.instance:type_name -> cc.arduino.cli.commands.Instance @@ -1789,11 +1803,12 @@ var file_commands_board_proto_depIdxs = []int32{ 20, // 17: cc.arduino.cli.commands.BoardListAllResp.boards:type_name -> cc.arduino.cli.commands.BoardListItem 21, // 18: cc.arduino.cli.commands.BoardListWatchReq.instance:type_name -> cc.arduino.cli.commands.Instance 15, // 19: cc.arduino.cli.commands.BoardListWatchResp.port:type_name -> cc.arduino.cli.commands.DetectedPort - 20, // [20:20] is the sub-list for method output_type - 20, // [20:20] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name + 24, // 20: cc.arduino.cli.commands.BoardListItem.platform:type_name -> cc.arduino.cli.commands.Platform + 21, // [21:21] is the sub-list for method output_type + 21, // [21:21] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name } func init() { file_commands_board_proto_init() } diff --git a/rpc/commands/board.proto b/rpc/commands/board.proto index 6b45b25d34e..adc9d977367 100644 --- a/rpc/commands/board.proto +++ b/rpc/commands/board.proto @@ -235,4 +235,6 @@ message BoardListItem { string VID = 4; // Product ID string PID = 5; + // Platform this board belongs to + Platform platform = 6; } diff --git a/rpc/commands/common.pb.go b/rpc/commands/common.pb.go index 6d6629fa077..1b721c2eca2 100644 --- a/rpc/commands/common.pb.go +++ b/rpc/commands/common.pb.go @@ -301,6 +301,189 @@ func (x *Programmer) GetName() string { return "" } +type Platform struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Platform ID (e.g., `arduino:avr`). + ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` + // Version of the platform. + Installed string `protobuf:"bytes,2,opt,name=Installed,proto3" json:"Installed,omitempty"` + // Newest available version of the platform. + Latest string `protobuf:"bytes,3,opt,name=Latest,proto3" json:"Latest,omitempty"` + // Name used to identify the platform to humans (e.g., "Arduino AVR Boards"). + Name string `protobuf:"bytes,4,opt,name=Name,proto3" json:"Name,omitempty"` + // Maintainer of the platform's package. + Maintainer string `protobuf:"bytes,5,opt,name=Maintainer,proto3" json:"Maintainer,omitempty"` + // A URL provided by the author of the platform's package, intended to point + // to their website. + Website string `protobuf:"bytes,6,opt,name=Website,proto3" json:"Website,omitempty"` + // Email of the maintainer of the platform's package. + Email string `protobuf:"bytes,7,opt,name=Email,proto3" json:"Email,omitempty"` + // List of boards provided by the platform. If the platform is installed, + // this is the boards listed in the platform's boards.txt. If the platform is + // not installed, this is an arbitrary list of board names provided by the + // platform author for display and may not match boards.txt. + Boards []*Board `protobuf:"bytes,8,rep,name=Boards,proto3" json:"Boards,omitempty"` + // If true this Platform has been installed manually in the user' sketchbook + // hardware folder + ManuallyInstalled bool `protobuf:"varint,9,opt,name=ManuallyInstalled,proto3" json:"ManuallyInstalled,omitempty"` +} + +func (x *Platform) Reset() { + *x = Platform{} + if protoimpl.UnsafeEnabled { + mi := &file_commands_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Platform) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Platform) ProtoMessage() {} + +func (x *Platform) ProtoReflect() protoreflect.Message { + mi := &file_commands_common_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 Platform.ProtoReflect.Descriptor instead. +func (*Platform) Descriptor() ([]byte, []int) { + return file_commands_common_proto_rawDescGZIP(), []int{4} +} + +func (x *Platform) GetID() string { + if x != nil { + return x.ID + } + return "" +} + +func (x *Platform) GetInstalled() string { + if x != nil { + return x.Installed + } + return "" +} + +func (x *Platform) GetLatest() string { + if x != nil { + return x.Latest + } + return "" +} + +func (x *Platform) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Platform) GetMaintainer() string { + if x != nil { + return x.Maintainer + } + return "" +} + +func (x *Platform) GetWebsite() string { + if x != nil { + return x.Website + } + return "" +} + +func (x *Platform) GetEmail() string { + if x != nil { + return x.Email + } + return "" +} + +func (x *Platform) GetBoards() []*Board { + if x != nil { + return x.Boards + } + return nil +} + +func (x *Platform) GetManuallyInstalled() bool { + if x != nil { + return x.ManuallyInstalled + } + return false +} + +type Board struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name used to identify the board to humans. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Fully qualified board name used to identify the board to machines. The FQBN + // is only available for installed boards. + Fqbn string `protobuf:"bytes,2,opt,name=fqbn,proto3" json:"fqbn,omitempty"` +} + +func (x *Board) Reset() { + *x = Board{} + if protoimpl.UnsafeEnabled { + mi := &file_commands_common_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Board) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Board) ProtoMessage() {} + +func (x *Board) ProtoReflect() protoreflect.Message { + mi := &file_commands_common_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 Board.ProtoReflect.Descriptor instead. +func (*Board) Descriptor() ([]byte, []int) { + return file_commands_common_proto_rawDescGZIP(), []int{5} +} + +func (x *Board) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Board) GetFqbn() string { + if x != nil { + return x.Fqbn + } + return "" +} + var File_commands_common_proto protoreflect.FileDescriptor var file_commands_common_proto_rawDesc = []byte{ @@ -328,11 +511,32 @@ var file_commands_common_proto_rawDesc = []byte{ 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x2d, - 0x5a, 0x2b, 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, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x9a, + 0x02, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x49, + 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x61, 0x74, + 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4c, 0x61, 0x74, 0x65, 0x73, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x61, 0x69, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x36, 0x0a, 0x06, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, + 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 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, + 0x42, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x06, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x12, 0x2c, 0x0a, + 0x11, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, + 0x6c, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x22, 0x2f, 0x0a, 0x05, 0x42, + 0x6f, 0x61, 0x72, 0x64, 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, 0x42, 0x2d, 0x5a, 0x2b, + 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, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -347,19 +551,22 @@ func file_commands_common_proto_rawDescGZIP() []byte { return file_commands_common_proto_rawDescData } -var file_commands_common_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_commands_common_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_commands_common_proto_goTypes = []interface{}{ (*Instance)(nil), // 0: cc.arduino.cli.commands.Instance (*DownloadProgress)(nil), // 1: cc.arduino.cli.commands.DownloadProgress (*TaskProgress)(nil), // 2: cc.arduino.cli.commands.TaskProgress (*Programmer)(nil), // 3: cc.arduino.cli.commands.Programmer + (*Platform)(nil), // 4: cc.arduino.cli.commands.Platform + (*Board)(nil), // 5: cc.arduino.cli.commands.Board } var file_commands_common_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 + 5, // 0: cc.arduino.cli.commands.Platform.Boards:type_name -> cc.arduino.cli.commands.Board + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_commands_common_proto_init() } @@ -416,6 +623,30 @@ func file_commands_common_proto_init() { return nil } } + file_commands_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Platform); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_commands_common_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Board); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -423,7 +654,7 @@ func file_commands_common_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_commands_common_proto_rawDesc, NumEnums: 0, - NumMessages: 4, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/commands/common.proto b/rpc/commands/common.proto index c49000214d6..fc31624529a 100644 --- a/rpc/commands/common.proto +++ b/rpc/commands/common.proto @@ -51,3 +51,37 @@ message Programmer { string id = 2; string name = 3; } + +message Platform { + // Platform ID (e.g., `arduino:avr`). + string ID = 1; + // Version of the platform. + string Installed = 2; + // Newest available version of the platform. + string Latest = 3; + // Name used to identify the platform to humans (e.g., "Arduino AVR Boards"). + string Name = 4; + // Maintainer of the platform's package. + string Maintainer = 5; + // A URL provided by the author of the platform's package, intended to point + // to their website. + string Website = 6; + // Email of the maintainer of the platform's package. + string Email = 7; + // List of boards provided by the platform. If the platform is installed, + // this is the boards listed in the platform's boards.txt. If the platform is + // not installed, this is an arbitrary list of board names provided by the + // platform author for display and may not match boards.txt. + repeated Board Boards = 8; + // If true this Platform has been installed manually in the user' sketchbook + // hardware folder + bool ManuallyInstalled = 9; +} + +message Board { + // Name used to identify the board to humans. + string name = 1; + // Fully qualified board name used to identify the board to machines. The FQBN + // is only available for installed boards. + string fqbn = 2; +} \ No newline at end of file diff --git a/rpc/commands/core.pb.go b/rpc/commands/core.pb.go index 2c26ab04f2e..743e2cf01c1 100644 --- a/rpc/commands/core.pb.go +++ b/rpc/commands/core.pb.go @@ -781,189 +781,6 @@ func (x *PlatformListResp) GetInstalledPlatform() []*Platform { return nil } -type Platform struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Platform ID (e.g., `arduino:avr`). - ID string `protobuf:"bytes,1,opt,name=ID,proto3" json:"ID,omitempty"` - // Version of the platform. - Installed string `protobuf:"bytes,2,opt,name=Installed,proto3" json:"Installed,omitempty"` - // Newest available version of the platform. - Latest string `protobuf:"bytes,3,opt,name=Latest,proto3" json:"Latest,omitempty"` - // Name used to identify the platform to humans (e.g., "Arduino AVR Boards"). - Name string `protobuf:"bytes,4,opt,name=Name,proto3" json:"Name,omitempty"` - // Maintainer of the platform's package. - Maintainer string `protobuf:"bytes,5,opt,name=Maintainer,proto3" json:"Maintainer,omitempty"` - // A URL provided by the author of the platform's package, intended to point - // to their website. - Website string `protobuf:"bytes,6,opt,name=Website,proto3" json:"Website,omitempty"` - // Email of the maintainer of the platform's package. - Email string `protobuf:"bytes,7,opt,name=Email,proto3" json:"Email,omitempty"` - // List of boards provided by the platform. If the platform is installed, - // this is the boards listed in the platform's boards.txt. If the platform is - // not installed, this is an arbitrary list of board names provided by the - // platform author for display and may not match boards.txt. - Boards []*Board `protobuf:"bytes,8,rep,name=Boards,proto3" json:"Boards,omitempty"` - // If true this Platform has been installed manually in the user' sketchbook - // hardware folder - ManuallyInstalled bool `protobuf:"varint,9,opt,name=ManuallyInstalled,proto3" json:"ManuallyInstalled,omitempty"` -} - -func (x *Platform) Reset() { - *x = Platform{} - if protoimpl.UnsafeEnabled { - mi := &file_commands_core_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Platform) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Platform) ProtoMessage() {} - -func (x *Platform) ProtoReflect() protoreflect.Message { - mi := &file_commands_core_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 Platform.ProtoReflect.Descriptor instead. -func (*Platform) Descriptor() ([]byte, []int) { - return file_commands_core_proto_rawDescGZIP(), []int{12} -} - -func (x *Platform) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *Platform) GetInstalled() string { - if x != nil { - return x.Installed - } - return "" -} - -func (x *Platform) GetLatest() string { - if x != nil { - return x.Latest - } - return "" -} - -func (x *Platform) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Platform) GetMaintainer() string { - if x != nil { - return x.Maintainer - } - return "" -} - -func (x *Platform) GetWebsite() string { - if x != nil { - return x.Website - } - return "" -} - -func (x *Platform) GetEmail() string { - if x != nil { - return x.Email - } - return "" -} - -func (x *Platform) GetBoards() []*Board { - if x != nil { - return x.Boards - } - return nil -} - -func (x *Platform) GetManuallyInstalled() bool { - if x != nil { - return x.ManuallyInstalled - } - return false -} - -type Board struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Name used to identify the board to humans. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Fully qualified board name used to identify the board to machines. The FQBN - // is only available for installed boards. - Fqbn string `protobuf:"bytes,2,opt,name=fqbn,proto3" json:"fqbn,omitempty"` -} - -func (x *Board) Reset() { - *x = Board{} - if protoimpl.UnsafeEnabled { - mi := &file_commands_core_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Board) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Board) ProtoMessage() {} - -func (x *Board) ProtoReflect() protoreflect.Message { - mi := &file_commands_core_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 Board.ProtoReflect.Descriptor instead. -func (*Board) Descriptor() ([]byte, []int) { - return file_commands_core_proto_rawDescGZIP(), []int{13} -} - -func (x *Board) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Board) GetFqbn() string { - if x != nil { - return x.Fqbn - } - return "" -} - var File_commands_core_proto protoreflect.FileDescriptor var file_commands_core_proto_rawDesc = []byte{ @@ -1085,31 +902,10 @@ var file_commands_core_proto_rawDesc = []byte{ 0x0b, 0x32, 0x21, 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, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x52, 0x11, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x50, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x9a, 0x02, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x49, 0x44, 0x12, 0x1c, 0x0a, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, - 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, - 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, - 0x0a, 0x0a, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x4d, 0x61, 0x69, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x18, - 0x0a, 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x45, 0x6d, 0x61, 0x69, - 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x36, - 0x0a, 0x06, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, - 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, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x52, 0x06, - 0x42, 0x6f, 0x61, 0x72, 0x64, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, - 0x6c, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x11, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x6c, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6c, 0x6c, 0x65, 0x64, 0x22, 0x2f, 0x0a, 0x05, 0x42, 0x6f, 0x61, 0x72, 0x64, 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, 0x42, 0x2d, 0x5a, 0x2b, 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, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x42, 0x2d, 0x5a, 0x2b, 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, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1124,7 +920,7 @@ func file_commands_core_proto_rawDescGZIP() []byte { return file_commands_core_proto_rawDescData } -var file_commands_core_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_commands_core_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_commands_core_proto_goTypes = []interface{}{ (*PlatformInstallReq)(nil), // 0: cc.arduino.cli.commands.PlatformInstallReq (*PlatformInstallResp)(nil), // 1: cc.arduino.cli.commands.PlatformInstallResp @@ -1138,33 +934,31 @@ var file_commands_core_proto_goTypes = []interface{}{ (*PlatformSearchResp)(nil), // 9: cc.arduino.cli.commands.PlatformSearchResp (*PlatformListReq)(nil), // 10: cc.arduino.cli.commands.PlatformListReq (*PlatformListResp)(nil), // 11: cc.arduino.cli.commands.PlatformListResp - (*Platform)(nil), // 12: cc.arduino.cli.commands.Platform - (*Board)(nil), // 13: cc.arduino.cli.commands.Board - (*Instance)(nil), // 14: cc.arduino.cli.commands.Instance - (*DownloadProgress)(nil), // 15: cc.arduino.cli.commands.DownloadProgress - (*TaskProgress)(nil), // 16: cc.arduino.cli.commands.TaskProgress + (*Instance)(nil), // 12: cc.arduino.cli.commands.Instance + (*DownloadProgress)(nil), // 13: cc.arduino.cli.commands.DownloadProgress + (*TaskProgress)(nil), // 14: cc.arduino.cli.commands.TaskProgress + (*Platform)(nil), // 15: cc.arduino.cli.commands.Platform } var file_commands_core_proto_depIdxs = []int32{ - 14, // 0: cc.arduino.cli.commands.PlatformInstallReq.instance:type_name -> cc.arduino.cli.commands.Instance - 15, // 1: cc.arduino.cli.commands.PlatformInstallResp.progress:type_name -> cc.arduino.cli.commands.DownloadProgress - 16, // 2: cc.arduino.cli.commands.PlatformInstallResp.task_progress:type_name -> cc.arduino.cli.commands.TaskProgress - 14, // 3: cc.arduino.cli.commands.PlatformDownloadReq.instance:type_name -> cc.arduino.cli.commands.Instance - 15, // 4: cc.arduino.cli.commands.PlatformDownloadResp.progress:type_name -> cc.arduino.cli.commands.DownloadProgress - 14, // 5: cc.arduino.cli.commands.PlatformUninstallReq.instance:type_name -> cc.arduino.cli.commands.Instance - 16, // 6: cc.arduino.cli.commands.PlatformUninstallResp.task_progress:type_name -> cc.arduino.cli.commands.TaskProgress - 14, // 7: cc.arduino.cli.commands.PlatformUpgradeReq.instance:type_name -> cc.arduino.cli.commands.Instance - 15, // 8: cc.arduino.cli.commands.PlatformUpgradeResp.progress:type_name -> cc.arduino.cli.commands.DownloadProgress - 16, // 9: cc.arduino.cli.commands.PlatformUpgradeResp.task_progress:type_name -> cc.arduino.cli.commands.TaskProgress - 14, // 10: cc.arduino.cli.commands.PlatformSearchReq.instance:type_name -> cc.arduino.cli.commands.Instance - 12, // 11: cc.arduino.cli.commands.PlatformSearchResp.search_output:type_name -> cc.arduino.cli.commands.Platform - 14, // 12: cc.arduino.cli.commands.PlatformListReq.instance:type_name -> cc.arduino.cli.commands.Instance - 12, // 13: cc.arduino.cli.commands.PlatformListResp.installed_platform:type_name -> cc.arduino.cli.commands.Platform - 13, // 14: cc.arduino.cli.commands.Platform.Boards:type_name -> cc.arduino.cli.commands.Board - 15, // [15:15] is the sub-list for method output_type - 15, // [15:15] is the sub-list for method input_type - 15, // [15:15] is the sub-list for extension type_name - 15, // [15:15] is the sub-list for extension extendee - 0, // [0:15] is the sub-list for field type_name + 12, // 0: cc.arduino.cli.commands.PlatformInstallReq.instance:type_name -> cc.arduino.cli.commands.Instance + 13, // 1: cc.arduino.cli.commands.PlatformInstallResp.progress:type_name -> cc.arduino.cli.commands.DownloadProgress + 14, // 2: cc.arduino.cli.commands.PlatformInstallResp.task_progress:type_name -> cc.arduino.cli.commands.TaskProgress + 12, // 3: cc.arduino.cli.commands.PlatformDownloadReq.instance:type_name -> cc.arduino.cli.commands.Instance + 13, // 4: cc.arduino.cli.commands.PlatformDownloadResp.progress:type_name -> cc.arduino.cli.commands.DownloadProgress + 12, // 5: cc.arduino.cli.commands.PlatformUninstallReq.instance:type_name -> cc.arduino.cli.commands.Instance + 14, // 6: cc.arduino.cli.commands.PlatformUninstallResp.task_progress:type_name -> cc.arduino.cli.commands.TaskProgress + 12, // 7: cc.arduino.cli.commands.PlatformUpgradeReq.instance:type_name -> cc.arduino.cli.commands.Instance + 13, // 8: cc.arduino.cli.commands.PlatformUpgradeResp.progress:type_name -> cc.arduino.cli.commands.DownloadProgress + 14, // 9: cc.arduino.cli.commands.PlatformUpgradeResp.task_progress:type_name -> cc.arduino.cli.commands.TaskProgress + 12, // 10: cc.arduino.cli.commands.PlatformSearchReq.instance:type_name -> cc.arduino.cli.commands.Instance + 15, // 11: cc.arduino.cli.commands.PlatformSearchResp.search_output:type_name -> cc.arduino.cli.commands.Platform + 12, // 12: cc.arduino.cli.commands.PlatformListReq.instance:type_name -> cc.arduino.cli.commands.Instance + 15, // 13: cc.arduino.cli.commands.PlatformListResp.installed_platform:type_name -> cc.arduino.cli.commands.Platform + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_commands_core_proto_init() } @@ -1318,30 +1112,6 @@ func file_commands_core_proto_init() { return nil } } - file_commands_core_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Platform); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_commands_core_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Board); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1349,7 +1119,7 @@ func file_commands_core_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_commands_core_proto_rawDesc, NumEnums: 0, - NumMessages: 14, + NumMessages: 12, NumExtensions: 0, NumServices: 0, }, diff --git a/rpc/commands/core.proto b/rpc/commands/core.proto index 92259368d09..89032875927 100644 --- a/rpc/commands/core.proto +++ b/rpc/commands/core.proto @@ -119,37 +119,3 @@ message PlatformListResp { // The installed platforms. repeated Platform installed_platform = 1; } - -message Platform { - // Platform ID (e.g., `arduino:avr`). - string ID = 1; - // Version of the platform. - string Installed = 2; - // Newest available version of the platform. - string Latest = 3; - // Name used to identify the platform to humans (e.g., "Arduino AVR Boards"). - string Name = 4; - // Maintainer of the platform's package. - string Maintainer = 5; - // A URL provided by the author of the platform's package, intended to point - // to their website. - string Website = 6; - // Email of the maintainer of the platform's package. - string Email = 7; - // List of boards provided by the platform. If the platform is installed, - // this is the boards listed in the platform's boards.txt. If the platform is - // not installed, this is an arbitrary list of board names provided by the - // platform author for display and may not match boards.txt. - repeated Board Boards = 8; - // If true this Platform has been installed manually in the user' sketchbook - // hardware folder - bool ManuallyInstalled = 9; -} - -message Board { - // Name used to identify the board to humans. - string name = 1; - // Fully qualified board name used to identify the board to machines. The FQBN - // is only available for installed boards. - string fqbn = 2; -} \ No newline at end of file diff --git a/test/test_board.py b/test/test_board.py index 0dbc34c427f..4a39fc08c6d 100644 --- a/test/test_board.py +++ b/test/test_board.py @@ -12,6 +12,8 @@ # 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. +from pathlib import Path +from git import Repo import simplejson as json @@ -399,39 +401,58 @@ def test_board_list(run_command): def test_board_listall(run_command): - run_command("core update-index") - run_command("core install arduino:avr@1.8.3") - res = run_command("board listall") + assert run_command("update") + assert run_command("core install arduino:avr@1.8.3") + res = run_command("board listall --format json") + assert res.ok + data = json.loads(res.stdout) + boards = {b["FQBN"]: b for b in data["boards"]} + assert len(boards) == 26 + assert "arduino:avr:yun" in boards + assert "Arduino Yún" == boards["arduino:avr:yun"]["name"] + platform = boards["arduino:avr:yun"]["platform"] + assert "arduino:avr" == platform["ID"] + assert "1.8.3" == platform["Installed"] + assert "" != platform["Latest"] + assert "Arduino AVR Boards" == platform["Name"] + + assert "arduino:avr:uno" in boards + assert "Arduino Uno" == boards["arduino:avr:uno"]["name"] + platform = boards["arduino:avr:uno"]["platform"] + assert "arduino:avr" == platform["ID"] + assert "1.8.3" == platform["Installed"] + assert "" != platform["Latest"] + assert "Arduino AVR Boards" == platform["Name"] + + +def test_board_listall_with_manually_installed_platform(run_command, data_dir): + assert run_command("update") + + # Manually installs a core in sketchbooks hardware folder + git_url = "https://github.com/arduino/ArduinoCore-samd.git" + repo_dir = Path(data_dir, "hardware", "arduino-beta-development", "samd") + assert Repo.clone_from(git_url, repo_dir, multi_options=["-b 1.8.11"]) + + res = run_command("board listall --format json") assert res.ok - lines = [l.rsplit(maxsplit=1) for l in res.stdout.strip().splitlines()] - assert len(lines) == 27 - assert ["Board Name", "FQBN"] in lines - assert ["Arduino Yún", "arduino:avr:yun"] in lines - assert ["Arduino Uno", "arduino:avr:uno"] in lines - assert ["Arduino Duemilanove or Diecimila", "arduino:avr:diecimila"] in lines - assert ["Arduino Nano", "arduino:avr:nano"] in lines - assert ["Arduino Mega or Mega 2560", "arduino:avr:mega"] in lines - assert ["Arduino Mega ADK", "arduino:avr:megaADK"] in lines - assert ["Arduino Leonardo", "arduino:avr:leonardo"] in lines - assert ["Arduino Leonardo ETH", "arduino:avr:leonardoeth"] in lines - assert ["Arduino Micro", "arduino:avr:micro"] in lines - assert ["Arduino Esplora", "arduino:avr:esplora"] in lines - assert ["Arduino Mini", "arduino:avr:mini"] in lines - assert ["Arduino Ethernet", "arduino:avr:ethernet"] in lines - assert ["Arduino Fio", "arduino:avr:fio"] in lines - assert ["Arduino BT", "arduino:avr:bt"] in lines - assert ["LilyPad Arduino USB", "arduino:avr:LilyPadUSB"] in lines - assert ["LilyPad Arduino", "arduino:avr:lilypad"] in lines - assert ["Arduino Pro or Pro Mini", "arduino:avr:pro"] in lines - assert ["Arduino NG or older", "arduino:avr:atmegang"] in lines - assert ["Arduino Robot Control", "arduino:avr:robotControl"] in lines - assert ["Arduino Robot Motor", "arduino:avr:robotMotor"] in lines - assert ["Arduino Gemma", "arduino:avr:gemma"] in lines - assert ["Adafruit Circuit Playground", "arduino:avr:circuitplay32u4cat"] in lines - assert ["Arduino Yún Mini", "arduino:avr:yunmini"] in lines - assert ["Arduino Industrial 101", "arduino:avr:chiwawa"] in lines - assert ["Linino One", "arduino:avr:one"] in lines - assert ["Arduino Uno WiFi", "arduino:avr:unowifi"] in lines + data = json.loads(res.stdout) + boards = {b["FQBN"]: b for b in data["boards"]} + assert len(boards) == 17 + assert "arduino-beta-development:samd:nano_33_iot" in boards + assert "Arduino NANO 33 IoT" == boards["arduino-beta-development:samd:nano_33_iot"]["name"] + platform = boards["arduino-beta-development:samd:nano_33_iot"]["platform"] + assert "arduino-beta-development:samd" == platform["ID"] + assert "1.8.11" == platform["Installed"] + assert "1.8.11" == platform["Latest"] + assert "Arduino SAMD (32-bits ARM Cortex-M0+) Boards" == platform["Name"] + + assert "arduino-beta-development:samd:mkr1000" in boards + assert "Arduino MKR1000" == boards["arduino-beta-development:samd:mkr1000"]["name"] + platform = boards["arduino-beta-development:samd:mkr1000"]["platform"] + assert "arduino-beta-development:samd" == platform["ID"] + assert "1.8.11" == platform["Installed"] + assert "1.8.11" == platform["Latest"] + assert "Arduino SAMD (32-bits ARM Cortex-M0+) Boards" == platform["Name"] def test_board_details(run_command): From 6fc1e3e35a894debc2764f7d0b1d4d014719403d Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Wed, 3 Mar 2021 11:22:27 +0100 Subject: [PATCH 2/2] Add fuzzy search to board listall command --- commands/board/listall.go | 38 ++++++++++++++++++++++++++++---------- test/test_board.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/commands/board/listall.go b/commands/board/listall.go index cb8baa15b36..a3d3eb075a9 100644 --- a/commands/board/listall.go +++ b/commands/board/listall.go @@ -22,8 +22,13 @@ import ( "github.com/arduino/arduino-cli/commands" rpc "github.com/arduino/arduino-cli/rpc/commands" + "github.com/lithammer/fuzzysearch/fuzzy" ) +// maximumSearchDistance is the maximum Levenshtein distance accepted when using fuzzy search. +// This value is completely arbitrary and picked randomly. +const maximumSearchDistance = 20 + // ListAll FIXMEDOC func ListAll(ctx context.Context, req *rpc.BoardListAllReq) (*rpc.BoardListAllResp, error) { pm := commands.GetPackageManager(req.GetInstance().GetId()) @@ -31,18 +36,18 @@ func ListAll(ctx context.Context, req *rpc.BoardListAllReq) (*rpc.BoardListAllRe return nil, errors.New("invalid instance") } - args := req.GetSearchArgs() - match := func(name string) bool { - if len(args) == 0 { + searchArgs := strings.Join(req.SearchArgs, " ") + + match := func(toTest []string) bool { + if len(searchArgs) == 0 { return true } - name = strings.ToLower(name) - for _, term := range args { - if !strings.Contains(name, strings.ToLower(term)) { - return false + for _, rank := range fuzzy.RankFindNormalizedFold(searchArgs, toTest) { + if rank.Distance < maximumSearchDistance { + return true } } - return true + return false } list := &rpc.BoardListAllResp{Boards: []*rpc.BoardListItem{}} @@ -72,13 +77,26 @@ func ListAll(ctx context.Context, req *rpc.BoardListAllReq) (*rpc.BoardListAllRe ManuallyInstalled: platform.ManuallyInstalled, } + toTest := []string{ + platform.String(), + platform.Name, + platform.Architecture, + targetPackage.Name, + targetPackage.Maintainer, + } + for _, board := range installedPlatformRelease.Boards { - if !match(board.Name()) { + if !req.GetIncludeHiddenBoards() && board.IsHidden() { continue } - if !req.GetIncludeHiddenBoards() && board.IsHidden() { + + toTest := toTest + toTest = append(toTest, strings.Split(board.Name(), " ")...) + toTest = append(toTest, board.FQBN()) + if !match(toTest) { continue } + list.Boards = append(list.Boards, &rpc.BoardListItem{ Name: board.Name(), FQBN: board.FQBN(), diff --git a/test/test_board.py b/test/test_board.py index 4a39fc08c6d..217064c83f4 100644 --- a/test/test_board.py +++ b/test/test_board.py @@ -455,6 +455,34 @@ def test_board_listall_with_manually_installed_platform(run_command, data_dir): assert "Arduino SAMD (32-bits ARM Cortex-M0+) Boards" == platform["Name"] +def test_board_listall_fuzzy_search(run_command, data_dir): + assert run_command("update") + + # Install from platform manager + assert run_command("core install arduino:avr@1.8.3") + + # Manually installs a core in sketchbooks hardware folder + git_url = "https://github.com/arduino/ArduinoCore-samd.git" + repo_dir = Path(data_dir, "hardware", "arduino-beta-development", "samd") + assert Repo.clone_from(git_url, repo_dir, multi_options=["-b 1.8.11"]) + + res = run_command("board listall --format json samd") + assert res.ok + data = json.loads(res.stdout) + boards = {b["FQBN"]: b for b in data["boards"]} + assert len(boards) == 17 + assert "arduino-beta-development:samd:mkr1000" in boards + assert "arduino:avr:uno" not in boards + + res = run_command("board listall --format json avr") + assert res.ok + data = json.loads(res.stdout) + boards = {b["FQBN"]: b for b in data["boards"]} + assert len(boards) == 26 + assert "arduino:avr:uno" in boards + assert "arduino-beta-development:samd:mkr1000" not in boards + + def test_board_details(run_command): run_command("core update-index") # Download samd core pinned to 1.8.6