Skip to content

Commit 133979a

Browse files
authored
Merge pull request #2593 from norio-nomura/improve-limactl-edit
Improve `limactl edit`
2 parents 4ad8139 + a10a8bb commit 133979a

File tree

5 files changed

+85
-22
lines changed

5 files changed

+85
-22
lines changed

cmd/limactl/edit.go

+46-15
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"path/filepath"
99

1010
"github.com/lima-vm/lima/cmd/limactl/editflags"
11+
"github.com/lima-vm/lima/cmd/limactl/guessarg"
1112
"github.com/lima-vm/lima/pkg/editutil"
1213
"github.com/lima-vm/lima/pkg/instance"
1314
"github.com/lima-vm/lima/pkg/limayaml"
@@ -22,8 +23,8 @@ import (
2223

2324
func newEditCommand() *cobra.Command {
2425
editCommand := &cobra.Command{
25-
Use: "edit INSTANCE",
26-
Short: "Edit an instance of Lima",
26+
Use: "edit INSTANCE|FILE.yaml",
27+
Short: "Edit an instance of Lima or a template",
2728
Args: WrapArgsError(cobra.MaximumNArgs(1)),
2829
RunE: editAction,
2930
ValidArgsFunction: editBashComplete,
@@ -34,24 +35,43 @@ func newEditCommand() *cobra.Command {
3435
}
3536

3637
func editAction(cmd *cobra.Command, args []string) error {
37-
instName := DefaultInstanceName
38+
var arg string
3839
if len(args) > 0 {
39-
instName = args[0]
40+
arg = args[0]
4041
}
4142

42-
inst, err := store.Inspect(instName)
43-
if err != nil {
44-
if errors.Is(err, os.ErrNotExist) {
45-
return fmt.Errorf("instance %q not found", instName)
43+
var filePath string
44+
var err error
45+
var inst *store.Instance
46+
switch {
47+
case guessarg.SeemsYAMLPath(arg):
48+
// absolute path is required for `limayaml.Validate`
49+
filePath, err = filepath.Abs(arg)
50+
if err != nil {
51+
return err
52+
}
53+
default:
54+
var instName string
55+
if arg != "" {
56+
instName = arg
57+
} else {
58+
instName = DefaultInstanceName
4659
}
47-
return err
48-
}
4960

50-
if inst.Status == store.StatusRunning {
51-
return errors.New("cannot edit a running instance")
61+
inst, err = store.Inspect(instName)
62+
if err != nil {
63+
if errors.Is(err, os.ErrNotExist) {
64+
return fmt.Errorf("instance %q not found", instName)
65+
}
66+
return err
67+
}
68+
69+
if inst.Status == store.StatusRunning {
70+
return errors.New("cannot edit a running instance")
71+
}
72+
filePath = filepath.Join(inst.Dir, filenames.LimaYAML)
5273
}
5374

54-
filePath := filepath.Join(inst.Dir, filenames.LimaYAML)
5575
yContent, err := os.ReadFile(filePath)
5676
if err != nil {
5777
return err
@@ -73,7 +93,12 @@ func editAction(cmd *cobra.Command, args []string) error {
7393
return err
7494
}
7595
} else if tty {
76-
hdr := fmt.Sprintf("# Please edit the following configuration for Lima instance %q\n", instName)
96+
var hdr string
97+
if inst != nil {
98+
hdr = fmt.Sprintf("# Please edit the following configuration for Lima instance %q\n", inst.Name)
99+
} else {
100+
hdr = fmt.Sprintf("# Please edit the following configuration %q\n", filePath)
101+
}
77102
hdr += "# and an empty file will abort the edit.\n"
78103
hdr += "\n"
79104
hdr += editutil.GenerateEditorWarningHeader()
@@ -105,12 +130,18 @@ func editAction(cmd *cobra.Command, args []string) error {
105130
if err := os.WriteFile(filePath, yBytes, 0o644); err != nil {
106131
return err
107132
}
108-
logrus.Infof("Instance %q configuration edited", instName)
133+
if inst != nil {
134+
logrus.Infof("Instance %q configuration edited", inst.Name)
135+
}
109136

110137
if !tty {
111138
// use "start" to start it
112139
return nil
113140
}
141+
if inst == nil {
142+
// edited a limayaml file directly
143+
return nil
144+
}
114145
startNow, err := askWhetherToStart()
115146
if err != nil {
116147
return err

go.mod

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ require (
2323
github.com/foxcpp/go-mockdns v1.1.0
2424
github.com/goccy/go-yaml v1.12.0
2525
github.com/google/go-cmp v0.6.0
26+
github.com/google/yamlfmt v0.13.0
2627
github.com/lima-vm/go-qcow2reader v0.1.2
2728
github.com/lima-vm/sshocker v0.3.4
2829
github.com/mattn/go-isatty v0.0.20
@@ -58,6 +59,8 @@ require (
5859
github.com/VividCortex/ewma v1.2.0 // indirect
5960
github.com/a8m/envsubst v1.4.2 // indirect
6061
github.com/alecthomas/participle/v2 v2.1.1 // indirect
62+
github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect
63+
github.com/braydonk/yaml v0.7.0 // indirect
6164
github.com/containerd/errdefs v0.1.0 // indirect
6265
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
6366
github.com/digitalocean/go-libvirt v0.0.0-20220804181439-8648fbde413e // indirect
@@ -95,6 +98,7 @@ require (
9598
github.com/mattn/go-runewidth v0.0.15 // indirect
9699
github.com/mdlayher/socket v0.4.1 // indirect
97100
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
101+
github.com/mitchellh/mapstructure v1.5.0 // indirect
98102
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
99103
github.com/modern-go/reflect2 v1.0.2 // indirect
100104
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
@@ -104,6 +108,7 @@ require (
104108
github.com/pkg/sftp v1.13.6 // indirect
105109
github.com/rivo/uniseg v0.2.0 // indirect
106110
github.com/russross/blackfriday/v2 v2.1.0 // indirect
111+
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
107112
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
108113
github.com/x448/float16 v0.8.4 // indirect
109114
github.com/yuin/gopher-lua v1.1.1 // indirect

go.sum

+10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/Y
2525
github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
2626
github.com/balajiv113/fd v0.0.0-20230330094840-143eec500f3e h1:IdMhFPEfTZQU971tIHx3UhY4l+yCeynprnINrDTSrOc=
2727
github.com/balajiv113/fd v0.0.0-20230330094840-143eec500f3e/go.mod h1:aXGMJsd3XrnUFTuyf/pTGg5jG6CY8JMZ5juywvShjgQ=
28+
github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
29+
github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
30+
github.com/braydonk/yaml v0.7.0 h1:ySkqO7r0MGoCNhiRJqE0Xe9yhINMyvOAB3nFjgyJn2k=
31+
github.com/braydonk/yaml v0.7.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4=
2832
github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk=
2933
github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI=
3034
github.com/containerd/containerd v1.7.22 h1:nZuNnNRA6T6jB975rx2RRNqqH2k6ELYKDZfqTHqwyy0=
@@ -123,6 +127,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU
123127
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
124128
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
125129
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
130+
github.com/google/yamlfmt v0.13.0 h1:OS8cjQNhRhEP437e1axMgZiwrYu60mWLtvb4/jtQCtE=
131+
github.com/google/yamlfmt v0.13.0/go.mod h1:y8JNH/2TqTaCSUjk/zhn0lYlibMvS0R+pbVUDo8oz9o=
126132
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
127133
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
128134
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
@@ -192,6 +198,8 @@ github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
192198
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
193199
github.com/mikefarah/yq/v4 v4.44.3 h1:3zxHntH67maSHr6ynCjM44htw7LZNINmTzYn3tM2t+I=
194200
github.com/mikefarah/yq/v4 v4.44.3/go.mod h1:1pm9sJoyZLDql3OqgklvRCkD0XIIHMZV38jKZgAuxwY=
201+
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
202+
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
195203
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
196204
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
197205
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -234,6 +242,8 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU
234242
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
235243
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
236244
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
245+
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
246+
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
237247
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
238248
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
239249
github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af h1:Sp5TG9f7K39yfB+If0vjp97vuT74F72r8hfRpP8jLU0=

pkg/yqutil/yqutil.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
"strings"
88

9+
"github.com/google/yamlfmt/formatters/basic"
910
"github.com/mikefarah/yq/v4/pkg/yqlib"
1011
"github.com/sirupsen/logrus"
1112
logging "gopkg.in/op/go-logging.v1"
@@ -69,7 +70,7 @@ func EvaluateExpression(expression string, content []byte) ([]byte, error) {
6970
return nil, err
7071
}
7172

72-
return out.Bytes(), nil
73+
return yamlfmt(out.Bytes())
7374
}
7475

7576
func Join(yqExprs []string) string {
@@ -78,3 +79,18 @@ func Join(yqExprs []string) string {
7879
}
7980
return strings.Join(yqExprs, " | ")
8081
}
82+
83+
func yamlfmt(content []byte) ([]byte, error) {
84+
factory := basic.BasicFormatterFactory{}
85+
config := map[string]interface{}{
86+
"indentless_arrays": true,
87+
"line_ending": "lf", // prefer LF even on Windows
88+
"pad_line_comments": 2,
89+
"retain_line_breaks": true, // does not affect to the output because yq removes empty lines before formatting
90+
}
91+
formatter, err := factory.NewFormatter(config)
92+
if err != nil {
93+
return nil, err
94+
}
95+
return formatter.Format(content)
96+
}

pkg/yqutil/yqutil_test.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,18 @@ mounts:
4141
`
4242
// Note: yq will use canonical yaml, with indented sequences
4343
// Note: yq will not explicitly quote strings, when not needed
44+
// Note: yamlfmt will fix indentation of sequences
4445
expected := `
4546
# Expose host directories to the guest, the mount point might be accessible from all UIDs in the guest
4647
# 🟢 Builtin default: null (Mount nothing)
4748
# 🔵 This file: Mount the home as read-only, /tmp/lima as writable
4849
mounts:
49-
- location: "~"
50-
# Configure the mountPoint inside the guest.
51-
# 🟢 Builtin default: value of location
52-
mountPoint: null
53-
- location: foo
54-
mountPoint: bar
50+
- location: "~"
51+
# Configure the mountPoint inside the guest.
52+
# 🟢 Builtin default: value of location
53+
mountPoint: null
54+
- location: foo
55+
mountPoint: bar
5556
`
5657
out, err := EvaluateExpression(expression, []byte(content))
5758
assert.NilError(t, err)

0 commit comments

Comments
 (0)