yq/pkg/yqlib/encoder.go
Robin H. Johnson c6029376a5
feat: K8S KYAML output format support (#2560)
* feat: K8S KYAML output format support

Reference: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/5295-kyaml/README.md
Co-authored-by: Codex <codex@openai.com>
Generated-with: OpenAI Codex CLI (partial)
Signed-off-by: Robin H. Johnson <rjohnson@coreweave.com>

* build: gomodcache/gocache should not be committed

Signed-off-by: Robin H. Johnson <rjohnson@coreweave.com>

* chore: fix spelling of behaviour

Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>

* build: pass GOFLAGS to docker to support buildvcs=false

In trying to develop the KYAML support, various tests gave false
positive results because they made assumptions about Git functionality
Make it possible to avoid that by passing GOFLAGS='-buildvcs=false' to
to Makefile.

Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>

* doc: cover documentScenarios for tests

Signed-off-by: Robin H. Johnson <rjohnson@coreweave.com>

* build: exclude go caches from gosec

Without tuning, gosec scans all of the vendor/gocache/gomodcache, taking
several minutes (3m35 here), whereas the core of the yq takes only 15
seconds to scan.

If we intend to remediate upstream issues in future; add a seperate
target to scan those.

Signed-off-by: Robin H. Johnson <rjohnson@coreweave.com>

---------

Signed-off-by: Robin H. Johnson <rjohnson@coreweave.com>
Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
Co-authored-by: Codex <codex@openai.com>
2026-01-01 15:14:53 +11:00

93 lines
2.1 KiB
Go

package yqlib
import (
"bufio"
"errors"
"io"
"strings"
"github.com/fatih/color"
)
type Encoder interface {
Encode(writer io.Writer, node *CandidateNode) error
PrintDocumentSeparator(writer io.Writer) error
PrintLeadingContent(writer io.Writer, content string) error
CanHandleAliases() bool
}
func mapKeysToStrings(node *CandidateNode) {
if node.Kind == MappingNode {
for index, child := range node.Content {
if index%2 == 0 { // its a map key
child.Tag = "!!str"
}
}
}
for _, child := range node.Content {
mapKeysToStrings(child)
}
}
// Some funcs are shared between encoder_yaml and encoder_kyaml
func PrintYAMLDocumentSeparator(writer io.Writer, PrintDocSeparators bool) error {
if PrintDocSeparators {
log.Debug("writing doc sep")
if err := writeString(writer, "---\n"); err != nil {
return err
}
}
return nil
}
func PrintYAMLLeadingContent(writer io.Writer, content string, PrintDocSeparators bool, ColorsEnabled bool) error {
reader := bufio.NewReader(strings.NewReader(content))
// reuse precompiled package-level regex
// (declared in decoder_yaml.go)
for {
readline, errReading := reader.ReadString('\n')
if errReading != nil && !errors.Is(errReading, io.EOF) {
return errReading
}
if strings.Contains(readline, "$yqDocSeparator$") {
// Preserve the original line ending (CRLF or LF)
lineEnding := "\n"
if strings.HasSuffix(readline, "\r\n") {
lineEnding = "\r\n"
}
if PrintDocSeparators {
if err := writeString(writer, "---"+lineEnding); err != nil {
return err
}
}
} else {
if len(readline) > 0 && readline != "\n" && readline[0] != '%' && !commentLineRe.MatchString(readline) {
readline = "# " + readline
}
if ColorsEnabled && strings.TrimSpace(readline) != "" {
readline = format(color.FgHiBlack) + readline + format(color.Reset)
}
if err := writeString(writer, readline); err != nil {
return err
}
}
if errors.Is(errReading, io.EOF) {
if readline != "" {
// the last comment we read didn't have a newline, put one in
if err := writeString(writer, "\n"); err != nil {
return err
}
}
break
}
}
return nil
}