Repository: google/yamlfmt
Pull request #65 (2022-11-03 14:31:21)

yamlfmt: Using new yaml fork
Switching to a new yaml fork that I'm maintaining which has a number of fixes that previously needed hotfix functionality. This PR removes a ton of code that was required before the library update.

Signed-off-by: braydonk <braydonk@google.com>


Patch:
diff --git a/cmd/yamlfmt/main.go b/cmd/yamlfmt/main.go
index f3dadf4..e04ee55 100644
--- a/cmd/yamlfmt/main.go
+++ b/cmd/yamlfmt/main.go
@@ -20,10 +20,10 @@ import (
 	"log"
 	"os"
 
+	"github.com/braydonk/yaml"
 	"github.com/google/yamlfmt"
 	"github.com/google/yamlfmt/command"
 	"github.com/google/yamlfmt/formatters/basic"
-	"gopkg.in/yaml.v3"
 )
 
 const defaultConfigName = ".yamlfmt"
diff --git a/formatters/basic/README.md b/formatters/basic/README.md
index 73544ab..35d99d3 100644
--- a/formatters/basic/README.md
+++ b/formatters/basic/README.md
@@ -1,6 +1,6 @@
 # Basic Formatter
 
-The basic formatter is a barebones formatter that simply takes the data provided, serializes it with [gopkg.in/yaml.v3](https://gopkg.in/yaml.v3) and encodes it again. This provides a consistent output format that is very opinionated and cannot be configured.
+The basic formatter is a barebones formatter that simply takes the data provided, serializes it with a fork of [gopkg.in/yaml.v3](https://www.github.com/braydonk/yaml) and encodes it again. This provides a consistent output format that is very opinionated and cannot be configured.
 
 ## Configuration
 
@@ -9,6 +9,5 @@ The basic formatter is a barebones formatter that simply takes the data provided
 | `indent`                 | int            | 2       | The indentation level in spaces to use for the formatted yaml|
 | `include_document_start` | bool           | false   | Include `---` at document start |
 | `line_ending`            | `lf` or `crlf` | `crlf` on Windows, `lf` otherwise | Parse and write the file with "lf" or "crlf" line endings. This setting will be overwritten by the global `line_ending`. |
-| `emoji_support`          | bool           | false   | Support encoding utf-8 emojis |
 | `retain_line_breaks`     | bool           | false   | Retain line breaks in formatted yaml |
 | `disallow_anchors`       | bool           | false   | If true, reject any YAML anchors or aliases found in the document. |
diff --git a/formatters/basic/config.go b/formatters/basic/config.go
index 108a99a..dcae4f6 100644
--- a/formatters/basic/config.go
+++ b/formatters/basic/config.go
@@ -23,7 +23,6 @@ import (
 type Config struct {
 	Indent               int                    `mapstructure:"indent"`
 	IncludeDocumentStart bool                   `mapstructure:"include_document_start"`
-	EmojiSupport         bool                   `mapstructure:"emoji_support"`
 	LineEnding           yamlfmt.LineBreakStyle `mapstructure:"line_ending"`
 	RetainLineBreaks     bool                   `mapstructure:"retain_line_breaks"`
 	DisallowAnchors      bool                   `mapstructure:"disallow_anchors"`
diff --git a/formatters/basic/features.go b/formatters/basic/features.go
index a879061..42f1a39 100644
--- a/formatters/basic/features.go
+++ b/formatters/basic/features.go
@@ -28,28 +28,13 @@ var (
 			return append([]byte(documentStart), content...), nil
 		},
 	}
-	featEmojiSupport = yamlfmt.Feature{
-		Name:        "Emoji Support",
-		AfterAction: hotfix.ParseUnicodePoints,
-	}
-	featCRLFSupport = yamlfmt.Feature{
-		Name:         "CRLF Support",
-		BeforeAction: hotfix.StripCRBytes,
-		AfterAction:  hotfix.WriteCRLFBytes,
-	}
 )
 
 func ConfigureFeaturesFromConfig(config *Config) yamlfmt.FeatureList {
 	features := []yamlfmt.Feature{}
-	if config.EmojiSupport {
-		features = append(features, featEmojiSupport)
-	}
 	if config.IncludeDocumentStart {
 		features = append(features, featIncludeDocumentStart)
 	}
-	if config.LineEnding == yamlfmt.LineBreakStyleCRLF {
-		features = append(features, featCRLFSupport)
-	}
 	if config.RetainLineBreaks {
 		lineSep, err := config.LineEnding.Separator()
 		if err != nil {
diff --git a/formatters/basic/formatter.go b/formatters/basic/formatter.go
index 77600c9..124f6d6 100644
--- a/formatters/basic/formatter.go
+++ b/formatters/basic/formatter.go
@@ -19,8 +19,8 @@ import (
 	"errors"
 	"io"
 
+	"github.com/braydonk/yaml"
 	"github.com/google/yamlfmt"
-	"gopkg.in/yaml.v3"
 )
 
 const BasicFormatterType string = "basic"
@@ -70,6 +70,9 @@ func (f *BasicFormatter) Format(input []byte) ([]byte, error) {
 	var b bytes.Buffer
 	e := yaml.NewEncoder(&b)
 	e.SetIndent(f.Config.Indent)
+	if f.Config.LineEnding == yamlfmt.LineBreakStyleCRLF {
+		e.SetLineBreakStyle(yaml.LineBreakStyleCRLF)
+	}
 	for _, doc := range documents {
 		err := e.Encode(&doc)
 		if err != nil {
diff --git a/go.mod b/go.mod
index 0cfe33b..07bd7d3 100644
--- a/go.mod
+++ b/go.mod
@@ -3,11 +3,10 @@ module github.com/google/yamlfmt
 go 1.19
 
 require (
-	github.com/RageCage64/go-utf8-codepoint-converter v0.1.0
 	github.com/RageCage64/multilinediff v0.2.0
 	github.com/bmatcuk/doublestar/v4 v4.2.0
+	github.com/braydonk/yaml v0.1.0
 	github.com/mitchellh/mapstructure v1.5.0
-	gopkg.in/yaml.v3 v3.0.1
 )
 
 require github.com/google/go-cmp v0.5.9 // indirect
diff --git a/go.sum b/go.sum
index 2b59ccc..7eb64af 100644
--- a/go.sum
+++ b/go.sum
@@ -1,16 +1,12 @@
-github.com/RageCage64/go-utf8-codepoint-converter v0.1.0 h1:6GreQRSQApXW1sgeFXMBLDdxSC6DCzu4lKBS/LEyrSA=
-github.com/RageCage64/go-utf8-codepoint-converter v0.1.0/go.mod h1:asNWDxR7n0QIQyZNYTlpNk6Dg7GkUnxtCXho987uen8=
-github.com/RageCage64/multilinediff v0.1.0 h1:P9Iht5Vj4SHSmTJhQPJnySzTlX/cpL99kN3RJxejipQ=
-github.com/RageCage64/multilinediff v0.1.0/go.mod h1:pKr+KLgP0gvRzA+yv0/IUaYQuBYN1ucWysvsL58aMP0=
 github.com/RageCage64/multilinediff v0.2.0 h1:yNSpSF5NXIrmo6bRIgO4Q0g7SXqFD4j/WEcBE+BdCFY=
 github.com/RageCage64/multilinediff v0.2.0/go.mod h1:pKr+KLgP0gvRzA+yv0/IUaYQuBYN1ucWysvsL58aMP0=
 github.com/bmatcuk/doublestar/v4 v4.2.0 h1:Qu+u9wR3Vd89LnlLMHvnZ5coJMWKQamqdz9/p5GNthA=
 github.com/bmatcuk/doublestar/v4 v4.2.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
+github.com/braydonk/yaml v0.1.0 h1:5YHA82fwVjHNONmSwFhAMfxqyUljBRwPrrEbQv6jGdU=
+github.com/braydonk/yaml v0.1.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
 github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/internal/anchors/check.go b/internal/anchors/check.go
index 8c33f6d..aef3070 100644
--- a/internal/anchors/check.go
+++ b/internal/anchors/check.go
@@ -18,7 +18,7 @@ import (
 	"errors"
 	"fmt"
 
-	"gopkg.in/yaml.v3"
+	"github.com/braydonk/yaml"
 )
 
 func Check(n yaml.Node) error {
diff --git a/internal/hotfix/crlf.go b/internal/hotfix/crlf.go
deleted file mode 100644
index 6f8d943..0000000
--- a/internal/hotfix/crlf.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2022 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package hotfix
-
-// yamlfmt.FeatureFunc
-func StripCRBytes(crlfContent []byte) ([]byte, error) {
-	onlyLf := []byte{}
-	for _, b := range crlfContent {
-		if b != '\r' {
-			onlyLf = append(onlyLf, b)
-		}
-	}
-	return onlyLf, nil
-}
-
-// yamlfmt.FeatureFunc
-func WriteCRLFBytes(lfContent []byte) ([]byte, error) {
-	crlfContent := []byte{}
-	for _, b := range lfContent {
-		if b == '\n' {
-			crlfContent = append(crlfContent, '\r')
-		}
-		crlfContent = append(crlfContent, b)
-	}
-	return crlfContent, nil
-}
diff --git a/internal/hotfix/unicode.go b/internal/hotfix/unicode.go
deleted file mode 100644
index 4374eaf..0000000
--- a/internal/hotfix/unicode.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2022 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package hotfix
-
-import (
-	"errors"
-	"regexp"
-
-	"github.com/RageCage64/go-utf8-codepoint-converter/codepoint"
-)
-
-// yamlfmt.FeatureFunc
-func ParseUnicodePoints(content []byte) ([]byte, error) {
-	if len(content) == 0 {
-		return []byte{}, nil
-	}
-
-	p := unicodeParser{
-		buf: content,
-		out: []byte{},
-	}
-
-	var err error
-	for err != errEndOfBuffer {
-		if p.peek() == '\\' && p.peekAhead(1) == 'U' {
-			err = p.parseUTF8CodePoint()
-			continue
-		}
-
-		p.write()
-		err = p.next()
-	}
-
-	return p.out, nil
-}
-
-type unicodeParser struct {
-	buf []byte
-	out []byte
-	pos uint
-}
-
-var (
-	errInvalidCodePoint = errors.New("invalid UTF-8 codepoint sequence")
-	errEndOfBuffer      = errors.New("end of buffer")
-)
-
-func (p *unicodeParser) peek() byte {
-	return p.buf[p.pos]
-}
-
-func (p *unicodeParser) peekAhead(n uint) byte {
-	return p.buf[p.pos+n]
-}
-
-func (p *unicodeParser) write() {
-	p.out = append(p.out, p.peek())
-}
-
-func (p *unicodeParser) writeArbitrary(b []byte) {
-	p.out = append(p.out, b...)
-}
-
-func (p *unicodeParser) next() error {
-	p.pos++
-	if p.pos == uint(len(p.buf)) {
-		return errEndOfBuffer
-	}
-	return nil
-}
-
-func (p *unicodeParser) parseUTF8CodePoint() error {
-	codepointBytes := []byte{}
-
-	// Parse literal escape tokens while checking if this is a valid UTF-16 sequence
-	if p.peek() != '\\' {
-		return errInvalidCodePoint
-	}
-	codepointBytes = append(codepointBytes, p.peek())
-	err := p.next()
-	if err != nil {
-		return err
-	}
-	if p.peek() != 'U' {
-		return errInvalidCodePoint
-	}
-	codepointBytes = append(codepointBytes, p.peek())
-
-	// We've detected a UTF-8 codepoint sequence. The library writes the UTF-16 sequence
-	// i.e. \U0001F60A as 10 individual bytes. Our goal is to combine the 8
-	// hexadecimal numbers we should see subsequently into the 4 byte values they
-	// represent.
-	isHex, err := regexp.Compile("[0-9A-F]")
-	if err != nil {
-		return err
-	}
-
-	for i := 0; i < 8; i++ {
-		// Get a byte and confirm it is a hex digit.
-		err = p.next()
-		if err != nil {
-			return err
-		}
-		hexDigit := p.peek()
-		if !isHex.Match([]byte{hexDigit}) {
-			return errInvalidCodePoint
-		}
-		codepointBytes = append(codepointBytes, hexDigit)
-	}
-
-	// Now that we have the codepoint, we'll represent it as a string
-	// and pass it to the codepoint conversion library.
-	utf8Bytes, err := codepoint.Convert(string(codepointBytes))
-	if err != nil {
-		return err
-	}
-	p.writeArbitrary(utf8Bytes)
-
-	// Continue to the next byte for convenience to the caller.
-	err = p.next()
-	if err != nil {
-		return err
-	}
-
-	return nil
-}


Test patch:
diff --git a/formatters/basic/formatter_test.go b/formatters/basic/formatter_test.go
index 8c1c010..1db5387 100644
--- a/formatters/basic/formatter_test.go
+++ b/formatters/basic/formatter_test.go
@@ -110,7 +110,6 @@ func TestCRLFLineEnding(t *testing.T) {
 
 func TestEmojiSupport(t *testing.T) {
 	config := basic.DefaultConfig()
-	config.EmojiSupport = true
 	f := newFormatter(config)
 
 	yaml := "a: 😊"
diff --git a/internal/anchors/check_test.go b/internal/anchors/check_test.go
index b5ecaa6..8d8071a 100644
--- a/internal/anchors/check_test.go
+++ b/internal/anchors/check_test.go
@@ -18,8 +18,8 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/braydonk/yaml"
 	"github.com/google/yamlfmt/internal/anchors"
-	"gopkg.in/yaml.v3"
 )
 
 func TestCheck(t *testing.T) {
diff --git a/internal/hotfix/crlf_test.go b/internal/hotfix/crlf_test.go
deleted file mode 100644
index aa9796b..0000000
--- a/internal/hotfix/crlf_test.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2022 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package hotfix_test
-
-import (
-	"testing"
-
-	"github.com/google/yamlfmt/internal/hotfix"
-)
-
-func TestStripCRBytes(t *testing.T) {
-	crlfContent := []byte("two\r\nlines\r\n")
-	lfContent, _ := hotfix.StripCRBytes(crlfContent)
-	count := countByte(lfContent, '\r')
-	if count != 0 {
-		t.Fatalf("Found %d CR (decimal 13) bytes in %v", count, lfContent)
-	}
-}
-
-func TestWriteCRLF(t *testing.T) {
-	lfContent := []byte("two\nlines\n")
-	crlfContent, _ := hotfix.WriteCRLFBytes(lfContent)
-	countCR := countByte(crlfContent, '\r')
-	countLF := countByte(crlfContent, '\n')
-	if countCR != countLF {
-		t.Fatalf("Found %d CR (decimal 13) and %d LF (decimal 10) bytes in %v", countCR, countLF, crlfContent)
-	}
-}
-
-func countByte(content []byte, searchByte byte) int {
-	count := 0
-	for _, b := range content {
-		if b == searchByte {
-			count++
-		}
-	}
-	return count
-}
diff --git a/internal/hotfix/unicode_test.go b/internal/hotfix/unicode_test.go
deleted file mode 100644
index 35a4979..0000000
--- a/internal/hotfix/unicode_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2022 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package hotfix_test
-
-import (
-	"testing"
-
-	"github.com/google/yamlfmt/formatters/basic"
-	"github.com/google/yamlfmt/internal/hotfix"
-)
-
-func TestParseEmoji(t *testing.T) {
-	testCases := []struct {
-		name        string
-		yamlStr     string
-		expectedStr string
-	}{
-		{
-			name:        "parses emoji",
-			yamlStr:     "a: 😂\n",
-			expectedStr: "a: \"😂\"\n",
-		},
-		{
-			name:        "parses multiple emoji",
-			yamlStr:     "a: 😼 👑\n",
-			expectedStr: "a: \"😼 👑\"\n",
-		},
-		{
-			name:        "retains backslashes",
-			yamlStr:     "a: \\look at my backslash\n",
-			expectedStr: "a: \\look at my backslash\n",
-		},
-	}
-
-	f := &basic.BasicFormatter{Config: basic.DefaultConfig()}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			formattedBefore, err := f.Format([]byte(tc.yamlStr))
-			if err != nil {
-				t.Fatalf("yaml failed to parse: %v", err)
-			}
-			formattedAfter, err := hotfix.ParseUnicodePoints(formattedBefore)
-			if err != nil {
-				t.Fatalf("expected no error, got: %v", err)
-			}
-			formattedStr := string(formattedAfter)
-			if formattedStr != tc.expectedStr {
-				t.Fatalf("parsed string does not match: \nexpected: %s\ngot: %s", tc.expectedStr, string(formattedStr))
-			}
-		})
-	}
-}