Skip to content
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

YAML library used #1616

Open
felixfontein opened this issue Sep 14, 2024 Discussed in #1437 · 4 comments
Open

YAML library used #1616

felixfontein opened this issue Sep 14, 2024 Discussed in #1437 · 4 comments

Comments

@felixfontein
Copy link
Contributor

(Created from #1437 so we can add it to the discussion milestone.)

We're using go-yaml.v3 in SOPS. Unfortunately this library doesn't seem to be actively maintained anymore; the last commit is from May 2022, and there are quite a few bug reports and bugfix PRs that haven't been looked at / haven't progressed, some of them for years. (I got one myself, go-yaml/yaml#690, open since January 2021, last maintainer reaction in May 2021. This is blocking a bugfix on sops's side: #936 (comment))

Two issues have been created in the past in the repository asking whether it's still maintained, and the (single) maintainer always responded that it still is:

Other projects have actually went on to fork go-yaml locally, like kubernetes-sigs:

Maybe we should also consider switching to that fork? Or is anyone aware of other forks of go-yaml.v3, or even other actively maintained YAML libraries for Go?

@felixfontein
Copy link
Contributor Author

There's another YAML library for Golang: https://github.com/goccy/go-yaml It seems to be actively maintained. Maybe we should consider migrating to that one? There seems to be no other actively maintained YAML library; the kubernetes-sigs fork only receives bugfixes the Kubernetes projects needs and only gets new features if the original go-yaml/yaml gets new features (which looks quite unlikely right now), and is not meant to be used by any non-Kubernetes projects.

@felixfontein
Copy link
Contributor Author

I did some first experiments. Simply unmarshaling data is very simple, for example the only change needed for config/config.go to use that library is

--- a/config/config.go
+++ b/config/config.go
@@ -19,7 +19,7 @@ import (
        "github.com/getsops/sops/v3/kms"
        "github.com/getsops/sops/v3/pgp"
        "github.com/getsops/sops/v3/publish"
-       "gopkg.in/yaml.v3"
+       "github.com/goccy/go-yaml"
 )
 
 type fileSystem interface {

The error messages also look a lot nicer.

Transforming YAML to SOPS' TreeBranches and vice versa is obviously more work. I've started doing some experiments on how to parse YAML here: https://gist.github.com/felixfontein/f53e704961c3b241810e061083017a5e

So far it looks pretty good. There are two things so far that I found that go-yaml.v3 can handle, and goccy/go-yaml can't:

(Also the node structure includes references to the token streams, which I guess would make it possible to implement #1755 for YAML as well, at least from the parsing side - I haven't looked at the emitting side so far.)

@felixfontein
Copy link
Contributor Author

Update: I now know how to distinguish between strings and other formats; see goccy/go-yaml#661 (comment). I've updated https://gist.github.com/felixfontein/f53e704961c3b241810e061083017a5e to print more infos.

@felixfontein
Copy link
Contributor Author

With goccy/go-yaml, we could also round-trip the representation of values, like encrypt and decrypt 0x1_5 instead of converting it to 21 (like now).

Something similar could also be done for JSON. (For decoding, one can call d.UseNumber() to ensure that numbers are returned as token.Number, which is basically a string. For encoding, we convert values to strings with json.Marshal(), so that's also easy to handle.)

This would also make it easier to serialize arbitrary data to INI or DotEnv, since we already have a string representation we can simply write into there. (Obviously it won't be roundtrip safe, since loading the INI/DotEnv file will give you a string back, not an integer/float/timestamp/date/...)

This would unfortunately break compatibility with older SOPS versions in the sense that files written with a version supporting this could not be decrypted with an older version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant