4
4
package main
5
5
6
6
import (
7
+ "bufio"
8
+ "bytes"
7
9
"errors"
8
10
"fmt"
9
- "os"
10
11
"reflect"
11
12
"sort"
12
13
"strings"
13
14
14
15
"github.com/cheggaaa/pb/v3/termutil"
15
- "github.com/mattn/go-isatty "
16
+ "github.com/mikefarah/yq/v4/pkg/yqlib "
16
17
"github.com/sirupsen/logrus"
17
18
"github.com/spf13/cobra"
18
19
19
20
"github.com/lima-vm/lima/v2/pkg/limatype"
20
21
"github.com/lima-vm/lima/v2/pkg/store"
22
+ "github.com/lima-vm/lima/v2/pkg/uiutil"
23
+ "github.com/lima-vm/lima/v2/pkg/yqutil"
21
24
)
22
25
23
26
func fieldNames () []string {
@@ -64,6 +67,7 @@ The following legacy flags continue to function:
64
67
listCommand .Flags ().Bool ("json" , false , "JSONify output" )
65
68
listCommand .Flags ().BoolP ("quiet" , "q" , false , "Only show names" )
66
69
listCommand .Flags ().Bool ("all-fields" , false , "Show all fields" )
70
+ listCommand .Flags ().String ("yq" , "" , "Apply yq expression to each instance" )
67
71
68
72
return listCommand
69
73
}
@@ -109,6 +113,10 @@ func listAction(cmd *cobra.Command, args []string) error {
109
113
if err != nil {
110
114
return err
111
115
}
116
+ yq , err := cmd .Flags ().GetString ("yq" )
117
+ if err != nil {
118
+ return err
119
+ }
112
120
113
121
if jsonFormat {
114
122
format = "json"
@@ -121,6 +129,14 @@ func listAction(cmd *cobra.Command, args []string) error {
121
129
if listFields && cmd .Flags ().Changed ("format" ) {
122
130
return errors .New ("option --list-fields conflicts with option --format" )
123
131
}
132
+ if yq != "" {
133
+ if cmd .Flags ().Changed ("format" ) && format != "json" && format != "yaml" {
134
+ return errors .New ("option --yq only works with --format json or yaml" )
135
+ }
136
+ if listFields {
137
+ return errors .New ("option --list-fields conflicts with option --yq" )
138
+ }
139
+ }
124
140
125
141
if quiet && format != "table" {
126
142
return errors .New ("option --quiet can only be used with '--format table'" )
@@ -194,16 +210,80 @@ func listAction(cmd *cobra.Command, args []string) error {
194
210
}
195
211
196
212
options := store.PrintOptions {AllFields : allFields }
197
- out := cmd .OutOrStdout ()
198
- if out == os .Stdout {
199
- if isatty .IsTerminal (os .Stdout .Fd ()) || isatty .IsCygwinTerminal (os .Stdout .Fd ()) {
200
- if w , err := termutil .TerminalWidth (); err == nil {
201
- options .TerminalWidth = w
213
+ isTTY := uiutil .OutputIsTTY (cmd .OutOrStdout ())
214
+ if isTTY {
215
+ if w , err := termutil .TerminalWidth (); err == nil {
216
+ options .TerminalWidth = w
217
+ }
218
+ }
219
+ // --yq implies --format json unless --format yaml has been explicitly specified
220
+ if yq != "" && ! cmd .Flags ().Changed ("format" ) {
221
+ format = "json"
222
+ }
223
+ // Always pipe JSON and YAML through yq to colorize it if isTTY
224
+ if yq == "" && (format == "json" || format == "yaml" ) {
225
+ yq = "."
226
+ }
227
+
228
+ if yq == "" {
229
+ err = store .PrintInstances (cmd .OutOrStdout (), instances , format , & options )
230
+ if err == nil && unmatchedInstances {
231
+ return unmatchedInstancesError {}
232
+ }
233
+ return err
234
+ }
235
+
236
+ buf := new (bytes.Buffer )
237
+ err = store .PrintInstances (buf , instances , format , & options )
238
+ if err != nil {
239
+ return err
240
+ }
241
+
242
+ if format == "json" {
243
+ encoderPrefs := yqlib .ConfiguredJSONPreferences .Copy ()
244
+ if isTTY {
245
+ // Using non-0 indent means the instance will be printed over multiple lines,
246
+ // so is no longer in JSON Lines format. This is a compromise for readability.
247
+ encoderPrefs .Indent = 4
248
+ encoderPrefs .ColorsEnabled = true
249
+ } else {
250
+ encoderPrefs .Indent = 0
251
+ encoderPrefs .ColorsEnabled = false
252
+ }
253
+ encoder := yqlib .NewJSONEncoder (encoderPrefs )
254
+
255
+ // Each line contains the JSON object for one Lima instance.
256
+ scanner := bufio .NewScanner (buf )
257
+ for scanner .Scan () {
258
+ var str string
259
+ if str , err = yqutil .EvaluateExpressionWithEncoder (yq , scanner .Text (), encoder ); err != nil {
260
+ return err
202
261
}
262
+ if _ , err = fmt .Fprint (cmd .OutOrStdout (), str ); err != nil {
263
+ return err
264
+ }
265
+ }
266
+ err = scanner .Err ()
267
+ if err == nil && unmatchedInstances {
268
+ return unmatchedInstancesError {}
203
269
}
270
+ return err
204
271
}
205
272
206
- err = store .PrintInstances (out , instances , format , & options )
273
+ var str string
274
+ if isTTY {
275
+ // This branch is trading the better formatting from yamlfmt for colorizing from yqlib.
276
+ if str , err = yqutil .EvaluateExpressionPlain (yq , buf .String (), true ); err != nil {
277
+ return err
278
+ }
279
+ } else {
280
+ var res []byte
281
+ if res , err = yqutil .EvaluateExpression (yq , buf .Bytes ()); err != nil {
282
+ return err
283
+ }
284
+ str = string (res )
285
+ }
286
+ _ , err = fmt .Fprint (cmd .OutOrStdout (), str )
207
287
if err == nil && unmatchedInstances {
208
288
return unmatchedInstancesError {}
209
289
}
0 commit comments