Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented "latest" field in 'firmware list' command #52

Merged
merged 5 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 12 additions & 6 deletions cli/firmware/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/arduino/arduino-cli/cli/feedback"
"github.com/arduino/arduino-cli/table"
"github.com/spf13/cobra"
semver "go.bug.st/relaxed-semver"
)

func newListCommand() *cobra.Command {
Expand All @@ -46,10 +47,10 @@ func newListCommand() *cobra.Command {
}

type FirmwareResult struct {
BoardName string `json:"board_name"`
BoardFQBN string `json:"board_fqbn"`
Module string `json:"module"`
FirmwareVersion string `json:"firmware_version"`
BoardName string `json:"board_name"`
BoardFQBN string `json:"board_fqbn"`
Module string `json:"module"`
FirmwareVersion *semver.RelaxedVersion `json:"firmware_version"`
Latest bool
}

Expand All @@ -70,6 +71,7 @@ func list(fqbn string) {
BoardFQBN: board.Fqbn,
Module: board.Module,
FirmwareVersion: firmware.Version,
Latest: board.Latest == firmware,
})
}
}
Expand All @@ -83,9 +85,13 @@ func (f FirmwareListResult) String() string {
return "No firmwares available."
}
t := table.New()
t.SetHeader("Board", "FQBN", "Module", "Version")
t.SetHeader("Board", "FQBN", "Module", "", "Version")
for _, fw := range f {
t.AddRow(fw.BoardName, fw.BoardFQBN, fw.Module, fw.FirmwareVersion)
latest := ""
if fw.Latest {
latest = "✔"
}
t.AddRow(fw.BoardName, fw.BoardFQBN, fw.Module, latest, fw.FirmwareVersion)
}
return t.Render()
}
Expand Down
2 changes: 1 addition & 1 deletion indexes/download/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func DownloadFirmware(firmware *firmwareindex.IndexFirmware) (*paths.Path, error
firmwarePath := globals.FwUploaderPath.Join(
"firmwares",
firmware.Module,
firmware.Version,
firmware.Version.String(),
path.Base(firmware.URL))
firmwarePath.Parent().MkdirAll()
if err := firmwarePath.WriteFile(nil); err != nil {
Expand Down
72 changes: 35 additions & 37 deletions indexes/firmwareindex/firmwareindex.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type IndexBoard struct {
UploadTouch bool `json:"upload.use_1200bps_touch"`
UploadWait bool `json:"upload.wait_for_upload_port"`
UploaderCommand *IndexUploaderCommand `json:"uploader.command,required"`
Latest *IndexFirmware `json:"-"`
}

type IndexUploaderCommand struct {
Expand All @@ -58,11 +59,11 @@ type IndexUploaderCommand struct {

// IndexFirmware represents a single Firmware version from module_firmware_index.json file.
type IndexFirmware struct {
Version string `json:"version,required"` // `*semver.Version` but with SARA version is giving problems
URL string `json:"url,required"`
Checksum string `json:"checksum,required"`
Size json.Number `json:"size,required"`
Module string `json:"module,required"`
Version *semver.RelaxedVersion `json:"version,required"`
URL string `json:"url,required"`
Checksum string `json:"checksum,required"`
Size json.Number `json:"size,required"`
Module string `json:"module,required"`
}

// IndexLoaderSketch represents the sketch used to upload the new firmware on a board.
Expand All @@ -74,12 +75,7 @@ type IndexLoaderSketch struct {

// LoadIndex reads a module_firmware_index.json from a file and returns the corresponding Index structure.
func LoadIndex(jsonIndexFile *paths.Path) (*Index, error) {
buff, err := jsonIndexFile.ReadFile()
if err != nil {
return nil, err
}
var index Index
err = json.Unmarshal(buff, &index.Boards)
index, err := LoadIndexNoSign(jsonIndexFile)
if err != nil {
return nil, err
}
Expand All @@ -93,20 +89,21 @@ func LoadIndex(jsonIndexFile *paths.Path) (*Index, error) {
if err != nil {
return nil, err
}

trusted, _, err := security.VerifySignature(jsonIndexFile, jsonSignatureFile, key)
if err != nil {
logrus.
WithField("index", jsonIndexFile).
WithField("signatureFile", jsonSignatureFile).
WithError(err).Infof("Checking signature")
} else {
logrus.
WithField("index", jsonIndexFile).
WithField("signatureFile", jsonSignatureFile).
WithField("trusted", trusted).Infof("Checking signature")
index.IsTrusted = trusted
return nil, err
}
return &index, nil
logrus.
WithField("index", jsonIndexFile).
WithField("signatureFile", jsonSignatureFile).
WithField("trusted", trusted).Infof("Checking signature")
index.IsTrusted = trusted
return index, nil
}

// LoadIndexNoSign reads a module_firmware_index.json from a file and returns the corresponding Index structure.
Expand All @@ -123,6 +120,19 @@ func LoadIndexNoSign(jsonIndexFile *paths.Path) (*Index, error) {

index.IsTrusted = true

// Determine latest firmware for each board
for _, board := range index.Boards {
if board.Module == "SARA" {
// TODO implement?? by defualt you have to specify the version
continue
}
for _, firmware := range board.Firmwares {
if board.Latest == nil || firmware.Version.GreaterThan(board.Latest.Version) {
board.Latest = firmware
}
}
}

return &index, nil
}

Expand All @@ -133,40 +143,28 @@ func (i *Index) GetLatestFirmwareURL(fqbn string) (string, error) {
if board == nil {
return "", fmt.Errorf("invalid FQBN: %s", fqbn)
}
if board.Module == "SARA" { // TODO togliere sara, lo assumo giá nel comando
// TODO implement?? by defualt you have to specify the version
return "", fmt.Errorf("not implemented for SARA module")
}

var latestVersion *semver.RelaxedVersion
var latestFirmwareURL string
for _, firmware := range board.Firmwares {
version := semver.ParseRelaxed(firmware.Version)
if latestVersion == nil || version.GreaterThan(latestVersion) { // TODO check the condition
latestVersion = version
latestFirmwareURL = firmware.URL
}
}
if latestVersion != nil {
return latestFirmwareURL, nil
} else {
if board.Latest == nil {
return "", fmt.Errorf("cannot find latest version")
}

return board.Latest.URL, nil
}

// GetFirmwareURL will take the fqbn of the required board and the version of the firmware as parameters.
// It will return the URL of the required firmware
func (i *Index) GetFirmwareURL(fqbn, version string) (string, error) {
func (i *Index) GetFirmwareURL(fqbn, v string) (string, error) {
board := i.GetBoard(fqbn)
if board == nil {
return "", fmt.Errorf("invalid FQBN: %s", fqbn)
}
version := semver.ParseRelaxed(v)
for _, firmware := range board.Firmwares {
if firmware.Version == version {
if firmware.Version.Equal(version) {
return firmware.URL, nil
}
}
return "", fmt.Errorf("invalid version: %s", version)
return "", fmt.Errorf("version not found: %s", version)
}

// GetLoaderSketchURL will take the board's fqbn and return the url of the loader sketch
Expand Down