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

feat: global linesep character, handle diffs #50

Merged
merged 2 commits into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ exclude:
- excluded/**/*.yaml
```

### Line Ending

The default line ending is `lf` (Unix style, Mac/Linux). The line ending can be changed to `crlf` (Windows style) with the `line_ending` setting:
```yaml
line_ending: crlf
```
This setting will be sent to any formatter as a config field called `line_ending`. If a `line_ending` is specified in the formatter, this will overwrite it. New formatters are free to ignore this setting if they don't need it, but any formatter provided by this repo will handle it accordingly.

### Formatter

In your `.yamlfmt` file you can also specify configuration for the formatter if that formatter supports it. To change the indentation level of the basic formatter for example:
Expand Down
41 changes: 27 additions & 14 deletions command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"io"
"os"
"runtime"

"github.com/google/yamlfmt"
"github.com/google/yamlfmt/engine"
Expand All @@ -40,9 +41,10 @@ type formatterConfig struct {
}

type commandConfig struct {
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
FormatterConfig *formatterConfig `mapstructure:"formatter,omitempty"`
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
LineEnding yamlfmt.LineBreakStyle `mapstructure:"line_ending"`
FormatterConfig *formatterConfig `mapstructure:"formatter,omitempty"`
}

func RunCommand(
Expand All @@ -58,14 +60,23 @@ func RunCommand(
if len(config.Include) == 0 {
config.Include = []string{"**/*.{yaml,yml}"}
}
if config.LineEnding == "" {
config.LineEnding = yamlfmt.LineBreakStyleLF
if runtime.GOOS == "windows" {
config.LineEnding = yamlfmt.LineBreakStyleCRLF
}
}

var formatter yamlfmt.Formatter
if config.FormatterConfig == nil {
factory, err := registry.GetDefaultFactory()
if err != nil {
return err
}
formatter = factory.NewDefault()
formatter, err = factory.NewFormatter(nil)
if err != nil {
return err
}
} else {
var (
factory yamlfmt.Factory
Expand All @@ -80,20 +91,22 @@ func RunCommand(
return err
}

if len(config.FormatterConfig.FormatterSettings) > 0 {
formatter, err = factory.NewWithConfig(config.FormatterConfig.FormatterSettings)
if err != nil {
return err
}
} else {
formatter = factory.NewDefault()
config.FormatterConfig.FormatterSettings["line_ending"] = config.LineEnding
formatter, err = factory.NewFormatter(config.FormatterConfig.FormatterSettings)
if err != nil {
return err
}
}

lineSepChar, err := config.LineEnding.Separator()
if err != nil {
return err
}
engine := &engine.Engine{
Include: config.Include,
Exclude: config.Exclude,
Formatter: formatter,
Include: config.Include,
Exclude: config.Exclude,
LineSepCharacter: lineSepChar,
Formatter: formatter,
}

switch operation {
Expand Down
27 changes: 14 additions & 13 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ import (
)

type Engine struct {
Include []string
Exclude []string
Formatter yamlfmt.Formatter
Include []string
Exclude []string
LineSepCharacter string
Formatter yamlfmt.Formatter
}

func (e *Engine) FormatAllFiles() error {
Expand Down Expand Up @@ -91,9 +92,9 @@ func (e *Engine) LintFile(path string) error {
if err != nil {
return err
}
diffContent := multilinediff.MultilineDiff(string(yamlBytes), string(formatted), "\n")
if diffContent != "" {
return fmt.Errorf(diffContent)
diff, diffCount := multilinediff.Diff(string(yamlBytes), string(formatted), e.LineSepCharacter)
if diffCount > 0 {
return fmt.Errorf(diff)
}
return nil
}
Expand All @@ -107,10 +108,10 @@ func (e *Engine) DryRunAllFiles() (string, error) {
formatErrors := NewFormatFileErrors()
dryRunDiffs := NewDryRunDiffs()
for _, path := range paths {
diff, err := e.DryRunFile(path)
diff, diffCount, err := e.DryRunFile(path)
if err != nil {
formatErrors.Add(path, err)
} else if diff != "" {
} else if diffCount > 0 {
dryRunDiffs.Add(path, diff)
}
}
Expand All @@ -121,15 +122,15 @@ func (e *Engine) DryRunAllFiles() (string, error) {
return dryRunDiffs.CombineOutput(), nil
}

func (e *Engine) DryRunFile(path string) (string, error) {
func (e *Engine) DryRunFile(path string) (string, int, error) {
yamlBytes, err := os.ReadFile(path)
if err != nil {
return "", err
return "", 0, err
}
formatted, err := e.Formatter.Format(yamlBytes)
if err != nil {
return "", err
return "", 0, err
}
diffContent := multilinediff.MultilineDiff(string(yamlBytes), string(formatted), "\n")
return diffContent, nil
diff, diffCount := multilinediff.Diff(string(yamlBytes), string(formatted), e.LineSepCharacter)
return diff, diffCount, nil
}
2 changes: 1 addition & 1 deletion formatters/basic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ 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 |
| `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 |
10 changes: 5 additions & 5 deletions formatters/basic/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ import (
)

