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

Commit23b1c2d

Browse files
authored
fix(cli/cliui): handle typed nil and null time in tables (#15984)
1 parentca96e67 commit23b1c2d

File tree

2 files changed

+52
-28
lines changed

2 files changed

+52
-28
lines changed

‎cli/cliui/table.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"github.com/fatih/structtag"
1010
"github.com/jedib0t/go-pretty/v6/table"
1111
"golang.org/x/xerrors"
12+
13+
"github.com/coder/coder/v2/codersdk"
1214
)
1315

1416
// Table creates a new table with standardized styles.
@@ -195,6 +197,12 @@ func renderTable(out any, sort string, headers table.Row, filterColumns []string
195197
ifval!=nil {
196198
v=val.Format(time.RFC3339)
197199
}
200+
case codersdk.NullTime:
201+
ifval.Valid {
202+
v=val.Time.Format(time.RFC3339)
203+
}else {
204+
v=nil
205+
}
198206
case*int64:
199207
ifval!=nil {
200208
v=*val
@@ -204,8 +212,13 @@ func renderTable(out any, sort string, headers table.Row, filterColumns []string
204212
v=val.String()
205213
}
206214
case fmt.Stringer:
207-
ifval!=nil {
215+
// Protect against typed nils since fmt.Stringer is an interface.
216+
vv:=reflect.ValueOf(v)
217+
nilPtr:=vv.Kind()==reflect.Ptr&&vv.IsNil()
218+
ifval!=nil&&!nilPtr {
208219
v=val.String()
220+
}elseifnilPtr {
221+
v=nil
209222
}
210223
}
211224

‎cli/cliui/table_test.go

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cliui_test
22

33
import (
4+
"database/sql"
45
"fmt"
56
"log"
67
"strings"
@@ -11,6 +12,7 @@ import (
1112
"github.com/stretchr/testify/require"
1213

1314
"github.com/coder/coder/v2/cli/cliui"
15+
"github.com/coder/coder/v2/codersdk"
1416
)
1517

1618
typestringWrapperstruct {
@@ -24,18 +26,20 @@ func (s stringWrapper) String() string {
2426
}
2527

2628
typetableTest1struct {
27-
Namestring`table:"name,default_sort"`
28-
NotIncludedstring// no table tag
29-
Ageint`table:"age"`
30-
Roles []string`table:"roles"`
31-
Sub1tableTest2`table:"sub_1,recursive"`
32-
Sub2*tableTest2`table:"sub_2,recursive"`
33-
Sub3tableTest3`table:"sub 3,recursive"`
34-
Sub4tableTest2`table:"sub 4"`// not recursive
29+
Namestring`table:"name,default_sort"`
30+
AltName*stringWrapper`table:"alt_name"`
31+
NotIncludedstring// no table tag
32+
Ageint`table:"age"`
33+
Roles []string`table:"roles"`
34+
Sub1tableTest2`table:"sub_1,recursive"`
35+
Sub2*tableTest2`table:"sub_2,recursive"`
36+
Sub3tableTest3`table:"sub 3,recursive"`
37+
Sub4tableTest2`table:"sub 4"`// not recursive
3538

3639
// Types with special formatting.
37-
Time time.Time`table:"time"`
38-
TimePtr*time.Time`table:"time_ptr"`
40+
Time time.Time`table:"time"`
41+
TimePtr*time.Time`table:"time_ptr"`
42+
NullTime codersdk.NullTime`table:"null_time"`
3943
}
4044

4145
typetableTest2struct {
@@ -62,9 +66,10 @@ func Test_DisplayTable(t *testing.T) {
6266
// Not sorted by name or age to test sorting.
6367
in:= []tableTest1{
6468
{
65-
Name:"bar",
66-
Age:20,
67-
Roles: []string{"a"},
69+
Name:"bar",
70+
AltName:&stringWrapper{str:"bar alt"},
71+
Age:20,
72+
Roles: []string{"a"},
6873
Sub1:tableTest2{
6974
Name:stringWrapper{str:"bar1"},
7075
Age:21,
@@ -82,6 +87,12 @@ func Test_DisplayTable(t *testing.T) {
8287
},
8388
Time:someTime,
8489
TimePtr:nil,
90+
NullTime: codersdk.NullTime{
91+
NullTime: sql.NullTime{
92+
Time:someTime,
93+
Valid:true,
94+
},
95+
},
8596
},
8697
{
8798
Name:"foo",
@@ -138,10 +149,10 @@ func Test_DisplayTable(t *testing.T) {
138149
t.Parallel()
139150

140151
expected:=`
141-
NAME AGE ROLES SUB 1 NAME SUB 1 AGE SUB 2 NAME SUB 2 AGE SUB 3 INNER NAME SUB 3 INNER AGE SUB 4 TIME TIME PTR
142-
bar20 [a] bar1 21 <nil> <nil> bar3 23 {bar4 24 } 2022-08-02T15:49:10Z <nil>
143-
baz30 [] baz1 31 <nil> <nil> baz3 33 {baz4 34 } 2022-08-02T15:49:10Z <nil>
144-
foo10 [a, b, c] foo1 11 foo2 12 foo3 13 {foo4 14 } 2022-08-02T15:49:10Z 2022-08-02T15:49:10Z
152+
NAMEALT NAMEAGE ROLES SUB 1 NAME SUB 1 AGE SUB 2 NAME SUB 2 AGE SUB 3 INNER NAME SUB 3 INNER AGE SUB 4 TIME TIME PTR NULL TIME
153+
barbar alt20 [a] bar1 21 <nil> <nil> bar3 23 {bar4 24 } 2022-08-02T15:49:10Z <nil> 2022-08-02T15:49:10Z
154+
baz<nil>30 [] baz1 31 <nil> <nil> baz3 33 {baz4 34 } 2022-08-02T15:49:10Z <nil> <nil>
155+
foo<nil>10 [a, b, c] foo1 11 foo2 12 foo3 13 {foo4 14 } 2022-08-02T15:49:10Z 2022-08-02T15:49:10Z <nil>
145156
`
146157

147158
// Test with non-pointer values.
@@ -165,10 +176,10 @@ foo 10 [a, b, c] foo1 11 foo2 12 foo3
165176
t.Parallel()
166177

167178
expected:=`
168-
NAME AGE ROLES SUB 1 NAME SUB 1 AGE SUB 2 NAME SUB 2 AGE SUB 3 INNER NAME SUB 3 INNER AGE SUB 4 TIME TIME PTR
169-
foo10 [a, b, c] foo1 11 foo2 12 foo3 13 {foo4 14 } 2022-08-02T15:49:10Z 2022-08-02T15:49:10Z
170-
bar20 [a] bar1 21 <nil> <nil> bar3 23 {bar4 24 } 2022-08-02T15:49:10Z <nil>
171-
baz30 [] baz1 31 <nil> <nil> baz3 33 {baz4 34 } 2022-08-02T15:49:10Z <nil>
179+
NAMEALT NAMEAGE ROLES SUB 1 NAME SUB 1 AGE SUB 2 NAME SUB 2 AGE SUB 3 INNER NAME SUB 3 INNER AGE SUB 4 TIME TIME PTR NULL TIME
180+
foo<nil>10 [a, b, c] foo1 11 foo2 12 foo3 13 {foo4 14 } 2022-08-02T15:49:10Z 2022-08-02T15:49:10Z <nil>
181+
barbar alt20 [a] bar1 21 <nil> <nil> bar3 23 {bar4 24 } 2022-08-02T15:49:10Z <nil> 2022-08-02T15:49:10Z
182+
baz<nil>30 [] baz1 31 <nil> <nil> baz3 33 {baz4 34 } 2022-08-02T15:49:10Z <nil> <nil>
172183
`
173184

174185
out,err:=cliui.DisplayTable(in,"age",nil)
@@ -235,12 +246,12 @@ Alice 25
235246
t.Run("WithSeparator",func(t*testing.T) {
236247
t.Parallel()
237248
expected:=`
238-
NAME AGE ROLES SUB 1 NAME SUB 1 AGE SUB 2 NAME SUB 2 AGE SUB 3 INNER NAME SUB 3 INNER AGE SUB 4 TIME TIME PTR
239-
bar20 [a] bar1 21 <nil> <nil> bar3 23 {bar4 24 } 2022-08-02T15:49:10Z <nil>
240-
---------------------------------------------------------------------------------------------------------------------------------------------------------------
241-
baz30 [] baz1 31 <nil> <nil> baz3 33 {baz4 34 } 2022-08-02T15:49:10Z <nil>
242-
---------------------------------------------------------------------------------------------------------------------------------------------------------------
243-
foo10 [a, b, c] foo1 11 foo2 12 foo3 13 {foo4 14 } 2022-08-02T15:49:10Z 2022-08-02T15:49:10Z
249+
NAMEALT NAMEAGE ROLES SUB 1 NAME SUB 1 AGE SUB 2 NAME SUB 2 AGE SUB 3 INNER NAME SUB 3 INNER AGE SUB 4 TIME TIME PTR NULL TIME
250+
barbar alt20 [a] bar1 21 <nil> <nil> bar3 23 {bar4 24 } 2022-08-02T15:49:10Z <nil> 2022-08-02T15:49:10Z
251+
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
252+
baz<nil>30 [] baz1 31 <nil> <nil> baz3 33 {baz4 34 } 2022-08-02T15:49:10Z <nil> <nil>
253+
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
254+
foo<nil>10 [a, b, c] foo1 11 foo2 12 foo3 13 {foo4 14 } 2022-08-02T15:49:10Z 2022-08-02T15:49:10Z <nil>
244255
`
245256

246257
varinlineIn []any

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp