Skip to content

Commit

Permalink
yqutil: use yamlfmt to fix indentation of sequence
Browse files Browse the repository at this point in the history
Signed-off-by: Norio Nomura <norio.nomura@gmail.com>

`limactl edit`: support editing lima.yaml file

This allows `limactl edit --set "..." <limayaml>` to be used instead of `yq -i eval "..." <limayaml>` in scripts like `hack/inject-cmdline-to-template.sh`.

Signed-off-by: Norio Nomura <norio.nomura@gmail.com>

yqutil: Use `LF` for line endings regardless of the platform.

Signed-off-by: Norio Nomura <norio.nomura@gmail.com>

`limactl edit`: update command description

Signed-off-by: Norio Nomura <norio.nomura@gmail.com>

yqutil_test: fix typo

Signed-off-by: Norio Nomura <norio.nomura@gmail.com>
  • Loading branch information
norio-nomura committed Sep 14, 2024
1 parent 4ad8139 commit a10a8bb
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 22 deletions.
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
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

0 comments on commit a10a8bb

Please sign in to comment.