Skip to content

Commit 3a82156

Browse files
feat: add list command (#4)
* feat: add list command * add licence header * remove unused parameter --------- Co-authored-by: MatteoPologruto <109663225+MatteoPologruto@users.noreply.github.com>
1 parent 102a096 commit 3a82156

File tree

7 files changed

+140
-18
lines changed

7 files changed

+140
-18
lines changed

go.mod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ require (
66
github.com/arduino/go-paths-helper v1.14.0
77
github.com/arduino/go-windows-runas v1.0.1
88
github.com/codeclysm/extract/v4 v4.0.0
9+
github.com/jedib0t/go-pretty/v6 v6.6.8
910
github.com/leonelquinteros/gotext v1.7.2
1011
github.com/schollz/progressbar/v3 v3.18.0
1112
github.com/sirupsen/logrus v1.9.3
1213
github.com/spf13/cobra v1.9.1
13-
github.com/stretchr/testify v1.9.0
14+
github.com/stretchr/testify v1.10.0
1415
go.bug.st/cleanup v1.0.0
16+
go.bug.st/f v0.4.0
1517
)
1618

1719
require (
@@ -20,12 +22,14 @@ require (
2022
github.com/inconshreveable/mousetrap v1.1.0 // indirect
2123
github.com/juju/errors v1.0.0 // indirect
2224
github.com/klauspost/compress v1.18.0 // indirect
25+
github.com/mattn/go-runewidth v0.0.16 // indirect
2326
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
2427
github.com/pmezard/go-difflib v1.0.0 // indirect
2528
github.com/rivo/uniseg v0.4.7 // indirect
2629
github.com/spf13/pflag v1.0.7 // indirect
2730
github.com/ulikunitz/xz v0.5.12 // indirect
2831
golang.org/x/sys v0.36.0 // indirect
2932
golang.org/x/term v0.35.0 // indirect
33+
golang.org/x/text v0.22.0 // indirect
3034
gopkg.in/yaml.v3 v3.0.1 // indirect
3135
)

go.sum

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg=
1414
github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
1515
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
1616
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
17+
github.com/jedib0t/go-pretty/v6 v6.6.8 h1:JnnzQeRz2bACBobIaa/r+nqjvws4yEhcmaZ4n1QzsEc=
18+
github.com/jedib0t/go-pretty/v6 v6.6.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
1719
github.com/juju/errors v1.0.0 h1:yiq7kjCLll1BiaRuNY53MGI0+EQ3rF6GB+wvboZDefM=
1820
github.com/juju/errors v1.0.0/go.mod h1:B5x9thDqx0wIMH3+aLIMP9HjItInYWObRovoCFM5Qe8=
1921
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
@@ -30,6 +32,7 @@ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2Em
3032
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
3133
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
3234
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
35+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
3336
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
3437
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
3538
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -45,17 +48,21 @@ github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
4548
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
4649
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
4750
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
48-
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
49-
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
51+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
52+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
5053
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
5154
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
5255
go.bug.st/cleanup v1.0.0 h1:XVj1HZxkBXeq3gMT7ijWUpHyIC1j8XAoNSyQ06CskgA=
5356
go.bug.st/cleanup v1.0.0/go.mod h1:EqVmTg2IBk4znLbPD28xne3abjsJftMdqqJEjhn70bk=
57+
go.bug.st/f v0.4.0 h1:Vstqb950nMA+PhAlRxUw8QL1ntHy/gXHNyyzjkQLJ10=
58+
go.bug.st/f v0.4.0/go.mod h1:bMo23205ll7UW63KwO1ut5RdlJ9JK8RyEEr88CmOF5Y=
5459
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
5560
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
5661
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
5762
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
5863
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
64+
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
65+
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
5966
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
6067
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
6168
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

list.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// This file is part of arduino-flasher-cli.
2+
//
3+
// Copyright 2025 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-flasher-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to license@arduino.cc.
15+
16+
package main
17+
18+
import (
19+
"github.com/jedib0t/go-pretty/v6/table"
20+
"github.com/spf13/cobra"
21+
22+
"github.com/arduino/arduino-flasher-cli/feedback"
23+
"github.com/arduino/arduino-flasher-cli/i18n"
24+
"github.com/arduino/arduino-flasher-cli/tablestyle"
25+
"github.com/arduino/arduino-flasher-cli/updater"
26+
)
27+
28+
func newListCmd() *cobra.Command {
29+
cmd := &cobra.Command{
30+
Use: "list",
31+
Short: "List the available Linux images",
32+
Args: cobra.NoArgs,
33+
Run: func(cmd *cobra.Command, args []string) {
34+
runListCommand()
35+
},
36+
}
37+
return cmd
38+
}
39+
40+
func runListCommand() {
41+
client := updater.NewClient()
42+
43+
manifest, err := client.GetInfoManifest()
44+
if err != nil {
45+
feedback.Fatal(i18n.Tr("error retrieving the manifest: %v", err), feedback.ErrBadArgument)
46+
}
47+
48+
feedback.PrintResult(listResult{Latest: manifest.Latest, Releases: manifest.Releases})
49+
}
50+
51+
type listResult struct {
52+
Latest updater.Release `json:"latest"`
53+
Releases []updater.Release `json:"releases"`
54+
}
55+
56+
// Data implements Result interface
57+
func (lr listResult) Data() interface{} {
58+
return lr
59+
}
60+
61+
// String implements Result interface
62+
func (lr listResult) String() string {
63+
t := table.NewWriter()
64+
t.SetStyle(tablestyle.CustomCleanStyle)
65+
t.AppendHeader(table.Row{"VERSION", "LATEST"})
66+
67+
for i := len(lr.Releases) - 1; i >= 0; i-- {
68+
row := table.Row{lr.Releases[i].Version}
69+
if lr.Releases[i].Version == lr.Latest.Version {
70+
row = append(row, "✓")
71+
}
72+
t.AppendRow(row)
73+
}
74+
return t.Render()
75+
}

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func main() {
5151
rootCmd.AddCommand(
5252
newFlashCmd(),
5353
newInstallDriversCmd(),
54+
newListCmd(),
5455
&cobra.Command{
5556
Use: "version",
5657
Short: "Print the version number of Arduino Flasher CLI",

tablestyle/tablestyle.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// This file is part of arduino-flasher-cli.
2+
//
3+
// Copyright 2025 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-flasher-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to license@arduino.cc.
15+
16+
package tablestyle
17+
18+
import (
19+
"github.com/jedib0t/go-pretty/v6/table"
20+
"github.com/jedib0t/go-pretty/v6/text"
21+
)
22+
23+
var (
24+
CustomCleanStyle = table.Style{
25+
Name: "CustomClean",
26+
Box: table.BoxStyle{PaddingRight: " "},
27+
Format: table.FormatOptions{
28+
Footer: text.FormatUpper,
29+
Header: text.FormatUpper,
30+
Row: text.FormatDefault,
31+
RowAlign: text.AlignCenter,
32+
},
33+
Options: table.Options{
34+
DrawBorder: false,
35+
SeparateColumns: true,
36+
SeparateFooter: false,
37+
SeparateHeader: false,
38+
SeparateRows: false,
39+
},
40+
}
41+
)

updater/flasher.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package updater
1818
import (
1919
"context"
2020
"fmt"
21-
"net/url"
2221
"runtime"
2322
"strings"
2423

@@ -31,14 +30,7 @@ import (
3130

3231
func Flash(ctx context.Context, imagePath *paths.Path, version string, forceYes bool) error {
3332
if !imagePath.Exist() {
34-
updateURL := "https://downloads.arduino.cc"
35-
36-
parsedURL, err := url.Parse(updateURL)
37-
if err != nil {
38-
return fmt.Errorf("invalid UPDATE_URL: %v", err)
39-
}
40-
41-
client := NewClient(parsedURL, "debian-im/Stable")
33+
client := NewClient()
4234

4335
tempImagePath, err := DownloadAndExtract(client, version, func(target string) (bool, error) {
4436
feedback.Printf("Found Debian image version: %s", target)

updater/http_client.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@ import (
2323
"io"
2424
"net/http"
2525
"net/url"
26+
27+
"go.bug.st/f"
2628
)
2729

30+
var baseURL = f.Must(url.Parse("https://downloads.arduino.cc"))
31+
32+
const pathRelease = "debian-im/Stable"
33+
2834
// Client holds the base URL, command name, allows custom HTTP client, and optional headers.
2935
type Client struct {
30-
BaseURL *url.URL
31-
CmdName string
3236
HTTPClient HTTPDoer
3337
Headers map[string]string // Optional headers to add to each request
3438
}
@@ -56,10 +60,8 @@ func WithHTTPClient(client HTTPDoer) Option {
5660
}
5761

5862
// NewClient creates a new Client with optional configuration.
59-
func NewClient(baseURL *url.URL, cmdName string, opts ...Option) *Client {
63+
func NewClient(opts ...Option) *Client {
6064
c := &Client{
61-
BaseURL: baseURL,
62-
CmdName: cmdName,
6365
HTTPClient: http.DefaultClient,
6466
Headers: nil,
6567
}
@@ -78,7 +80,7 @@ func (c *Client) addHeaders(req *http.Request) {
7880

7981
// GetInfoManifest fetches and decodes the Debian images info.json.
8082
func (c *Client) GetInfoManifest() (Manifest, error) {
81-
manifestURL := c.BaseURL.JoinPath(c.CmdName, "info.json").String()
83+
manifestURL := baseURL.JoinPath(pathRelease, "info.json").String()
8284
req, err := http.NewRequest("GET", manifestURL, nil)
8385
if err != nil {
8486
return Manifest{}, fmt.Errorf("failed to create request: %w", err)

0 commit comments

Comments
 (0)