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
This repository was archived by the owner on Aug 30, 2024. It is now read-only.
/coder-v1-cliPublic archive

Commit87c708a

Browse files
authored
Merge pull request#77 from cdr/users
Add users ls command
2 parents433da04 +5e43b71 commit87c708a

File tree

9 files changed

+142
-7
lines changed

9 files changed

+142
-7
lines changed

‎ci/integration/integration_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package integration
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"os"
78
"os/exec"
@@ -11,6 +12,8 @@ import (
1112
"time"
1213

1314
"cdr.dev/coder-cli/ci/tcli"
15+
"cdr.dev/coder-cli/internal/entclient"
16+
"cdr.dev/slog"
1417
"cdr.dev/slog/sloggers/slogtest/assert"
1518
)
1619

@@ -110,6 +113,19 @@ func TestCoderCLI(t *testing.T) {
110113
tcli.Error(),
111114
)
112115

116+
varuser entclient.User
117+
c.Run(ctx,`coder users ls -o json | jq -c '.[] | select( .username == "charlie")'`).Assert(t,
118+
tcli.Success(),
119+
jsonUnmarshals(&user),
120+
)
121+
assert.Equal(t,"user email is as expected","charlie@coder.com",user.Email)
122+
assert.Equal(t,"username is as expected","Charlie",user.Name)
123+
124+
c.Run(ctx,"coder users ls -o human | grep charlie").Assert(t,
125+
tcli.Success(),
126+
tcli.StdoutMatches("charlie"),
127+
)
128+
113129
c.Run(ctx,"coder logout").Assert(t,
114130
tcli.Success(),
115131
)
@@ -118,3 +134,11 @@ func TestCoderCLI(t *testing.T) {
118134
tcli.Error(),
119135
)
120136
}
137+
138+
funcjsonUnmarshals(targetinterface{}) tcli.Assertion {
139+
returnfunc(t*testing.T,r*tcli.CommandResult) {
140+
slog.Helper()
141+
err:=json.Unmarshal(r.Stdout,target)
142+
assert.Success(t,"json unmarshals",err)
143+
}
144+
}

‎cmd/coder/envs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type envsCmd struct {
1414
func (cmdenvsCmd)Spec() cli.CommandSpec {
1515
return cli.CommandSpec{
1616
Name:"envs",
17-
Desc:"get a list ofactive environment",
17+
Desc:"get a list ofenvironments owned by the authenticated user",
1818
}
1919
}
2020

‎cmd/coder/logout.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type logoutCmd struct {
1717
func (cmdlogoutCmd)Spec() cli.CommandSpec {
1818
return cli.CommandSpec{
1919
Name:"logout",
20-
Desc:"remote local authentication credentials (if any)",
20+
Desc:"remove local authentication credentials (if any)",
2121
}
2222
}
2323

‎cmd/coder/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func (r *rootCmd) Subcommands() []cli.Command {
4242
&urlsCmd{},
4343
&versionCmd{},
4444
&configSSHCmd{},
45+
&usersCmd{},
4546
}
4647
}
4748

‎cmd/coder/shell.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func (cmd *shellCmd) Spec() cli.CommandSpec {
2727
return cli.CommandSpec{
2828
Name:"sh",
2929
Usage:"<env name> [<command [args...]>]",
30-
Desc:"executes a remote command on the environment\nIf no command is specified, the default shell is opened.",
30+
Desc:"execute a remote command on the environment\nIf no command is specified, the default shell is opened.",
3131
RawArgs:true,
3232
}
3333
}

‎cmd/coder/users.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"os"
7+
"reflect"
8+
"strings"
9+
"text/tabwriter"
10+
11+
"github.com/spf13/pflag"
12+
13+
"go.coder.com/cli"
14+
"go.coder.com/flog"
15+
)
16+
17+
typeusersCmdstruct {
18+
}
19+
20+
func (cmdusersCmd)Spec() cli.CommandSpec {
21+
return cli.CommandSpec{
22+
Name:"users",
23+
Usage:"[subcommand] <flags>",
24+
Desc:"interact with user accounts",
25+
}
26+
}
27+
28+
func (cmdusersCmd)Run(fl*pflag.FlagSet) {
29+
exitUsage(fl)
30+
}
31+
32+
func (cmd*usersCmd)Subcommands() []cli.Command {
33+
return []cli.Command{
34+
&listCmd{},
35+
}
36+
}
37+
38+
typelistCmdstruct {
39+
outputFmtstring
40+
}
41+
42+
functabDelimited(datainterface{})string {
43+
v:=reflect.ValueOf(data)
44+
s:=&strings.Builder{}
45+
fori:=0;i<v.NumField();i++ {
46+
s.WriteString(fmt.Sprintf("%s\t",v.Field(i).Interface()))
47+
}
48+
returns.String()
49+
}
50+
51+
func (cmd*listCmd)Run(fl*pflag.FlagSet) {
52+
entClient:=requireAuth()
53+
54+
users,err:=entClient.Users()
55+
iferr!=nil {
56+
flog.Fatal("failed to get users: %v",err)
57+
}
58+
59+
switchcmd.outputFmt {
60+
case"human":
61+
w:=tabwriter.NewWriter(os.Stdout,0,0,3,' ',0)
62+
for_,u:=rangeusers {
63+
_,err=fmt.Fprintln(w,tabDelimited(u))
64+
iferr!=nil {
65+
flog.Fatal("failed to write: %v",err)
66+
}
67+
}
68+
err=w.Flush()
69+
iferr!=nil {
70+
flog.Fatal("failed to flush writer: %v",err)
71+
}
72+
case"json":
73+
err=json.NewEncoder(os.Stdout).Encode(users)
74+
iferr!=nil {
75+
flog.Fatal("failed to encode users to json: %v",err)
76+
}
77+
default:
78+
exitUsage(fl)
79+
}
80+
81+
}
82+
83+
func (cmd*listCmd)RegisterFlags(fl*pflag.FlagSet) {
84+
fl.StringVarP(&cmd.outputFmt,"output","o","human","output format (human | json)")
85+
}
86+
87+
func (cmd*listCmd)Spec() cli.CommandSpec {
88+
return cli.CommandSpec{
89+
Name:"ls",
90+
Usage:"<flags>",
91+
Desc:"list all users",
92+
}
93+
}

‎cmd/coder/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ func (versionCmd) Spec() cli.CommandSpec {
1515
return cli.CommandSpec{
1616
Name:"version",
1717
Usage:"",
18-
Desc:"Print the currently installed CLI version",
18+
Desc:"print the currently installed CLI version",
1919
}
2020
}
2121

‎internal/entclient/me.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package entclient
22

3+
import (
4+
"time"
5+
)
6+
37
// User describes a Coder user account
48
typeUserstruct {
5-
IDstring`json:"id"`
6-
Emailstring`json:"email"`
7-
Usernamestring`json:"username"`
9+
IDstring`json:"id"`
10+
Emailstring`json:"email"`
11+
Usernamestring`json:"username"`
12+
Namestring`json:"name"`
13+
CreatedAt time.Time`json:"created_at"`
814
}
915

1016
// Me gets the details of the authenticated user

‎internal/entclient/users.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package entclient
2+
3+
// Users gets the list of user accounts
4+
func (cClient)Users() ([]User,error) {
5+
varu []User
6+
err:=c.requestBody("GET","/api/users",nil,&u)
7+
iferr!=nil {
8+
returnnil,err
9+
}
10+
returnu,nil
11+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp