-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Sink: Force JSON encoding for .json files #3934
Conversation
Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please follow instructions at https://git.k8s.io/community/CLA.md#the-contributor-license-agreement to sign the CLA. It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Welcome @yhrn! |
Hi @yhrn. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
kyaml/kio/byteio_writer.go
Outdated
if !forceJSON { | ||
str, err := rNode.String() | ||
if err != nil { | ||
return errors.Wrap(err) | ||
} | ||
useJSONEncoder = json.Valid([]byte(str)) |
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 not sure if this stuff is still relevant. Maybe it's useful for getting more nicely formatted JSON compatible output when there is no path annotation?
CLA signed |
I just realized that JSON encoding an item will break multi doc output. This is really an old bug but it was hidden since the I'll update the PR to address this. |
Second attempt: the idea now is that JSON encoding should be used if and only if if there is only a single item, the item has a
I have also manually validated that running an |
/ok-to-test |
Thanks for the PR! It looks like You can run |
@natasha41575 I can get that test to pass by adding back the "if the YAML encoding of the node is JSON compatible then use JSON encoder" logic. However, I'm questioning a bit if this makes sense or if the test should just be removed? Why would you have JSON in a .yaml file and expect it to be formatted like JSON? Is that worth encoding most nodes twice for? And like I've described higher up, this check is also flaky, if you have a long string value it's going to fail. |
@monopole @Shell32-Natsu do you have any context on |
I just pushed a commit removing the test we discussed but I can add it back along with the code to make it pass if that ends up being the decision. I just wanted to see if I can get the test check to pass here because locally it fails after running the "normal" test suite but I suspect it's unrelated to my changes:
I don't understand what tests are running here and I also don't see how my changes would cause |
"config.kubernetes.io/path": "test.json" | ||
} | ||
} | ||
}`, |
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.
We can probably add a test case for an unformatted valid json resulting in formatted valid json. This will sort of cover the test for the deleted test case (TestFormatFileOrDirectory_YamlExtFileWithJson which tests unformatted json to formatted yaml which doesn't makes sense).
I agree, I don't see a real use case for that scenario. I commented the deleted test case was really testing unformatted-json-to-formatted, we can introduce a unit test-case to cover that scenario, then we should be good. WDYT ? |
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.
Thanks!
kyaml/kio/byteio_writer.go
Outdated
// YAML flow style encoding may not be compatible because of unquoted strings and newlines | ||
// introduced by the YAML marshaller in long string values. These newlines are insignificant | ||
// when interpreted as YAML but invalid when interpreted as JSON. | ||
jsonEncodeSingleNode := false |
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.
the comment should explain the rationale behind the node slice length == 1 check
So if we have 3 nodes, and the middle one came from a json file, while the other 2 did not,
we don't json encode? comment should explain
Also, please throw this code and comment into a func, e.g.
forceJsonEncoding := shouldForceJsonEncoding(nodes)
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.
Ok, but I'll name the func and var slightly differently to make it clear why it's fine to assume that the node slice has a single element when special casing further down.
kyaml/kio/byteio_writer.go
Outdated
"sigs.k8s.io/kustomize/kyaml/errors" | ||
"sigs.k8s.io/kustomize/kyaml/kio/kioutil" | ||
"sigs.k8s.io/kustomize/kyaml/yaml" | ||
) | ||
|
||
// Writer writes ResourceNodes to bytes. | ||
// ByteWriter writes ResourceNodes to bytes. |
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.
It would be useful to have the JSON vs YAML behavior (as a function of file name annotations) described up here.
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.
since you touched the line :)
thanks BTW
if i'm reading it correctly, the comment in the test was wrong. what the test was actually doing was confirming that If the file contained json on input, it would contain (formatted) json on output. which is a useful thing to have regression coverage for. |
I have a hard time understanding if the comment were wrong or just confusing. The reason I felt that deleting the test was the right option is that these tests verify specific formatting and in the particular case of dropping a full JSON document into a Put another way, accepting the changes to But if you feel strongly the other way then I'll add the test back with amended comments and changed expected text to the not so pretty flow style formatted YAML. |
forehead slap. yes, comments were way off. Please add a test proving that (write json to .json file, call format, read json and show nothing changed). Tests in this repo as are much about covering odd behavior and bugs (with a comment saying so) as they are about showing correct behavior. So if something gets fixed, the test must change, confirming the fix is real.
That's certainly the correct sentiment in general, except in this repo we must be sensitive about specific YAML and JSON formatting and have loads of tests that do straight up string compares of formatted text so we know when we might break someone downstream and why. |
I believe I have addressed all comments now - I added the requested tests and comments and moved the "should JSON encode?" logic to a separate func. |
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
thanks!
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: monopole, yhrn 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 |
The main issue this PR addresses is when a
.json
file containing long strings is read bykpt fn source
and then, potentially after passing through some functions, get written back to a.json
file bykpt fn sink
as invalid JSON because of newlines added to the long strings. This PR could maybe be seen as the followup mentioned in #2546.As a side note, it looks a bit problematic to get this change into kpt because it's at kyaml v0.10.17 and v0.10.20 comes with breaking changes. I could easily address all but one that was inside kustomize v2.0.3 which gets pulled in transitively via kubectl. Not sure how to deal with that.