From 18f0c66c80189610b8dea73263c2a93ce8f362c6 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 10 Jun 2021 12:59:03 +0200 Subject: [PATCH 1/6] Show help if user doesn't specify any parameter --- main.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.go b/main.go index 3321c013..09173629 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,11 @@ import ( func main() { uploaderCmd := cli.NewCommand() + if len(os.Args) == 1 { + // Show help if user doesn't specify any parameter + uploaderCmd.Help() + os.Exit(1) + } if err := uploaderCmd.Execute(); err != nil { os.Exit(1) } From afa2b9b4431a68d32a0f7a763490ce6e8b7876cc Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 10 Jun 2021 13:29:28 +0200 Subject: [PATCH 2/6] Renamed variable --- cli/cli.go | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/cli/cli.go b/cli/cli.go index a3f8f433..6a22dbb3 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -55,7 +55,7 @@ var ( func NewCommand() *cobra.Command { // FirmwareUploader is the root command - firmwareUploaderCli := &cobra.Command{ + rootCmd := &cobra.Command{ Use: "FirmwareUploader", Short: "FirmwareUploader.", Long: "FirmwareUploader (FirmwareUploader).", @@ -65,28 +65,29 @@ func NewCommand() *cobra.Command { PersistentPreRun: preRun, } - firmwareUploaderCli.AddCommand(version.NewCommand()) + rootCmd.AddCommand(version.NewCommand()) - firmwareUploaderCli.Flags().StringVar(&ctx.PortName, "port", "", "serial port to use for flashing") - firmwareUploaderCli.Flags().StringVar(&ctx.RootCertDir, "certs", "", "root certificate directory") - firmwareUploaderCli.Flags().StringSliceVar(&ctx.Addresses, "address", []string{}, "address (host:port) to fetch and flash root certificate for, multiple values allowed") - firmwareUploaderCli.Flags().StringVar(&ctx.FirmwareFile, "firmware", "", "firmware file to flash") - firmwareUploaderCli.Flags().BoolVar(&ctx.ReadAll, "read", false, "read all firmware and output to stdout") - firmwareUploaderCli.Flags().StringVar(&ctx.FWUploaderBinary, "flasher", "", "firmware upload binary (precompiled for the right target)") - firmwareUploaderCli.Flags().StringVar(&ctx.BinaryToRestore, "restore_binary", "", "binary to restore after the firmware upload (precompiled for the right target)") - firmwareUploaderCli.Flags().StringVar(&ctx.ProgrammerPath, "programmer", "", "path of programmer in use (avrdude/bossac)") - firmwareUploaderCli.Flags().StringVar(&ctx.Model, "model", "", "module model (winc, nina or sara)") - firmwareUploaderCli.Flags().StringVar(&ctx.BoardName, "get_available_for", "", "Ask for available firmwares matching a given board") - firmwareUploaderCli.Flags().IntVar(&ctx.Retries, "retries", 9, "Number of retries in case of upload failure") - firmwareUploaderCli.PersistentFlags().StringVar(&outputFormat, "format", "text", "The output format, can be {text|json}.") + rootCmd.Flags().StringVar(&ctx.PortName, "port", "", "serial port to use for flashing") + rootCmd.Flags().StringVar(&ctx.RootCertDir, "certs", "", "root certificate directory") + rootCmd.Flags().StringSliceVar(&ctx.Addresses, "address", []string{}, "address (host:port) to fetch and flash root certificate for, multiple values allowed") + rootCmd.Flags().StringVar(&ctx.FirmwareFile, "firmware", "", "firmware file to flash") + rootCmd.Flags().BoolVar(&ctx.ReadAll, "read", false, "read all firmware and output to stdout") + rootCmd.Flags().StringVar(&ctx.FWUploaderBinary, "flasher", "", "firmware upload binary (precompiled for the right target)") + rootCmd.Flags().StringVar(&ctx.BinaryToRestore, "restore_binary", "", "binary to restore after the firmware upload (precompiled for the right target)") + rootCmd.Flags().StringVar(&ctx.ProgrammerPath, "programmer", "", "path of programmer in use (avrdude/bossac)") + rootCmd.Flags().StringVar(&ctx.Model, "model", "", "module model (winc, nina or sara)") + rootCmd.Flags().StringVar(&ctx.BoardName, "get_available_for", "", "Ask for available firmwares matching a given board") + rootCmd.Flags().IntVar(&ctx.Retries, "retries", 9, "Number of retries in case of upload failure") - firmwareUploaderCli.PersistentFlags().StringVar(&logFile, "log-file", "", "Path to the file where logs will be written") - firmwareUploaderCli.PersistentFlags().StringVar(&logFormat, "log-format", "", "The output format for the logs, can be {text|json}.") - firmwareUploaderCli.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Messages with this level and above will be logged. Valid levels are: trace, debug, info, warn, error, fatal, panic") - firmwareUploaderCli.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Print the logs on the standard output.") + rootCmd.PersistentFlags().StringVar(&outputFormat, "format", "text", "The output format, can be {text|json}.") - return firmwareUploaderCli + rootCmd.PersistentFlags().StringVar(&logFile, "log-file", "", "Path to the file where logs will be written") + rootCmd.PersistentFlags().StringVar(&logFormat, "log-format", "", "The output format for the logs, can be {text|json}.") + rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Messages with this level and above will be logged. Valid levels are: trace, debug, info, warn, error, fatal, panic") + rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Print the logs on the standard output.") + + return rootCmd } func run(cmd *cobra.Command, args []string) { From 2caeaca6ea6521225419c35d35ce13c2c407ddb6 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 10 Jun 2021 13:29:55 +0200 Subject: [PATCH 3/6] Added 'firmware list' command stubs --- cli/cli.go | 2 ++ cli/firmware/firmware.go | 46 ++++++++++++++++++++++++++++++++++++++++ cli/firmware/list.go | 25 ++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 cli/firmware/firmware.go create mode 100644 cli/firmware/list.go diff --git a/cli/cli.go b/cli/cli.go index 6a22dbb3..17b89ece 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -28,6 +28,7 @@ import ( "strings" "time" + "github.com/arduino/FirmwareUploader/cli/firmware" "github.com/arduino/FirmwareUploader/cli/version" "github.com/arduino/FirmwareUploader/modules/nina" "github.com/arduino/FirmwareUploader/modules/sara" @@ -67,6 +68,7 @@ func NewCommand() *cobra.Command { rootCmd.AddCommand(version.NewCommand()) + rootCmd.AddCommand(firmware.NewCommand()) rootCmd.Flags().StringVar(&ctx.PortName, "port", "", "serial port to use for flashing") rootCmd.Flags().StringVar(&ctx.RootCertDir, "certs", "", "root certificate directory") diff --git a/cli/firmware/firmware.go b/cli/firmware/firmware.go new file mode 100644 index 00000000..ce551f71 --- /dev/null +++ b/cli/firmware/firmware.go @@ -0,0 +1,46 @@ +/* + FirmwareUploader + Copyright (c) 2021 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +package firmware + +import ( + "os" + + "github.com/spf13/cobra" +) + +func NewCommand() *cobra.Command { + firmwareCmd := &cobra.Command{ + Use: "firmware", + Short: "Commands to operate on firmwares.", + Long: "A subset of commands to perform various firmware operations.", + Example: " " + os.Args[0] + " firmware ...", + } + + firmwareListCmd := &cobra.Command{ + Use: "list", + Short: "List available firmwares", + Long: "Displays the availale firmwares, is it possible to filter results for a specific board.", + Example: " " + os.Args[0] + " firmware list -b arduino:samd:mkr1000", + Args: cobra.NoArgs, + Run: list, + } + firmwareCmd.AddCommand(firmwareListCmd) + return firmwareCmd +} diff --git a/cli/firmware/list.go b/cli/firmware/list.go new file mode 100644 index 00000000..0d3a6571 --- /dev/null +++ b/cli/firmware/list.go @@ -0,0 +1,25 @@ +/* + FirmwareUploader + Copyright (c) 2021 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +package firmware + +import "github.com/spf13/cobra" + +func list(cmd *cobra.Command, args []string) { +} From 1d06066c8b9a47d775dc1f4c03b42a8f9129838d Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 10 Jun 2021 15:01:38 +0200 Subject: [PATCH 4/6] Fixed json directive --- indexes/firmwareindex/firmwareindex.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indexes/firmwareindex/firmwareindex.go b/indexes/firmwareindex/firmwareindex.go index f2c95892..25f85820 100644 --- a/indexes/firmwareindex/firmwareindex.go +++ b/indexes/firmwareindex/firmwareindex.go @@ -62,7 +62,7 @@ type IndexFirmware struct { URL string `json:"url,required"` Checksum string `json:"checksum,required"` Size json.Number `json:"size,required"` - Module string `json:module,required` + Module string `json:"module,required"` } // IndexLoaderSketch represents the sketch used to upload the new firmware on a board. From 3c5d3155d04b1d9d32a8acbbc2eb4a3f23dfeecf Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 10 Jun 2021 15:02:24 +0200 Subject: [PATCH 5/6] Added Index.GetBoard method and factored out API in Index and BoardIndex --- indexes/firmwareindex/firmwareindex.go | 77 ++++++++++++++------------ 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/indexes/firmwareindex/firmwareindex.go b/indexes/firmwareindex/firmwareindex.go index 25f85820..73acc5f0 100644 --- a/indexes/firmwareindex/firmwareindex.go +++ b/indexes/firmwareindex/firmwareindex.go @@ -129,54 +129,63 @@ func LoadIndexNoSign(jsonIndexFile *paths.Path) (*Index, error) { // GetLatestFirmwareURL takes the fqbn as parameter and returns the URL of the latest available firmware. // Not currently implemented for SARA, as the version for it's firmware is a bit strange func (i *Index) GetLatestFirmwareURL(fqbn string) (string, error) { - for _, board := range i.Boards { - var latestVersion *semver.RelaxedVersion - var latestFirmwareURL string - if board.Fqbn == fqbn && board.Module != "SARA" { // TODO togliere sara, lo assumo giá nel comando - 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 { - return "", fmt.Errorf("cannot find latest version") - } - } else if board.Fqbn == fqbn { // SARA - // TODO implement?? by defualt you have to specify the version - return "", fmt.Errorf("not implemented for SARA module") + board := i.GetBoard(fqbn) + 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 } } - return "", fmt.Errorf("invalid FQBN: %s", fqbn) + if latestVersion != nil { + return latestFirmwareURL, nil + } else { + return "", fmt.Errorf("cannot find latest version") + } } // 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 +// It will return the URL of the required firmware func (i *Index) GetFirmwareURL(fqbn, version string) (string, error) { - for _, board := range i.Boards { - if board.Fqbn == fqbn { - for _, firmware := range board.Firmwares { - if firmware.Version == version { - return firmware.URL, nil - } - } - return "", fmt.Errorf("invalid version: %s", version) + board := i.GetBoard(fqbn) + if board == nil { + return "", fmt.Errorf("invalid FQBN: %s", fqbn) + } + for _, firmware := range board.Firmwares { + if firmware.Version == version { + return firmware.URL, nil } } - return "", fmt.Errorf("invalid FQBN: %s", fqbn) + return "", fmt.Errorf("invalid version: %s", version) } // GetLoaderSketchURL will take the board's fqbn and return the url of the loader sketch func (i *Index) GetLoaderSketchURL(fqbn string) (string, error) { - for _, board := range i.Boards { - if board.Fqbn == fqbn { - return board.LoaderSketch.URL, nil + board := i.GetBoard(fqbn) + if board == nil { + return "", fmt.Errorf("invalid FQBN: %s", fqbn) + } + return board.LoaderSketch.URL, nil +} + +// GetBoard returns the IndexBoard for the given FQBN +func (i *Index) GetBoard(fqbn string) *IndexBoard { + for _, b := range i.Boards { + if b.Fqbn == fqbn { + return b } } - return "", fmt.Errorf("invalid FQBN: %s", fqbn) + return nil } func (b *IndexBoard) GetUploaderCommand() string { From 7f9bbac56e6c4f6a0b133d3e55b79a37098faff0 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 10 Jun 2021 15:02:43 +0200 Subject: [PATCH 6/6] 'firmware list' first implementation --- cli/firmware/firmware.go | 10 +----- cli/firmware/list.go | 74 ++++++++++++++++++++++++++++++++++++++-- go.sum | 1 + 3 files changed, 74 insertions(+), 11 deletions(-) diff --git a/cli/firmware/firmware.go b/cli/firmware/firmware.go index ce551f71..2b81a8a1 100644 --- a/cli/firmware/firmware.go +++ b/cli/firmware/firmware.go @@ -33,14 +33,6 @@ func NewCommand() *cobra.Command { Example: " " + os.Args[0] + " firmware ...", } - firmwareListCmd := &cobra.Command{ - Use: "list", - Short: "List available firmwares", - Long: "Displays the availale firmwares, is it possible to filter results for a specific board.", - Example: " " + os.Args[0] + " firmware list -b arduino:samd:mkr1000", - Args: cobra.NoArgs, - Run: list, - } - firmwareCmd.AddCommand(firmwareListCmd) + firmwareCmd.AddCommand(newListCommand()) return firmwareCmd } diff --git a/cli/firmware/list.go b/cli/firmware/list.go index 0d3a6571..365ba1b7 100644 --- a/cli/firmware/list.go +++ b/cli/firmware/list.go @@ -19,7 +19,77 @@ package firmware -import "github.com/spf13/cobra" +import ( + "os" -func list(cmd *cobra.Command, args []string) { + "github.com/arduino/FirmwareUploader/indexes" + "github.com/arduino/arduino-cli/cli/feedback" + "github.com/arduino/arduino-cli/table" + "github.com/spf13/cobra" +) + +func newListCommand() *cobra.Command { + var fqbn *string + + listCmd := &cobra.Command{ + Use: "list", + Short: "List available firmwares", + Long: "Displays the availale firmwares, is it possible to filter results for a specific board.", + Example: " " + os.Args[0] + " firmware list -b arduino:samd:mkr1000", + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + list(*fqbn) + }, + } + fqbn = listCmd.Flags().StringP("fqbn", "b", "", "Filter result for the specified board FQBN") + return listCmd +} + +type FirmwareResult struct { + BoardName string `json:"board_name"` + BoardFQBN string `json:"board_fqbn"` + Module string `json:"module"` + FirmwareVersion string `json:"firmware_version"` + Latest bool +} + +type FirmwareListResult []*FirmwareResult + +func list(fqbn string) { + firmwareIndex, err := indexes.GetFirmwareIndex() + if err != nil { + feedback.Error(err) + } + + res := FirmwareListResult{} + for _, board := range firmwareIndex.Boards { + if fqbn == "" || board.Fqbn == fqbn { + for _, firmware := range board.Firmwares { + res = append(res, &FirmwareResult{ + BoardName: board.Name, + BoardFQBN: board.Fqbn, + Module: board.Module, + FirmwareVersion: firmware.Version, + }) + } + } + } + + feedback.PrintResult(res) +} + +func (f FirmwareListResult) String() string { + if len(f) == 0 { + return "No firmwares available." + } + t := table.New() + t.SetHeader("Board", "FQBN", "Module", "Version") + for _, fw := range f { + t.AddRow(fw.BoardName, fw.BoardFQBN, fw.Module, fw.FirmwareVersion) + } + return t.Render() +} + +func (f FirmwareListResult) Data() interface{} { + return f } diff --git a/go.sum b/go.sum index 18f29d48..17f0714a 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,7 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fluxio/iohelpers v0.0.0-20160419043813-3a4dd67a94d2/go.mod h1:c7sGIpDbBo0JZZ1tKyC1p5smWf8QcUjK4bFtZjHAecg= github.com/fluxio/multierror v0.0.0-20160419044231-9c68d39025e5/go.mod h1:BEUDl7FG1cc76sM0J0x8dqr6RhiL4uqvk6oFkwuNyuM=