Replace olekukonko/tablewriter with cheynewallace/tabby

- Closes #1497
- Closes #1498

This library is simpler and doesn't produce extraneous whitespace around
the output.

A local helper function restores "--" for empty output.

Signed-off-by: Jonathon Anderson <janderson@ciq.com>
This commit is contained in:
Jonathon Anderson
2024-11-07 16:17:40 -07:00
parent 3cbb295e7b
commit a8554b0af5
11 changed files with 194 additions and 168 deletions

View File

@@ -4,7 +4,8 @@ import (
"strings"
"github.com/spf13/cobra"
"github.com/warewulf/warewulf/internal/app/wwctl/helper"
"github.com/warewulf/warewulf/internal/app/wwctl/table"
apinode "github.com/warewulf/warewulf/internal/pkg/api/node"
"github.com/warewulf/warewulf/internal/pkg/api/routes/wwapiv1"
"github.com/warewulf/warewulf/internal/pkg/wwlog"
@@ -38,12 +39,12 @@ func CobraRunE(vars *variables) func(cmd *cobra.Command, args []string) (err err
if req.Type == wwapiv1.GetNodeList_YAML || req.Type == wwapiv1.GetNodeList_JSON {
wwlog.Info(nodeInfo.Output[0])
} else {
ph := helper.New(strings.Split(nodeInfo.Output[0], ":=:"))
t := table.New(cmd.OutOrStdout())
t.AddHeader(table.Prep(strings.Split(nodeInfo.Output[0], ":=:"))...)
for _, val := range nodeInfo.Output[1:] {
ph.Append(strings.Split(val, ":=:"))
t.AddLine(table.Prep(strings.Split(val, ":=:"))...)
}
ph.Render()
wwlog.Info("%s", ph.String())
t.Print()
}
}
return

View File

@@ -28,8 +28,10 @@ func Test_List(t *testing.T) {
name: "single node list",
args: []string{},
wantErr: false,
stdout: ` NODE NAME PROFILES NETWORK
n01 [default]
stdout: `
NODE NAME PROFILES NETWORK
--------- -------- -------
n01 [default] --
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -44,9 +46,11 @@ nodes:
name: "multiple nodes list",
args: []string{},
wantErr: false,
stdout: ` NODE NAME PROFILES NETWORK
n01 [default]
n02 [default]
stdout: `
NODE NAME PROFILES NETWORK
--------- -------- -------
n01 [default] --
n02 [default] --
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -64,9 +68,11 @@ nodes:
name: "node list returns multiple nodes",
args: []string{"n01,n02"},
wantErr: false,
stdout: ` NODE NAME PROFILES NETWORK
n01 [default]
n02 [default]
stdout: `
NODE NAME PROFILES NETWORK
--------- -------- -------
n01 [default] --
n02 [default] --
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -84,9 +90,11 @@ nodes:
name: "node list returns multiple nodes (case 2)",
args: []string{"n01,n03"},
wantErr: false,
stdout: ` NODE NAME PROFILES NETWORK
n01 [default]
n03 [default]
stdout: `
NODE NAME PROFILES NETWORK
--------- -------- -------
n01 [default] --
n03 [default] --
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -113,8 +121,10 @@ nodes:
name: "node list returns one node",
args: []string{"n01,"},
wantErr: false,
stdout: ` NODE NAME PROFILES NETWORK
n01 [default]
stdout: `
NODE NAME PROFILES NETWORK
--------- -------- -------
n01 [default] --
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -132,8 +142,10 @@ nodes:
name: "node list profile with network",
args: []string{},
wantErr: false,
stdout: ` NODE NAME PROFILES NETWORK
n01 [default] default
stdout: `
NODE NAME PROFILES NETWORK
--------- -------- -------
n01 [default] default
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -150,9 +162,11 @@ nodes:
name: "node list profile with comment",
args: []string{"-a"},
wantErr: false,
stdout: ` NODE FIELD PROFILE VALUE
n01 Comment default profilecomment
n01 Profiles default
stdout: `
NODE FIELD PROFILE VALUE
---- ----- ------- -----
n01 Comment default profilecomment
n01 Profiles -- default
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -167,9 +181,11 @@ nodes:
name: "node list profile with comment superseded",
args: []string{"-a"},
wantErr: false,
stdout: ` NODE FIELD PROFILE VALUE
n01 Comment SUPERSEDED nodecomment
n01 Profiles default
stdout: `
NODE FIELD PROFILE VALUE
---- ----- ------- -----
n01 Comment SUPERSEDED nodecomment
n01 Profiles -- default
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -185,8 +201,10 @@ nodes:
name: "node list profile with ipmi user",
args: []string{"-i"},
wantErr: false,
stdout: ` NODE IPMI IPADDR IPMI PORT IPMI USERNAME IPMI INTERFACE
n01 <nil> admin
stdout: `
NODE IPMI IPADDR IPMI PORT IPMI USERNAME IPMI INTERFACE
---- ----------- --------- ------------- --------------
n01 <nil> -- admin --
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -202,8 +220,10 @@ nodes:
name: "node list profile with ipmi user superseded",
args: []string{"-i"},
wantErr: false,
stdout: ` NODE IPMI IPADDR IPMI PORT IPMI USERNAME IPMI INTERFACE
n01 <nil> user
stdout: `
NODE IPMI IPADDR IPMI PORT IPMI USERNAME IPMI INTERFACE
---- ----------- --------- ------------- --------------
n01 <nil> -- user --
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -221,8 +241,10 @@ nodes:
name: "multiple profiles list",
args: []string{},
wantErr: false,
stdout: ` NODE NAME PROFILES NETWORK
n01 [p1 p2]
stdout: `
NODE NAME PROFILES NETWORK
--------- -------- -------
n01 [p1 p2] --
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -238,8 +260,10 @@ nodes:
name: "multiple profiles list all",
args: []string{"-a"},
wantErr: false,
stdout: ` NODE FIELD PROFILE VALUE
n01 Profiles p1,p2
stdout: `
NODE FIELD PROFILE VALUE
---- ----- ------- -----
n01 Profiles -- p1,p2
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -255,8 +279,10 @@ nodes:
name: "multiple overlays list long with negation",
args: []string{"-l"},
wantErr: false,
stdout: ` NODE NAME KERNEL OVERRIDE CONTAINER OVERLAYS (S/R)
n01 /rop1,rop2
stdout: `
NODE NAME KERNEL OVERRIDE CONTAINER OVERLAYS (S/R)
--------- --------------- --------- --------------
n01 -- -- /rop1,rop2
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -273,8 +299,10 @@ nodes:
name: "multiple overlays list long",
args: []string{"-l"},
wantErr: false,
stdout: ` NODE NAME KERNEL OVERRIDE CONTAINER OVERLAYS (S/R)
n01 sop1/nop1,~rop1,rop1,rop2
stdout: `
NODE NAME KERNEL OVERRIDE CONTAINER OVERLAYS (S/R)
--------- --------------- --------- --------------
n01 -- -- sop1/nop1,~rop1,rop1,rop2
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -296,10 +324,12 @@ nodes:
name: "multiple overlays list all with negation",
args: []string{"-a"},
wantErr: false,
stdout: ` NODE FIELD PROFILE VALUE
n01 Profiles p1
n01 RuntimeOverlay p1+ nop1,~rop1,rop1,rop2
n01 SystemOverlay p1 sop1
stdout: `
NODE FIELD PROFILE VALUE
---- ----- ------- -----
n01 Profiles -- p1
n01 RuntimeOverlay p1+ nop1,~rop1,rop1,rop2
n01 SystemOverlay p1 sop1
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -321,9 +351,11 @@ nodes:
name: "multiple overlays list all",
args: []string{"-a"},
wantErr: false,
stdout: ` NODE FIELD PROFILE VALUE
n01 Profiles p1
n01 RuntimeOverlay p1+ nop1,rop1,rop2
stdout: `
NODE FIELD PROFILE VALUE
---- ----- ------- -----
n01 Profiles -- p1
n01 RuntimeOverlay p1+ nop1,rop1,rop2
`,
inDb: `WW_INTERNAL: 45
nodeprofiles:
@@ -342,8 +374,10 @@ nodes:
name: "network onboot",
args: []string{"-a"},
wantErr: false,
stdout: ` NODE FIELD PROFILE VALUE
n1 NetDevs[default].OnBoot true
stdout: `
NODE FIELD PROFILE VALUE
---- ----- ------- -----
n1 NetDevs[default].OnBoot -- true
`,
inDb: `WW_INTERNAL: 45
nodes:
@@ -356,7 +390,9 @@ nodes:
name: "empty network device",
args: []string{"-a"},
wantErr: false,
stdout: ` NODE FIELD PROFILE VALUE
stdout: `
NODE FIELD PROFILE VALUE
---- ----- ------- -----
`,
inDb: `WW_INTERNAL: 46
nodes:
@@ -393,13 +429,14 @@ nodes:
baseCmd := GetCommand()
baseCmd.SetArgs(tt.args)
buf := new(bytes.Buffer)
baseCmd.SetOut(buf)
baseCmd.SetErr(buf)
wwlog.SetLogWriter(buf)
wwlog.SetLogWriterErr(buf)
wwlog.SetLogWriterInfo(buf)
err := baseCmd.Execute()
assert.NoError(t, err)
assert.NotEmpty(t, buf, "output should not be empty")
assert.Equal(t, tt.stdout, buf.String())
assert.Equal(t, strings.TrimSpace(tt.stdout), strings.TrimSpace(buf.String()))
})
}
@@ -492,9 +529,7 @@ nodes:
} else {
assert.NoError(t, err)
}
assert.Contains(t,
strings.Join(strings.Fields(tt.stdout), ""),
strings.Join(strings.Fields(buf.String()), ""))
assert.Equal(t, strings.TrimSpace(buf.String()), strings.TrimSpace(tt.stdout))
})
}
}