44package main
55
66import (
7+ "bufio"
8+ "bytes"
79 "errors"
810 "fmt"
9- "os"
1011 "reflect"
1112 "sort"
1213 "strings"
1314
1415 "github.com/cheggaaa/pb/v3/termutil"
15- "github.com/mattn/go-isatty "
16+ "github.com/mikefarah/yq/v4/pkg/yqlib "
1617 "github.com/sirupsen/logrus"
1718 "github.com/spf13/cobra"
1819
1920 "github.com/lima-vm/lima/v2/pkg/limatype"
2021 "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"
2124)
2225
2326func fieldNames () []string {
@@ -64,6 +67,7 @@ The following legacy flags continue to function:
6467 listCommand .Flags ().Bool ("json" , false , "JSONify output" )
6568 listCommand .Flags ().BoolP ("quiet" , "q" , false , "Only show names" )
6669 listCommand .Flags ().Bool ("all-fields" , false , "Show all fields" )
70+ listCommand .Flags ().String ("yq" , "" , "Apply yq expression to each instance" )
6771
6872 return listCommand
6973}
@@ -109,6 +113,10 @@ func listAction(cmd *cobra.Command, args []string) error {
109113 if err != nil {
110114 return err
111115 }
116+ yq , err := cmd .Flags ().GetString ("yq" )
117+ if err != nil {
118+ return err
119+ }
112120
113121 if jsonFormat {
114122 format = "json"
@@ -121,6 +129,14 @@ func listAction(cmd *cobra.Command, args []string) error {
121129 if listFields && cmd .Flags ().Changed ("format" ) {
122130 return errors .New ("option --list-fields conflicts with option --format" )
123131 }
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+ }
124140
125141 if quiet && format != "table" {
126142 return errors .New ("option --quiet can only be used with '--format table'" )
@@ -194,16 +210,80 @@ func listAction(cmd *cobra.Command, args []string) error {
194210 }
195211
196212 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
202261 }
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 {}
203269 }
270+ return err
204271 }
205272
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 )
207287 if err == nil && unmatchedInstances {
208288 return unmatchedInstancesError {}
209289 }
0 commit comments