Skip to content

Commit 83d7f6e

Browse files
author
Roberto Sora
authored
Enhance "board details" command (arduino#674)
* Add properties to board details printing * Add usb IdentificationPrefs * Add more details * refactor board id * Add help and Package name * Inject package URL in package structs * Add tool release unroll * Prettify commands code * Polish struct usage * Add board details test * Reformat proto * Make linter happy * Add table printing * Make linter happy again * Add missing sizes to gold details json test * Add search for external package tool dependencies * Add --full flag and test table print comestics
1 parent 763b4a7 commit 83d7f6e

File tree

10 files changed

+1302
-219
lines changed

10 files changed

+1302
-219
lines changed

arduino/cores/packageindex/index.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ type indexPackage struct {
3535
Name string `json:"name,required"`
3636
Maintainer string `json:"maintainer,required"`
3737
WebsiteURL string `json:"websiteUrl"`
38+
URL string `json:"Url"`
3839
Email string `json:"email"`
3940
Platforms []*indexPlatformRelease `json:"platforms,required"`
4041
Tools []*indexToolRelease `json:"tools,required"`
@@ -94,7 +95,7 @@ type indexHelp struct {
9495
}
9596

9697
// MergeIntoPackages converts the Index data into a cores.Packages and merge them
97-
// with the existing conents of the cores.Packages passed as parameter.
98+
// with the existing contents of the cores.Packages passed as parameter.
9899
func (index Index) MergeIntoPackages(outPackages cores.Packages) {
99100
for _, inPackage := range index.Packages {
100101
inPackage.extractPackageIn(outPackages)
@@ -105,7 +106,9 @@ func (inPackage indexPackage) extractPackageIn(outPackages cores.Packages) {
105106
outPackage := outPackages.GetOrCreatePackage(inPackage.Name)
106107
outPackage.Maintainer = inPackage.Maintainer
107108
outPackage.WebsiteURL = inPackage.WebsiteURL
109+
outPackage.URL = inPackage.URL
108110
outPackage.Email = inPackage.Email
111+
outPackage.Help = cores.PackageHelp{Online: inPackage.Help.Online}
109112

110113
for _, inTool := range inPackage.Tools {
111114
inTool.extractToolIn(outPackage)

arduino/cores/packagemanager/package_manager.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,18 @@ func (pm *PackageManager) ResolveFQBN(fqbn *cores.FQBN) (
201201

202202
// LoadPackageIndex loads a package index by looking up the local cached file from the specified URL
203203
func (pm *PackageManager) LoadPackageIndex(URL *url.URL) error {
204-
_, err := pm.LoadPackageIndexFromFile(pm.IndexDir.Join(path.Base(URL.Path)))
205-
return err
204+
indexPath := pm.IndexDir.Join(path.Base(URL.Path))
205+
index, err := packageindex.LoadIndex(indexPath)
206+
if err != nil {
207+
return fmt.Errorf("loading json index file %s: %s", indexPath, err)
208+
}
209+
210+
for _, p := range index.Packages {
211+
p.URL = URL.String()
212+
}
213+
214+
index.MergeIntoPackages(pm.Packages)
215+
return nil
206216
}
207217

208218
// LoadPackageIndexFromFile load a package index from the specified file

arduino/cores/status.go

+7
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,21 @@ func NewPackages() Packages {
3030
return map[string]*Package{}
3131
}
3232

33+
// PackageHelp contains info on how to reach maintainers for help
34+
type PackageHelp struct {
35+
Online string `json:"online,omitempty"`
36+
}
37+
3338
// Package represents a package in the system.
3439
type Package struct {
3540
Name string // Name of the package.
3641
Maintainer string // Name of the maintainer.
3742
WebsiteURL string // Website of maintainer.
43+
URL string // origin URL for package index json file.
3844
Email string // Email of maintainer.
3945
Platforms map[string]*Platform // The platforms in the system.
4046
Tools map[string]*Tool // The tools in the system.
47+
Help PackageHelp `json:"-"`
4148
Packages Packages `json:"-"`
4249
}
4350

cli/board/board.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func NewCommand() *cobra.Command {
3434
}
3535

3636
boardCommand.AddCommand(initAttachCommand())
37-
boardCommand.AddCommand(detailsCommand)
37+
boardCommand.AddCommand(initDetailsCommand())
3838
boardCommand.AddCommand(initListCommand())
3939
boardCommand.AddCommand(listAllCommand)
4040

cli/board/details.go

+61-13
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ package board
1717

1818
import (
1919
"context"
20-
"os"
21-
20+
"fmt"
2221
"github.com/arduino/arduino-cli/cli/errorcodes"
2322
"github.com/arduino/arduino-cli/cli/feedback"
2423
"github.com/arduino/arduino-cli/cli/instance"
@@ -27,15 +26,24 @@ import (
2726
"github.com/arduino/arduino-cli/table"
2827
"github.com/fatih/color"
2928
"github.com/spf13/cobra"
29+
"os"
3030
)
3131

32-
var detailsCommand = &cobra.Command{
33-
Use: "details <FQBN>",
34-
Short: "Print details about a board.",
35-
Long: "Show information about a board, in particular if the board has options to be specified in the FQBN.",
36-
Example: " " + os.Args[0] + " board details arduino:avr:nano",
37-
Args: cobra.ExactArgs(1),
38-
Run: runDetailsCommand,
32+
var showFullDetails bool
33+
34+
func initDetailsCommand() *cobra.Command {
35+
var detailsCommand = &cobra.Command{
36+
Use: "details <FQBN>",
37+
Short: "Print details about a board.",
38+
Long: "Show information about a board, in particular if the board has options to be specified in the FQBN.",
39+
Example: " " + os.Args[0] + " board details arduino:avr:nano",
40+
Args: cobra.ExactArgs(1),
41+
Run: runDetailsCommand,
42+
}
43+
44+
detailsCommand.Flags().BoolVarP(&showFullDetails, "full", "f", false, "Include full details in text output")
45+
46+
return detailsCommand
3947
}
4048

4149
func runDetailsCommand(cmd *cobra.Command, args []string) {
@@ -85,18 +93,58 @@ func (dr detailsResult) String() string {
8593
t := table.New()
8694
t.SetColumnWidthMode(1, table.Average)
8795
t.AddRow("Board name:", details.Name)
96+
t.AddRow("Board fqbn:", details.Fqbn)
97+
t.AddRow("Board propertiesId:", details.PropertiesId)
98+
t.AddRow("Board version:", details.Version)
99+
100+
if details.Official {
101+
t.AddRow() // get some space from above
102+
t.AddRow("Official Arduino board:",
103+
table.NewCell("✔", color.New(color.FgGreen)))
104+
}
88105

89-
for i, tool := range details.RequiredTools {
106+
for i, idp := range details.IdentificationPref {
90107
if i == 0 {
91108
t.AddRow() // get some space from above
92-
t.AddRow("Required tools:", tool.Packager+":"+tool.Name, "", tool.Version)
109+
t.AddRow("Identification Preferences:", "VID:"+idp.UsbID.VID+" PID:"+idp.UsbID.PID)
93110
continue
94111
}
95-
t.AddRow("", tool.Packager+":"+tool.Name, "", tool.Version)
112+
t.AddRow("", "VID:"+idp.UsbID.VID+" PID:"+idp.UsbID.PID)
96113
}
97114

98-
for _, option := range details.ConfigOptions {
115+
t.AddRow() // get some space from above
116+
t.AddRow("Package name:", details.Package.Name)
117+
t.AddRow("Package maintainer:", details.Package.Maintainer)
118+
t.AddRow("Package URL:", details.Package.Url)
119+
t.AddRow("Package websiteURL:", details.Package.WebsiteURL)
120+
t.AddRow("Package online help:", details.Package.Help.Online)
121+
122+
t.AddRow() // get some space from above
123+
t.AddRow("Platform name:", details.Platform.Name)
124+
t.AddRow("Platform category:", details.Platform.Category)
125+
t.AddRow("Platform architecture:", details.Platform.Architecture)
126+
t.AddRow("Platform URL:", details.Platform.Url)
127+
t.AddRow("Platform file name:", details.Platform.ArchiveFileName)
128+
t.AddRow("Platform size (bytes):", fmt.Sprint(details.Platform.Size))
129+
t.AddRow("Platform checksum:", details.Platform.Checksum)
130+
131+
t.AddRow() // get some space from above
132+
for _, tool := range details.ToolsDependencies {
133+
t.AddRow("Required tools:", tool.Packager+":"+tool.Name, "", tool.Version)
134+
if showFullDetails {
135+
for _, sys := range tool.Systems {
136+
t.AddRow("", "OS:", "", sys.Host)
137+
t.AddRow("", "File:", "", sys.ArchiveFileName)
138+
t.AddRow("", "Size (bytes):", "", fmt.Sprint(sys.Size))
139+
t.AddRow("", "Checksum:", "", sys.Checksum)
140+
t.AddRow("", "URL:", "", sys.Url)
141+
t.AddRow() // get some space from above
142+
}
143+
}
99144
t.AddRow() // get some space from above
145+
}
146+
147+
for _, option := range details.ConfigOptions {
100148
t.AddRow("Option:", option.OptionLabel, "", option.Option)
101149
for _, value := range option.Values {
102150
green := color.New(color.FgGreen)

commands/board/details.go

+57-9
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import (
2525
rpc "github.com/arduino/arduino-cli/rpc/commands"
2626
)
2727

28-
// Details FIXMEDOC
28+
// Details returns all details for a board including tools and HW identifiers.
29+
// This command basically gather al the information and translates it into the required grpc struct properties
2930
func Details(ctx context.Context, req *rpc.BoardDetailsReq) (*rpc.BoardDetailsResp, error) {
3031
pm := commands.GetPackageManager(req.GetInstance().GetId())
3132
if pm == nil {
@@ -37,13 +38,47 @@ func Details(ctx context.Context, req *rpc.BoardDetailsReq) (*rpc.BoardDetailsRe
3738
return nil, fmt.Errorf("parsing fqbn: %s", err)
3839
}
3940

40-
_, _, board, _, _, err := pm.ResolveFQBN(fqbn)
41+
boardPackage, boardPlatform, board, _, _, err := pm.ResolveFQBN(fqbn)
4142
if err != nil {
4243
return nil, fmt.Errorf("loading board data: %s", err)
4344
}
4445

4546
details := &rpc.BoardDetailsResp{}
4647
details.Name = board.Name()
48+
details.Fqbn = board.FQBN()
49+
details.PropertiesId = board.BoardID
50+
details.Official = fqbn.Package == "arduino"
51+
details.Version = board.PlatformRelease.Version.String()
52+
53+
details.Package = &rpc.Package{
54+
Name: boardPackage.Name,
55+
Maintainer: boardPackage.Maintainer,
56+
WebsiteURL: boardPackage.WebsiteURL,
57+
Email: boardPackage.Email,
58+
Help: &rpc.Help{Online: boardPackage.Help.Online},
59+
Url: boardPackage.URL,
60+
}
61+
62+
details.Platform = &rpc.BoardPlatform{
63+
Architecture: boardPlatform.Platform.Architecture,
64+
Category: boardPlatform.Platform.Category,
65+
Url: boardPlatform.Resource.URL,
66+
ArchiveFileName: boardPlatform.Resource.ArchiveFileName,
67+
Checksum: boardPlatform.Resource.Checksum,
68+
Size: boardPlatform.Resource.Size,
69+
Name: boardPlatform.Platform.Name,
70+
}
71+
72+
details.IdentificationPref = []*rpc.IdentificationPref{}
73+
vids := board.Properties.SubTree("vid")
74+
pids := board.Properties.SubTree("pid")
75+
for id, vid := range vids.AsMap() {
76+
if pid, ok := pids.GetOk(id); ok {
77+
idPref := rpc.IdentificationPref{UsbID: &rpc.USBID{VID: vid, PID: pid}}
78+
details.IdentificationPref = append(details.IdentificationPref, &idPref)
79+
}
80+
}
81+
4782
details.ConfigOptions = []*rpc.ConfigOption{}
4883
options := board.GetConfigOptions()
4984
for _, option := range options.Keys() {
@@ -60,7 +95,6 @@ func Details(ctx context.Context, req *rpc.BoardDetailsReq) (*rpc.BoardDetailsRe
6095
} else if !hasSelected && i == 0 {
6196
configValue.Selected = true
6297
}
63-
6498
configValue.Value = value
6599
configValue.ValueLabel = values.Get(value)
66100
configOption.Values = append(configOption.Values, configValue)
@@ -69,12 +103,26 @@ func Details(ctx context.Context, req *rpc.BoardDetailsReq) (*rpc.BoardDetailsRe
69103
details.ConfigOptions = append(details.ConfigOptions, configOption)
70104
}
71105

72-
details.RequiredTools = []*rpc.RequiredTool{}
73-
for _, reqTool := range board.PlatformRelease.Dependencies {
74-
details.RequiredTools = append(details.RequiredTools, &rpc.RequiredTool{
75-
Name: reqTool.ToolName,
76-
Packager: reqTool.ToolPackager,
77-
Version: reqTool.ToolVersion.String(),
106+
details.ToolsDependencies = []*rpc.ToolsDependencies{}
107+
for _, tool := range boardPlatform.Dependencies {
108+
toolRelease := pm.FindToolDependency(tool)
109+
var systems []*rpc.Systems
110+
if toolRelease != nil {
111+
for _, f := range toolRelease.Flavors {
112+
systems = append(systems, &rpc.Systems{
113+
Checksum: f.Resource.Checksum,
114+
Size: f.Resource.Size,
115+
Host: f.OS,
116+
ArchiveFileName: f.Resource.ArchiveFileName,
117+
Url: f.Resource.URL,
118+
})
119+
}
120+
}
121+
details.ToolsDependencies = append(details.ToolsDependencies, &rpc.ToolsDependencies{
122+
Name: tool.ToolName,
123+
Packager: tool.ToolPackager,
124+
Version: tool.ToolVersion.String(),
125+
Systems: systems,
78126
})
79127
}
80128

0 commit comments

Comments
 (0)