Skip to content

yqutil: fix to preserve line breaks #2625

New issue

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

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

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ jobs:
run: make
- name: Install
run: sudo make install
- name: Verify templates match `limactl edit` format
run: |
find examples -name '*.yaml' -exec limactl edit --set 'del(.nothing)' {} \;
git diff-index --exit-code HEAD
- name: Uninstall
run: sudo make uninstall

Expand Down
10 changes: 5 additions & 5 deletions examples/buildkit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
# $ export BUILDKIT_HOST=$(limactl list buildkit --format 'unix://{{.Dir}}/sock/buildkitd.sock')
# $ buildctl debug workers
message: |
To run `buildkit` on the host (assumes buildctl is installed), run the following commands:
-------
export BUILDKIT_HOST="unix://{{.Dir}}/sock/buildkitd.sock"
buildctl debug workers
-------
To run `buildkit` on the host (assumes buildctl is installed), run the following commands:
-------
export BUILDKIT_HOST="unix://{{.Dir}}/sock/buildkitd.sock"
buildctl debug workers
-------
images:
# Try to use release-yyyyMMdd image if available. Note that release-yyyyMMdd will be removed after several months.
- location: "https://cloud-images.ubuntu.com/releases/24.04/release-20240821/ubuntu-24.04-server-cloudimg-amd64.img"
Expand Down
12 changes: 6 additions & 6 deletions examples/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,10 @@ containerd:
# Setting of instructions is supported like this: "qemu64,+ssse3".
# 🟢 Builtin default: hard-coded arch map with type (see the output of `limactl info | jq .defaultTemplate.cpuType`)
cpuType:
# aarch64: "cortex-a72" # (or "host" when running on aarch64 host)
# armv7l: "cortex-a7" # (or "host" when running on armv7l host)
# riscv64: "rv64" # (or "host" when running on riscv64 host)
# x86_64: "qemu64" # (or "host,-pdpe1gb" when running on x86_64 host)
# aarch64: "cortex-a72" # (or "host" when running on aarch64 host)
# armv7l: "cortex-a7" # (or "host" when running on armv7l host)
# riscv64: "rv64" # (or "host" when running on riscv64 host)
# x86_64: "qemu64" # (or "host,-pdpe1gb" when running on x86_64 host)

rosetta:
# Enable Rosetta for Linux (EXPERIMENTAL; will graduate from experimental in Lima v1.0).
Expand Down Expand Up @@ -456,8 +456,8 @@ hostResolver:
# predefined to specify the gateway address to the host.
# 🟢 Builtin default: null
hosts:
# guest.name: 127.1.1.1
# host.name: host.lima.internal
# guest.name: 127.1.1.1
# host.name: host.lima.internal

# If hostResolver.enabled is false, then the following rules apply for configuring dns:
# Explicitly set DNS addresses for qemu user-mode networking. By default qemu picks *one*
Expand Down
45 changes: 44 additions & 1 deletion pkg/yqutil/yqutil.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package yqutil

import (
"bufio"
"bytes"
"fmt"
"os"
Expand All @@ -15,13 +16,17 @@ import (
// EvaluateExpression evaluates the yq expression, and returns the modified yaml.
func EvaluateExpression(expression string, content []byte) ([]byte, error) {
logrus.Debugf("Evaluating yq expression: %q", expression)
contentModified, err := replaceLineBreaksWithMagicString(content)
if err != nil {
return nil, err
}
tmpYAMLFile, err := os.CreateTemp("", "lima-yq-*.yaml")
if err != nil {
return nil, err
}
tmpYAMLPath := tmpYAMLFile.Name()
defer os.RemoveAll(tmpYAMLPath)
Copy link
Member

Choose a reason for hiding this comment

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

I know this is not part of this PR, but why is this calling os.RemoveAll() instead of os.Remove() given that tmpYAMLPath is a file and not a directory.

@afbjorklund Do you remember why you choose RemoveAll?

_, err = tmpYAMLFile.Write(content)
_, err = tmpYAMLFile.Write(contentModified)
if err != nil {
tmpYAMLFile.Close()
return nil, err
Expand Down Expand Up @@ -94,3 +99,41 @@ func yamlfmt(content []byte) ([]byte, error) {
}
return formatter.Format(content)
}

const yamlfmtLineBreakPlaceholder = "#magic___^_^___line"

type paddinger struct {
strings.Builder
}

func (p *paddinger) adjust(txt string) {
var indentSize int
for i := 0; i < len(txt) && txt[i] == ' '; i++ { // yaml only allows space to indent.
indentSize++
}
// Grows if the given size is larger than us and always return the max padding.
for diff := indentSize - p.Len(); diff > 0; diff-- {
p.WriteByte(' ')
}
}

func replaceLineBreaksWithMagicString(content []byte) ([]byte, error) {
// hotfix: yq does not support line breaks in the middle of a string.
var buf bytes.Buffer
reader := bytes.NewReader(content)
scanner := bufio.NewScanner(reader)
var padding paddinger
for scanner.Scan() {
txt := scanner.Text()
padding.adjust(txt)
if strings.TrimSpace(txt) == "" { // line break or empty space line.
buf.WriteString(padding.String()) // prepend some padding incase literal multiline strings.
buf.WriteString(yamlfmtLineBreakPlaceholder)
buf.WriteString("\n")
} else {
buf.WriteString(txt)
buf.WriteString("\n")
}
}
return buf.Bytes(), scanner.Err()
}
1 change: 1 addition & 0 deletions pkg/yqutil/yqutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ memory: null
expected := `
# CPUs
cpus: 2

# Memory size
memory: 2GiB
`
Expand Down
Loading