Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit00d468b

Browse files
authored
feat(cli): add --output={text,json} to version cmd (#7010)
* feat(cliui): add TextFormat* feat(cli): add --format={text,json} to version cmd
1 parent9c4ccd7 commit00d468b

File tree

7 files changed

+192
-33
lines changed

7 files changed

+192
-33
lines changed

‎cli/cliui/output.go‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cliui
33
import (
44
"context"
55
"encoding/json"
6+
"fmt"
67
"reflect"
78
"strings"
89

@@ -171,3 +172,23 @@ func (jsonFormat) Format(_ context.Context, data any) (string, error) {
171172

172173
returnstring(outBytes),nil
173174
}
175+
176+
typetextFormatstruct{}
177+
178+
var_OutputFormat=textFormat{}
179+
180+
// TextFormat is a formatter that just outputs unstructured text.
181+
// It uses fmt.Sprintf under the hood.
182+
funcTextFormat()OutputFormat {
183+
returntextFormat{}
184+
}
185+
186+
func (textFormat)ID()string {
187+
return"text"
188+
}
189+
190+
func (textFormat)AttachOptions(_*clibase.OptionSet) {}
191+
192+
func (textFormat)Format(_ context.Context,dataany) (string,error) {
193+
returnfmt.Sprintf("%s",data),nil
194+
}

‎cli/cliui/output_test.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ func Test_OutputFormatter(t *testing.T) {
5050
require.Panics(t,func() {
5151
cliui.NewOutputFormatter(cliui.JSONFormat())
5252
})
53+
require.NotPanics(t,func() {
54+
cliui.NewOutputFormatter(cliui.JSONFormat(),cliui.TextFormat())
55+
})
5356
})
5457

5558
t.Run("NoMissingFormatID",func(t*testing.T) {

‎cli/root.go‎

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func (r *RootCmd) Core() []*clibase.Cmd {
8282
r.templates(),
8383
r.users(),
8484
r.tokens(),
85-
r.version(),
85+
r.version(defaultVersionInfo),
8686

8787
// Workspace Commands
8888
r.configSSH(),
@@ -370,36 +370,6 @@ func LoggerFromContext(ctx context.Context) (slog.Logger, bool) {
370370
returnl,ok
371371
}
372372

373-
// version prints the coder version
374-
func (*RootCmd)version()*clibase.Cmd {
375-
return&clibase.Cmd{
376-
Use:"version",
377-
Short:"Show coder version",
378-
Handler:func(inv*clibase.Invocation)error {
379-
varstr strings.Builder
380-
_,_=str.WriteString("Coder ")
381-
ifbuildinfo.IsAGPL() {
382-
_,_=str.WriteString("(AGPL) ")
383-
}
384-
_,_=str.WriteString(buildinfo.Version())
385-
buildTime,valid:=buildinfo.Time()
386-
ifvalid {
387-
_,_=str.WriteString(" "+buildTime.Format(time.UnixDate))
388-
}
389-
_,_=str.WriteString("\r\n"+buildinfo.ExternalURL()+"\r\n\r\n")
390-
391-
ifbuildinfo.IsSlim() {
392-
_,_=str.WriteString(fmt.Sprintf("Slim build of Coder, does not support the %s subcommand.\n",cliui.Styles.Code.Render("server")))
393-
}else {
394-
_,_=str.WriteString(fmt.Sprintf("Full build of Coder, supports the %s subcommand.\n",cliui.Styles.Code.Render("server")))
395-
}
396-
397-
_,_=fmt.Fprint(inv.Stdout,str.String())
398-
returnnil
399-
},
400-
}
401-
}
402-
403373
funcisTest()bool {
404374
returnflag.Lookup("test.v")!=nil
405375
}
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
Usage: coder version
1+
Usage: coder version [flags]
22

33
Show coder version
44

5+
Options
6+
-o, --output string (default: text)
7+
Output format. Available formats: text, json.
8+
59
---
610
Run `coder --help` for a list of global options.

‎cli/version.go‎

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"time"
7+
8+
"github.com/coder/coder/buildinfo"
9+
"github.com/coder/coder/cli/clibase"
10+
"github.com/coder/coder/cli/cliui"
11+
)
12+
13+
// versionInfo wraps the stuff we get from buildinfo so that it's
14+
// easier to emit in different formats.
15+
typeversionInfostruct {
16+
Versionstring`json:"version"`
17+
BuildTime time.Time`json:"build_time"`
18+
ExternalURLstring`json:"external_url"`
19+
Slimbool`json:"slim"`
20+
AGPLbool`json:"agpl"`
21+
}
22+
23+
// String() implements Stringer
24+
func (viversionInfo)String()string {
25+
varstr strings.Builder
26+
_,_=str.WriteString("Coder ")
27+
ifvi.AGPL {
28+
_,_=str.WriteString("(AGPL) ")
29+
}
30+
_,_=str.WriteString(vi.Version)
31+
32+
if!vi.BuildTime.IsZero() {
33+
_,_=str.WriteString(" "+vi.BuildTime.Format(time.UnixDate))
34+
}
35+
_,_=str.WriteString("\r\n"+vi.ExternalURL+"\r\n\r\n")
36+
37+
ifvi.Slim {
38+
_,_=str.WriteString(fmt.Sprintf("Slim build of Coder, does not support the %s subcommand.",cliui.Styles.Code.Render("server")))
39+
}else {
40+
_,_=str.WriteString(fmt.Sprintf("Full build of Coder, supports the %s subcommand.",cliui.Styles.Code.Render("server")))
41+
}
42+
returnstr.String()
43+
}
44+
45+
funcdefaultVersionInfo()*versionInfo {
46+
buildTime,_:=buildinfo.Time()
47+
return&versionInfo{
48+
Version:buildinfo.Version(),
49+
BuildTime:buildTime,
50+
ExternalURL:buildinfo.ExternalURL(),
51+
Slim:buildinfo.IsSlim(),
52+
AGPL:buildinfo.IsAGPL(),
53+
}
54+
}
55+
56+
// version prints the coder version
57+
func (*RootCmd)version(versionInfofunc()*versionInfo)*clibase.Cmd {
58+
var (
59+
formatter=cliui.NewOutputFormatter(
60+
cliui.TextFormat(),
61+
cliui.JSONFormat(),
62+
)
63+
vi=versionInfo()
64+
)
65+
66+
cmd:=&clibase.Cmd{
67+
Use:"version",
68+
Short:"Show coder version",
69+
Options: clibase.OptionSet{},
70+
Handler:func(inv*clibase.Invocation)error {
71+
out,err:=formatter.Format(inv.Context(),vi)
72+
iferr!=nil {
73+
returnerr
74+
}
75+
76+
_,err=fmt.Fprintln(inv.Stdout,out)
77+
returnerr
78+
},
79+
}
80+
81+
formatter.AttachOptions(&cmd.Options)
82+
83+
returncmd
84+
}

‎cli/version_test.go‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package cli_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"strings"
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/coder/coder/cli/clitest"
12+
"github.com/coder/coder/testutil"
13+
)
14+
15+
funcTestVersion(t*testing.T) {
16+
t.Parallel()
17+
expectedText:=`Coder v0.0.0-devel
18+
https://github.com/coder/coder
19+
20+
Full build of Coder, supports the server subcommand.
21+
`
22+
expectedJSON:=`{
23+
"version": "v0.0.0-devel",
24+
"build_time": "0001-01-01T00:00:00Z",
25+
"external_url": "https://github.com/coder/coder",
26+
"slim": false,
27+
"agpl": false
28+
}
29+
`
30+
for_,tt:=range []struct {
31+
Namestring
32+
Args []string
33+
Expectedstring
34+
}{
35+
{
36+
Name:"Defaults to human-readable output",
37+
Args: []string{"version"},
38+
Expected:expectedText,
39+
},
40+
{
41+
Name:"JSON output",
42+
Args: []string{"version","--output=json"},
43+
Expected:expectedJSON,
44+
},
45+
{
46+
Name:"Text output",
47+
Args: []string{"version","--output=text"},
48+
Expected:expectedText,
49+
},
50+
} {
51+
tt:=tt
52+
t.Run(tt.Name,func(t*testing.T) {
53+
t.Parallel()
54+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitShort)
55+
t.Cleanup(cancel)
56+
inv,_:=clitest.New(t,tt.Args...)
57+
buf:=new(bytes.Buffer)
58+
inv.Stdout=buf
59+
err:=inv.WithContext(ctx).Run()
60+
require.NoError(t,err)
61+
actual:=buf.String()
62+
actual=strings.ReplaceAll(actual,"\r\n","\n")
63+
require.Equal(t,tt.Expected,actual)
64+
})
65+
}
66+
}

‎docs/cli/version.md‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,16 @@ Show coder version
77
##Usage
88

99
```console
10-
coder version
10+
coder version [flags]
1111
```
12+
13+
##Options
14+
15+
###-o, --output
16+
17+
|||
18+
| -------| -------------------|
19+
| Type| <code>string</code>|
20+
| Default| <code>text</code>|
21+
22+
Output format. Available formats: text, json.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp