Skip to content

Commit bc6508a

Browse files
committed
Hide identical columns in the list command
If all the instances have the same type or arch, then don't display the column - unless requested. Only hide the arch if it is the same as host arch. Emulated instances all show their arch by default. Signed-off-by: Anders F Björklund <[email protected]>
1 parent e4ede4f commit bc6508a

File tree

3 files changed

+154
-7
lines changed

3 files changed

+154
-7
lines changed

cmd/limactl/list.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func newListCommand() *cobra.Command {
5454
listCommand.Flags().Bool("list-fields", false, "List fields available for format")
5555
listCommand.Flags().Bool("json", false, "JSONify output")
5656
listCommand.Flags().BoolP("quiet", "q", false, "Only show names")
57+
listCommand.Flags().Bool("all-fields", false, "Show all fields")
5758

5859
return listCommand
5960
}
@@ -155,7 +156,14 @@ func listAction(cmd *cobra.Command, args []string) error {
155156
}
156157
}
157158

158-
return store.PrintInstances(cmd.OutOrStdout(), instances, format)
159+
allFields, err := cmd.Flags().GetBool("all-fields")
160+
if err != nil {
161+
return err
162+
}
163+
164+
options := store.PrintOptions{AllFields: allFields}
165+
out := cmd.OutOrStdout()
166+
return store.PrintInstances(out, instances, format, &options)
159167
}
160168

