Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Improve limactl edit #2593

Merged
merged 1 commit into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 46 additions & 15 deletions cmd/limactl/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"

"github.com/lima-vm/lima/cmd/limactl/editflags"
"github.com/lima-vm/lima/cmd/limactl/guessarg"
"github.com/lima-vm/lima/pkg/editutil"
"github.com/lima-vm/lima/pkg/instance"
"github.com/lima-vm/lima/pkg/limayaml"
Expand All @@ -22,8 +23,8 @@ import (

func newEditCommand() *cobra.Command {
editCommand := &cobra.Command{
Use: "edit INSTANCE",
Short: "Edit an instance of Lima",
Use: "edit INSTANCE|FILE.yaml",
Short: "Edit an instance of Lima or a template",
Args: WrapArgsError(cobra.MaximumNArgs(1)),
RunE: editAction,
ValidArgsFunction: editBashComplete,
Expand All @@ -34,24 +35,43 @@ func newEditCommand() *cobra.Command {
}

func editAction(cmd *cobra.Command, args []string) error {
instName := DefaultInstanceName
var arg string
if len(args) > 0 {
instName = args[0]
arg = args[0]
}

inst, err := store.Inspect(instName)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("instance %q not found", instName)
var filePath string
var err error
var inst *store.Instance
switch {
case guessarg.SeemsYAMLPath(arg):
// absolute path is required for `limayaml.Validate`
filePath, err = filepath.Abs(arg)
if err != nil {
return err
}
default:
var instName string
if arg != "" {
instName = arg
} else {
instName = DefaultInstanceName
}
return err
}

if inst.Status == store.StatusRunning {
return errors.New("cannot edit a running instance")
inst, err = store.Inspect(instName)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return fmt.Errorf("instance %q not found", instName)
}
return err
}

if inst.Status == store.StatusRunning {
return errors.New("cannot edit a running instance")
}
filePath = filepath.Join(inst.Dir, filenames.LimaYAML)
}

filePath := filepath.Join(inst.Dir, filenames.LimaYAML)
yContent, err := os.ReadFile(filePath)
if err != nil {
return err
Expand All @@ -73,7 +93,12 @@ func editAction(cmd *cobra.Command, args []string) error {
return err
}
} else if tty {
hdr := fmt.Sprintf("# Please edit the following configuration for Lima instance %q\n", instName)
var hdr string
if inst != nil {
hdr = fmt.Sprintf("# Please edit the following configuration for Lima instance %q\n", inst.Name)
} else {
hdr = fmt.Sprintf("# Please edit the following configuration %q\n", filePath)
}
hdr += "# and an empty file will abort the edit.\n"
hdr += "\n"
hdr += editutil.GenerateEditorWarningHeader()
Expand Down Expand Up @@ -105,12 +130,18 @@ func editAction(cmd *cobra.Command, args []string) error {
if err := os.WriteFile(filePath, yBytes, 0o644); err != nil {
return err
}
logrus.Infof("Instance %q configuration edited", instName)
if inst != nil {
logrus.Infof("Instance %q configuration edited", inst.Name)
}

if !tty {
// use "start" to start it
return nil
}
if inst == nil {
// edited a limayaml file directly
return nil
}
startNow, err := askWhetherToStart()
if err != nil {
return err
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ require (
github.com/foxcpp/go-mockdns v1.1.0
github.com/goccy/go-yaml v1.12.0
github.com/google/go-cmp v0.6.0
github.com/google/yamlfmt v0.13.0
github.com/lima-vm/go-qcow2reader v0.1.2
github.com/lima-vm/sshocker v0.3.4
github.com/mattn/go-isatty v0.0.20
Expand Down Expand Up @@ -58,6 +59,8 @@ require (
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/a8m/envsubst v1.4.2 // indirect
github.com/alecthomas/participle/v2 v2.1.1 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect
github.com/braydonk/yaml v0.7.0 // indirect
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge fan of importing multiple YAML libraries

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the fifth YAML library?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, is this the first time a YAML library forked from https://github.com/go-yaml/yaml is being added?

This comment was marked as off-topic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to express my gratitude to Go for allowing the use of both a forked library and the original library simultaneously without causing issues. 👏🏻

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think both of yqlib and yamlfmt brings enough value, to be allowed to bring-their-own-yaml to the party

github.com/containerd/errdefs v0.1.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/digitalocean/go-libvirt v0.0.0-20220804181439-8648fbde413e // indirect
Expand Down Expand Up @@ -95,6 +98,7 @@ require (
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
Expand All @@ -104,6 +108,7 @@ require (
github.com/pkg/sftp v1.13.6 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/yuin/gopher-lua v1.1.1 // indirect
Expand Down
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/Y
github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a/go.mod h1:QmP9hvJ91BbJmGVGSbutW19IC0Q9phDCLGaomwTJbgU=
github.com/balajiv113/fd v0.0.0-20230330094840-143eec500f3e h1:IdMhFPEfTZQU971tIHx3UhY4l+yCeynprnINrDTSrOc=
github.com/balajiv113/fd v0.0.0-20230330094840-143eec500f3e/go.mod h1:aXGMJsd3XrnUFTuyf/pTGg5jG6CY8JMZ5juywvShjgQ=
github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/braydonk/yaml v0.7.0 h1:ySkqO7r0MGoCNhiRJqE0Xe9yhINMyvOAB3nFjgyJn2k=
github.com/braydonk/yaml v0.7.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4=
github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk=
github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI=
github.com/containerd/containerd v1.7.22 h1:nZuNnNRA6T6jB975rx2RRNqqH2k6ELYKDZfqTHqwyy0=
Expand Down Expand Up @@ -123,6 +127,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/yamlfmt v0.13.0 h1:OS8cjQNhRhEP437e1axMgZiwrYu60mWLtvb4/jtQCtE=
github.com/google/yamlfmt v0.13.0/go.mod h1:y8JNH/2TqTaCSUjk/zhn0lYlibMvS0R+pbVUDo8oz9o=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
Expand Down Expand Up @@ -192,6 +198,8 @@ github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
github.com/mikefarah/yq/v4 v4.44.3 h1:3zxHntH67maSHr6ynCjM44htw7LZNINmTzYn3tM2t+I=
github.com/mikefarah/yq/v4 v4.44.3/go.mod h1:1pm9sJoyZLDql3OqgklvRCkD0XIIHMZV38jKZgAuxwY=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down Expand Up @@ -234,6 +242,8 @@ github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
github.com/sirupsen/logrus v1.9.4-0.20230606125235-dd1b4c2e81af h1:Sp5TG9f7K39yfB+If0vjp97vuT74F72r8hfRpP8jLU0=
Expand Down
18 changes: 17 additions & 1 deletion pkg/yqutil/yqutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"strings"

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

return out.Bytes(), nil
return yamlfmt(out.Bytes())
}

func Join(yqExprs []string) string {
Expand All @@ -78,3 +79,18 @@ func Join(yqExprs []string) string {
}
return strings.Join(yqExprs, " | ")
}

func yamlfmt(content []byte) ([]byte, error) {
factory := basic.BasicFormatterFactory{}
config := map[string]interface{}{
"indentless_arrays": true,
"line_ending": "lf", // prefer LF even on Windows
"pad_line_comments": 2,
"retain_line_breaks": true, // does not affect to the output because yq removes empty lines before formatting
}
formatter, err := factory.NewFormatter(config)
if err != nil {
return nil, err
}
return formatter.Format(content)
}
13 changes: 7 additions & 6 deletions pkg/yqutil/yqutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,18 @@ mounts:
`
// Note: yq will use canonical yaml, with indented sequences
// Note: yq will not explicitly quote strings, when not needed
// Note: yamlfmt will fix indentation of sequences
expected := `
# Expose host directories to the guest, the mount point might be accessible from all UIDs in the guest
# 🟢 Builtin default: null (Mount nothing)
# 🔵 This file: Mount the home as read-only, /tmp/lima as writable
mounts:
- location: "~"
# Configure the mountPoint inside the guest.
# 🟢 Builtin default: value of location
mountPoint: null
- location: foo
mountPoint: bar
- location: "~"
# Configure the mountPoint inside the guest.
# 🟢 Builtin default: value of location
mountPoint: null
- location: foo
mountPoint: bar
`
out, err := EvaluateExpression(expression, []byte(content))
assert.NilError(t, err)
Expand Down
Loading