-
Couldn't load subscription status.
- Fork 87
Add "kyaml" support and yamlfmt #132
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
Conversation
c72348b to
8fb29f1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
quick pass just on go.mod and yamlfmt/
yamlfmt/yamlfmt.go
Outdated
| } | ||
| } | ||
|
|
||
| func renderYAML(in io.Reader, format string, printDiff bool, out io.Writer) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks ripe for a unit test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, fair. I didn't write tests for the CLI tool yet.
|
Pushed with everything but a unit test. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
super quick sweep with a couple initial comments, didn't dig very deep into the impl
yamlfmt/yamlfmt.go
Outdated
| help := flag.Bool("?", false, "print usage and exit") | ||
| diff := flag.Bool("d", false, "diff input files with their formatted versions") | ||
| write := flag.Bool("w", false, "write result to input files instead of stdout") | ||
| format := flag.String("o", "yaml", "output format: may be 'yaml' or 'kyaml'") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised to even offer a non-kyaml option here, let alone defaulting to it... don't we want to be opinionated towards kyaml?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mayber eventually but I don't KNOW that yet? There's enough pushback that I think we should be cautious and open to being wrong.
kyaml/kyaml.go
Outdated
| if lazyQuote && !needsQuotes(val) { | ||
| fmt.Fprint(out, val) | ||
| } else { | ||
| fmt.Fprint(out, strconv.Quote(val)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is standard go quoting 100% compatible with yaml string escaping?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair question. I will have to evaluate that and get back
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://yaml.org/spec/1.2.2/#escaped-characters
All non-printable characters must be escaped. YAML escape sequences use the “\” notation common to most modern computer languages [...]
[...]
YAML escape sequences are a superset of C’s escape sequences:
https://pkg.go.dev/strconv#Quote
Quote returns a double-quoted Go string literal representing s. The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for control characters and non-printable characters as defined by IsPrint.
https://pkg.go.dev/strconv#IsPrint
IsPrint reports whether the rune is defined as printable by Go, with the same definition as unicode.IsPrint: letters, numbers, punctuation, symbols and ASCII space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be compatible.
\t \n, \xFF \u0100 escape style are all in "Example 5.13 Escaped Characters" in YAML 1.2.2 spec.
I also see these in 1.1 "Example 5.14. Escaped Characters" and even the 1.0 draft "4.6.9. Escaping".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I read the YAML spec correctly, '\x00' should escape in YAML as "\0" but Go converts it to "\x00" - so I probably have to decode manually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I have no idea how to read that table - it includes space and slash, which clearly are not actually escaped
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I read the YAML spec correctly, '\x00' should escape in YAML as "\0" but Go converts it to "\x00" - so I probably have to decode manually.
I don't think \x00 is invalid in yaml, but \0 would probably be canonical. https://go.dev/play/p/a6_gobBEp0k
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a commit, but not sure we need it.
It's unclear if we actually need to change this logic. The round-trip test works without it, but we could very likely just be making the same bad assumptions as go-yaml.
The spec describes escapes for things like space and forward-slash, which seem wrong to escape, so I may be misreading it.
|
Easy things fixed |
c603bd5 to
17c7943
Compare
d46fbd4 to
0a0c08a
Compare
|
TTBOMK this is ready for review. |
|
I have a commit cooking to simplify tests, but the rest of this is "done". |
|
Tests are a bit simpler. |
KYAML is a strict subset of YAML, which is sort of halfway between YAML
and JSON. It has the following properties:
* Does not depend on whitespace (easier to text-patch and template).
* Always quotes value strings (no ambiguity aroud things like "no").
* Allows quoted keys, but does not require them, and only quotes them if
they are not obviously safe (e.g. "no" would always be quoted).
* Always uses {} for structs and maps (no more obscure errors about
mapping values).
* Always uses [] for lists (no more trying to figure out if a dash
changes the meaning).
* When printing, it includes a header which makes it clear this is YAML
and not ill-formed JSON.
* Allows trailing commas
* Allows comments,
* Tries to economize on vertical space by "cuddling" some kinds of
brackets together.
* Retains comments.
Examples:
A struct:
```yaml
metadata: {
creationTimestamp: "2024-12-11T00:10:11Z",
labels: {
app: "hostnames",
},
name: "hostnames",
namespace: "default",
resourceVersion: "15231643",
uid: "f64dbcba-9c58-40b0-bbe7-70495efb5202",
}
```
A list of primitves:
```yaml
ipFamilies: [
"IPv4",
"IPv6",
]
```
A list of structs:
```yaml
ports: [{
port: 80,
protocol: "TCP",
targetPort: 80,
}, {
port: 443,
protocol: "TCP",
targetPort: 443,
}]
```
A multi-document stream:
```yaml
---
{
foo: "bar",
}
---
{
qux: "zrb",
}
```
* Can read 1 file (cmdline) * Can read multiple files (cmdline) * Can read stdin * Can write traditional YAML or KYAML * Can diff input vs output (-d) * Can write results to the input files (-w)
It's unclear if we actually need this. The round-trip test works without it. The spec describes escapes for things like space and forward-slash, which seem wrong to escape, so I may be misreading it.
Merge the "regular" and "compact" tests together.
|
a k/k PR preview: kubernetes/kubernetes#132942 |
|
FTR: I will be away for the last 3 days of the code-freeze, so if we want this in, I need it soon. Otherwise we can push to next release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry was out, but this lgtm
| } | ||
| if indent != 0 { | ||
| return fmt.Errorf("kyaml internal error: line %d: document non-zero indent (%d)", doc.Line, indent) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: some of the error cases are not covered by tests, would be nice to get that added in followup PRs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the error paths are more like "assert" - they are no expected to ever trigger, but when they do it will at least fail in a semi-obvious way. Will look at adding test cases. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some tests around error handling. Coverage is > 89%. What's left is mostly error-returning from YAML and JSON parsing, and some impossible-to-reach (for now?) comment handling (yaml.v3 comments are...inconsistently implemented)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
|
Pushed with new test cases for corner cases mostly. Needs LGTM and approve. |
|
/lgtm Expanded test coverage looks excellent |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jpbetz, soltysh, thockin The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
This repo seems to use tags - do we need a v1.5.1 or v1.6.0 tag so I can re-vendor to k/k ? |
|
yes, let's add v1.6.0 since this added features |
KEP kubernetes/enhancements#5295
KYAML is a strict subset of YAML, which is sort of halfway between YAML and JSON. It has the following properties:
Output from
kubectl get -o kyamlcan be fed back intokubectl.Examples:
A struct:
A list of primitves:
A list of structs:
A multi-document stream: