@@ -18,23 +18,23 @@ package version
1818import (
1919 "encoding/json"
2020 "fmt"
21- "io"
2221 "net"
2322 "net/http"
2423 "net/url"
24+ "strings"
2525 "time"
2626
2727 "github.com/spf13/cobra"
2828
2929 "github.com/arduino/arduino-app-cli/cmd/feedback"
30- "github.com/arduino/arduino-app-cli/cmd/i18n"
3130)
3231
3332// The actual listening address for the daemon
3433// is defined in the installation package
3534const (
3635 DefaultHostname = "localhost"
3736 DefaultPort = "8800"
37+ ProgramName = "Arduino App CLI"
3838)
3939
4040func NewVersionCmd (clientVersion string ) * cobra.Command {
@@ -44,104 +44,103 @@ func NewVersionCmd(clientVersion string) *cobra.Command {
4444 Run : func (cmd * cobra.Command , args []string ) {
4545 host , _ := cmd .Flags ().GetString ("host" )
4646
47- versionHandler (clientVersion , host )
47+ validatedHostAndPort , err := validateHost (host )
48+ if err != nil {
49+ feedback .Fatal ("Error: invalid host:port format" , feedback .ErrBadArgument )
50+ }
51+
52+ httpClient := http.Client {
53+ Timeout : time .Second ,
54+ }
55+
56+ result , err := versionHandler (httpClient , clientVersion , validatedHostAndPort )
57+ if err != nil {
58+ feedback .Warnf ("Waning: " + err .Error () + "\n " )
59+ }
60+ feedback .PrintResult (result )
4861 },
4962 }
5063 cmd .Flags ().String ("host" , fmt .Sprintf ("%s:%s" , DefaultHostname , DefaultPort ),
5164 "The daemon network address [host]:[port]" )
5265 return cmd
5366}
5467
55- func versionHandler (clientVersion string , host string ) {
56- httpClient := http.Client {
57- Timeout : time .Second ,
68+ func versionHandler (httpClient http.Client , clientVersion string , hostAndPort string ) (versionResult , error ) {
69+ url := url.URL {
70+ Scheme : "http" ,
71+ Host : hostAndPort ,
72+ Path : "/v1/version" ,
5873 }
59- result := doVersionHandler (httpClient , clientVersion , host )
60- feedback .PrintResult (result )
61- }
6274
63- func doVersionHandler (httpClient http.Client , clientVersion string , host string ) versionResult {
64- url , err := getValidOrDefaultUrl (host )
65- if err != nil {
66- feedback .Fatal (i18n .Tr ("Error: invalid host:port format" ), feedback .ErrBadArgument )
67- }
75+ daemonVersion := getServerVersion (httpClient , url .String ())
6876
69- serverVersion , err := getServerVersion (httpClient , url )
70- if err != nil {
71- serverVersion = fmt .Sprintf ("n/a (cannot connect to the server %s://%s)" , url .Scheme , url .Host )
77+ result := versionResult {
78+ Name : ProgramName ,
79+ ClientVersion : clientVersion ,
80+ DaemonVersion : daemonVersion ,
7281 }
7382
74- return versionResult {
75- ClientVersion : clientVersion ,
76- ServerVersion : serverVersion ,
83+ if daemonVersion == "" {
84+ return result , fmt .Errorf ("cannot connect to %s" , hostAndPort )
7785 }
86+ return result , nil
7887}
7988
80- func getValidOrDefaultUrl (hostPort string ) (url.URL , error ) {
81- host := DefaultHostname
82- port := DefaultPort
83-
84- if hostPort != "" {
85- h , p , err := net .SplitHostPort (hostPort )
86- if err != nil {
87- return url.URL {}, err
88- }
89- if h != "" {
90- host = h
91- }
92- if p != "" {
93- port = p
94- }
95-
89+ func validateHost (hostPort string ) (string , error ) {
90+ if ! strings .Contains (hostPort , ":" ) {
91+ hostPort = hostPort + ":"
9692 }
9793
98- hostAndPort := net .JoinHostPort (host , port )
99-
100- u := url.URL {
101- Scheme : "http" ,
102- Host : hostAndPort ,
103- Path : "/v1/version" ,
94+ h , p , err := net .SplitHostPort (hostPort )
95+ if err != nil {
96+ return "" , err
97+ }
98+ if h == "" {
99+ h = DefaultHostname
100+ }
101+ if p == "" {
102+ p = DefaultPort
104103 }
105104
106- return u , nil
105+ return net . JoinHostPort ( h , p ) , nil
107106}
108107
109- func getServerVersion (httpClient http.Client , url url. URL ) ( string , error ) {
110- resp , err := httpClient .Get (url . String () )
108+ func getServerVersion (httpClient http.Client , url string ) string {
109+ resp , err := httpClient .Get (url )
111110 if err != nil {
112- return "" , err
111+ return ""
113112 }
114113 defer resp .Body .Close ()
115114
116115 if resp .StatusCode != http .StatusOK {
117- return "" , fmt . Errorf ( "request failed with status %d" , resp . StatusCode )
116+ return ""
118117 }
119118
120- body , err := io .ReadAll (resp .Body )
121- if err != nil {
122- return "" , err
119+ var serverResponse struct {
120+ Version string `json:"version"`
123121 }
124-
125- var serverResponse serverVersionResponse
126- if err := json .Unmarshal (body , & serverResponse ); err != nil {
127- return "" , err
122+ if err := json .NewDecoder (resp .Body ).Decode (& serverResponse ); err != nil {
123+ return ""
128124 }
129125
130- return serverResponse .Version , nil
131- }
132-
133- type serverVersionResponse struct {
134- Version string `json:"version"`
126+ return serverResponse .Version
135127}
136128
137129type versionResult struct {
138- ClientVersion string `json:"version"`
139- ServerVersion string `json:"serverVersion"`
130+ Name string `json:"name"`
131+ ClientVersion string `json:"client_version"`
132+ DaemonVersion string `json:"daemon_version,omitempty"`
140133}
141134
142135func (r versionResult ) String () string {
143- return fmt .Sprintf ("client: %s\n server: %s" ,
144- r .ClientVersion , r .ServerVersion )
136+ serverMessage := fmt .Sprintf ("%s client version %s" ,
137+ ProgramName , r .ClientVersion )
138+
139+ if r .DaemonVersion != "" {
140+ serverMessage = fmt .Sprintf ("%s\n daemon version: %s" ,
141+ serverMessage , r .DaemonVersion )
142+ }
143+ return serverMessage
145144}
146145
147146func (r versionResult ) Data () interface {} {
0 commit comments