161169
func listBashComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {

pkg/store/instance.go

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,17 +232,48 @@ func AddGlobalFields(inst *Instance) (FormatData, error) {
232232
return data, nil
233233
}
234234

235+
type PrintOptions struct {
236+
AllFields bool
237+
}
238+
235239
// PrintInstances prints instances in a requested format to a given io.Writer.
236240
// Supported formats are "json", "yaml", "table", or a go template
237-
func PrintInstances(w io.Writer, instances []*Instance, format string) error {
241+
func PrintInstances(w io.Writer, instances []*Instance, format string, options *PrintOptions) error {
238242
switch format {
239243
case "json":
240244
format = "{{json .}}"
241245
case "yaml":
242246
format = "{{yaml .}}"
243247
case "table":
248+
types := map[string]int{}
249+
archs := map[string]int{}
250+
for _, instance := range instances {
251+
types[instance.VMType]++
252+
archs[instance.Arch]++
253+
}
254+
all := options != nil && options.AllFields
255+
hideType := false
256+
hideArch := false
257+
hideDir := false
258+
259+
hideType = len(types) == 1 && !all
260+
// only hide arch if it is the same as the host arch
261+
goarch := limayaml.NewArch(runtime.GOARCH)
262+
hideArch = len(archs) == 1 && instances[0].Arch == goarch && !all
263+
244264
w := tabwriter.NewWriter(w, 4, 8, 4, ' ', 0)
245-
fmt.Fprintln(w, "NAME\tSTATUS\tSSH\tVMTYPE\tARCH\tCPUS\tMEMORY\tDISK\tDIR")
265+
fmt.Fprint(w, "NAME\tSTATUS\tSSH")
266+
if !hideType {
267+
fmt.Fprint(w, "\tVMTYPE")
268+
}
269+
if !hideArch {
270+
fmt.Fprint(w, "\tARCH")
271+
}
272+
fmt.Fprint(w, "\tCPUS\tMEMORY\tDISK")
273+
if !hideDir {
274+
fmt.Fprint(w, "\tDIR")
275+
}
276+
fmt.Fprintln(w)
246277

247278
u, err := user.Current()
248279
if err != nil {
@@ -255,17 +286,33 @@ func PrintInstances(w io.Writer, instances []*Instance, format string) error {
255286
if strings.HasPrefix(dir, homeDir) {
256287
dir = strings.Replace(dir, homeDir, "~", 1)
257288
}
258-
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%d\t%s\t%s\t%s\n",
289+
fmt.Fprintf(w, "%s\t%s\t%s",
259290
instance.Name,
260291
instance.Status,
261292
fmt.Sprintf("127.0.0.1:%d", instance.SSHLocalPort),
262-
instance.VMType,
263-
instance.Arch,
293+
)
294+
if !hideType {
295+
fmt.Fprintf(w, "\t%s",
296+
instance.VMType,
297+
)
298+
}
299+
if !hideArch {
300+
fmt.Fprintf(w, "\t%s",
301+
instance.Arch,
302+
)
303+
}
304+
fmt.Fprintf(w, "\t%d\t%s\t%s",
264305
instance.CPUs,
265306
units.BytesSize(float64(instance.Memory)),
266307
units.BytesSize(float64(instance.Disk)),
267-
dir,
268308
)
309+
if !hideDir {
310+
fmt.Fprintf(w, "\t%s",
311+
dir,
312+
)
313+
}
314+
fmt.Fprint(w, "\n")
315+
269316
}
270317
return w.Flush()
271318
default:

pkg/store/instance_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package store
2+
3+
import (
4+
"bytes"
5+
"os/user"
6+
"path/filepath"
7+
"runtime"
8+
"testing"
9+
10+
"github.com/lima-vm/lima/pkg/limayaml"
11+
"gotest.tools/v3/assert"
12+
)
13+
14+
const separator = string(filepath.Separator)
15+
16+
var vmtype = limayaml.QEMU
17+
var goarch = limayaml.NewArch(runtime.GOARCH)
18+
19+
var instance = Instance{
20+
Name: "foo",
21+
Status: StatusStopped,
22+
VMType: vmtype,
23+
Arch: goarch,
24+
Dir: "dir",
25+
}
26+
27+
var table = "NAME STATUS SSH CPUS MEMORY DISK DIR\n" +
28+
"foo Stopped 127.0.0.1:0 0 0B 0B dir\n"
29+
30+
var tableEmu = "NAME STATUS SSH ARCH CPUS MEMORY DISK DIR\n" +
31+
"foo Stopped 127.0.0.1:0 unknown 0 0B 0B dir\n"
32+
33+
var tableHome = "NAME STATUS SSH CPUS MEMORY DISK DIR\n" +
34+
"foo Stopped 127.0.0.1:0 0 0B 0B ~" + separator + "dir\n"
35+
36+
var tableAll = "NAME STATUS SSH VMTYPE ARCH CPUS MEMORY DISK DIR\n" +
37+
"foo Stopped 127.0.0.1:0 " + vmtype + " " + goarch + " 0 0B 0B dir\n"
38+
39+
var tableTwo = "NAME STATUS SSH VMTYPE ARCH CPUS MEMORY DISK DIR\n" +
40+
"foo Stopped 127.0.0.1:0 qemu x86_64 0 0B 0B dir\n" +
41+
"bar Stopped 127.0.0.1:0 vz aarch64 0 0B 0B dir\n"
42+
43+
func TestPrintInstanceTable(t *testing.T) {
44+
var buf bytes.Buffer
45+
instances := []*Instance{&instance}
46+
PrintInstances(&buf, instances, "table", nil)
47+
assert.Equal(t, table, buf.String())
48+
}
49+
50+
func TestPrintInstanceTableEmu(t *testing.T) {
51+
var buf bytes.Buffer
52+
instance1 := instance
53+
instance1.Arch = "unknown"
54+
instances := []*Instance{&instance1}
55+
PrintInstances(&buf, instances, "table", nil)
56+
assert.Equal(t, tableEmu, buf.String())
57+
}
58+
59+
func TestPrintInstanceTableHome(t *testing.T) {
60+
var buf bytes.Buffer
61+
u, err := user.Current()
62+
assert.NilError(t, err)
63+
instance1 := instance
64+
instance1.Dir = filepath.Join(u.HomeDir, "dir")
65+
instances := []*Instance{&instance1}
66+
PrintInstances(&buf, instances, "table", nil)
67+
assert.Equal(t, tableHome, buf.String())
68+
}
69+
70+
func TestPrintInstanceTableAll(t *testing.T) {
71+
var buf bytes.Buffer
72+
instances := []*Instance{&instance}
73+
options := PrintOptions{AllFields: true}
74+
PrintInstances(&buf, instances, "table", &options)
75+
assert.Equal(t, tableAll, buf.String())
76+
}
77+
78+
func TestPrintInstanceTableTwo(t *testing.T) {
79+
var buf bytes.Buffer
80+
instance1 := instance
81+
instance1.Name = "foo"
82+
instance1.VMType = limayaml.QEMU
83+
instance1.Arch = limayaml.X8664
84+
instance2 := instance
85+
instance2.Name = "bar"
86+
instance2.VMType = limayaml.VZ
87+
instance2.Arch = limayaml.AARCH64
88+
instances := []*Instance{&instance1, &instance2}
89+
options := PrintOptions{}
90+
PrintInstances(&buf, instances, "table", &options)
91+
assert.Equal(t, tableTwo, buf.String())
92+
}

0 commit comments

Comments
 (0)