knadh / koanf

Simple, extremely lightweight, extensible, configuration management library for Go. Support for JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Remove dependency on gopkg.in/yaml.v3

Baldomo opened this issue · comments

Sadly, gopkg.in is offline or unreachable way too often, right now i get an error pulling refs from Github but it's a new one almost every week. For example

https fetch: Get "https://gopkg.in/square/go-jose.v2?go-get=1": dial tcp 185.125.188.128:443: i/o timeout

or

github.com/knadh/koanf/parsers/yaml imports
    gopkg.in/yaml.v3 tested by
    gopkg.in/yaml.v3.test imports
    gopkg.in/check.v1: unrecognized import path "gopkg.in/check.v1": https fetch: Get "https://gopkg.in/check.v1?go-get=1": dial tcp 185.125.188.236:443: i/o timeout

I suggest switching to goccy/go-yaml since it's a fork of the original package, is very well maintained and has the same API (plus nice formatted error messages). I am not affiliated with the project in any way, I'm just fed up with having to wait until gopkg.in fixes itself.

Hi @Baldomo. I tested this out locally and the tests fail. Maybe you'd be able to test this out and send a PR that we can evaluate?

For the purposes of this issue, I'll refer to goccy/go-yaml and go-yaml/yaml as goccy and go-yaml respectively

First of all, sorry for the late response. I looked into it a little more and found three main differences between the two libraries:

  1. goccy does not "beautify" the output of Marshal() by default but the following diff fixes that:
diff --git a/parsers/yaml/yaml.go b/parsers/yaml/yaml.go
index 17b847d..b288047 100644
--- a/parsers/yaml/yaml.go
+++ b/parsers/yaml/yaml.go
@@ -2,7 +2,7 @@
 package yaml
 
 import (
-       "gopkg.in/yaml.v3"
+       "github.com/goccy/go-yaml"
 )
 
 // YAML implements a YAML parser.
@@ -25,5 +25,5 @@ func (p *YAML) Unmarshal(b []byte) (map[string]interface{}, error) {
 
 // Marshal marshals the given config map to YAML bytes.
 func (p *YAML) Marshal(o map[string]interface{}) ([]byte, error) {
-       return yaml.Marshal(o)
+       return yaml.MarshalWithOptions(o, yaml.Indent(4), yaml.IndentSequence(true))
 }
  1. goccy outputs uint64 (if positive) or int64 (if negative) if the output object is an interface{}, which is ok I guess? The spec doesn't mention anything about this because it's implementation-specific.

  2. For whatever reason tabs are not considered illegal whitespace in goccy, which is totally against the standard. Rightfully so, users opened an issue about it not long ago: goccy/go-yaml#273

The latter one is especially damning for goccy because it would probably break packages using koanf (although it seems users already ahve a fix ready for that).

Finally, the go-yaml author has faith in gopkg.in and makes a good point about switching to Github in go-yaml/yaml#925

I leave this into your capabale hands, since I'm not in any position to decide whichever solution is the best. I'm also quite conflicted considering the points above.

Since this hasn't come up elsewhere, I think it's best to leave it untouched. The Go pkg proxy should ideally handle any connectivity issues in the upstream.