type Config struct {
Indent int `mapstructure:"indent"`
IncludeDocumentStart bool `mapstructure:"include_document_start"`
EmojiSupport bool `mapstructure:"emoji_support"`
LineEnding string `mapstructure:"line_ending"`
RetainLineBreaks bool `mapstructure:"retain_line_breaks"`
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"`
}

func DefaultConfig() *Config {
Expand Down
19 changes: 19 additions & 0 deletions formatters/basic/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package basic

import "fmt"

type BasicFormatterError struct {
err error
}

func (e BasicFormatterError) Error() string {
return fmt.Sprintf("basic formatter error: %v", e.err)
}

func (e BasicFormatterError) Unwrap() error {
return e.err
}

func wrapBasicFormatterError(err error) error {
return BasicFormatterError{err: err}
}
14 changes: 6 additions & 8 deletions formatters/basic/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ func (f *BasicFormatterFactory) Type() string {
return BasicFormatterType
}

func (f *BasicFormatterFactory) NewDefault() yamlfmt.Formatter {
return newFormatter(DefaultConfig())
}

func (f *BasicFormatterFactory) NewWithConfig(configData map[string]interface{}) (yamlfmt.Formatter, error) {
func (f *BasicFormatterFactory) NewFormatter(configData map[string]interface{}) (yamlfmt.Formatter, error) {
config := DefaultConfig()
err := mapstructure.Decode(configData, &config)
if err != nil {
return nil, err
if configData != nil {
err := mapstructure.Decode(configData, &config)
if err != nil {
return nil, err
}
}
return newFormatter(config), nil
}
Expand Down
2 changes: 1 addition & 1 deletion formatters/basic/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func TestNewWithConfigRetainsDefaultValues(t *testing.T) {
factory := basic.BasicFormatterFactory{}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
formatter, err := factory.NewWithConfig(tc.configMap)
formatter, err := factory.NewFormatter(tc.configMap)
if err != nil {
t.Fatalf("expected factory to create config, got error: %v", err)
}
Expand Down
8 changes: 4 additions & 4 deletions formatters/basic/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ func ConfigureFeaturesFromConfig(config *Config) yamlfmt.FeatureList {
features = append(features, featCRLFSupport)
}
if config.RetainLineBreaks {
linebreakStr := "\n"
if config.LineEnding == yamlfmt.LineBreakStyleCRLF {
linebreakStr = "\r\n"
lineSep, err := config.LineEnding.Separator()
if err != nil {
lineSep = "\n"
}
featLineBreak := hotfix.MakeFeatureRetainLineBreak(linebreakStr)
featLineBreak := hotfix.MakeFeatureRetainLineBreak(lineSep)
features = append(features, featLineBreak)
}
return features
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.19

require (
github.com/RageCage64/go-utf8-codepoint-converter v0.1.0
github.com/RageCage64/multilinediff v0.1.0
github.com/RageCage64/multilinediff v0.2.0
github.com/bmatcuk/doublestar/v4 v4.2.0
github.com/mitchellh/mapstructure v1.5.0
gopkg.in/yaml.v3 v3.0.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/RageCage64/go-utf8-codepoint-converter v0.1.0 h1:6GreQRSQApXW1sgeFXMB
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/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
Expand Down
2 changes: 1 addition & 1 deletion internal/hotfix/unicode.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
// yamlfmt.FeatureFunc
func ParseUnicodePoints(content []byte) ([]byte, error) {
if len(content) == 0 {
return []byte{}, errors.New("no content")
return []byte{}, nil
}

p := unicodeParser{
Expand Down
27 changes: 23 additions & 4 deletions yamlfmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ type Formatter interface {

type Factory interface {
Type() string
NewDefault() Formatter
NewWithConfig(config map[string]interface{}) (Formatter, error)
NewFormatter(config map[string]interface{}) (Formatter, error)
}

type Registry struct {
Expand Down Expand Up @@ -63,11 +62,31 @@ func (r *Registry) GetDefaultFactory() (Factory, error) {
return factory, nil
}

type LineBreakStyle string

const (
LineBreakStyleLF = "lf"
LineBreakStyleCRLF = "crlf"
LineBreakStyleLF LineBreakStyle = "lf"
LineBreakStyleCRLF LineBreakStyle = "crlf"
)

type UnsupportedLineBreakError struct {
style LineBreakStyle
}

func (e UnsupportedLineBreakError) Error() string {
return fmt.Sprintf("unsupported line break style %s, see package documentation for supported styles", e.style)
}

func (s LineBreakStyle) Separator() (string, error) {
switch s {
case LineBreakStyleLF:
return "\n", nil
case LineBreakStyleCRLF:
return "\r\n", nil
}
return "", UnsupportedLineBreakError{style: s}
}

type FeatureFunc func([]byte) ([]byte, error)

type Feature struct {
Expand Down