Skip to content

Commit

Permalink
Add eof_newline option (#189)
Browse files Browse the repository at this point in the history
This PR adds a new option to forcibly add the end of file newline if
it's not there. This is useful in the scenario where the
`retain_line_breaks` feature is disabled but the eof newline is still
wanted.
  • Loading branch information
braydonk authored Jun 24, 2024
1 parent e003da6 commit 7202c12
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 10 deletions.
3 changes: 2 additions & 1 deletion docs/config-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ The basic formatter is a barebones formatter that simply takes the data provided
| `indentless_arrays` | bool | false | Render `-` array items (block sequence items) without an increased indent. |
| `drop_merge_tag` | bool | false | Assume that any well formed merge using just a `<<` token will be a merge, and drop the `!!merge` tag from the formatted result. |
| `pad_line_comments` | int | 1 | The number of padding spaces to insert before line comments. |
| `trim_trailing_whitespace` | bool | false | Whether to trim trailing whitespace from lines. |
| `trim_trailing_whitespace` | bool | false | Trim trailing whitespace from lines. |
| `eof_newline` | bool | false | Always add a newline at end of file. Useful in the scenario where `retain_line_breaks` is disabled but the trailing newline is still needed. |

### Note on `max_line_length`

Expand Down
1 change: 1 addition & 0 deletions formatters/basic/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Config struct {
DropMergeTag bool `mapstructure:"drop_merge_tag"`
PadLineComments int `mapstructure:"pad_line_comments"`
TrimTrailingWhitespace bool `mapstructure:"trim_trailing_whitespace"`
EOFNewline bool `mapstructure:"eof_newline"`
}

func DefaultConfig() *Config {
Expand Down
22 changes: 14 additions & 8 deletions formatters/basic/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,35 @@ import (
"github.com/braydonk/yaml"
"github.com/google/yamlfmt"
"github.com/google/yamlfmt/formatters/basic/anchors"
"github.com/google/yamlfmt/internal/features"
"github.com/google/yamlfmt/internal/hotfix"
"github.com/google/yamlfmt/internal/trim"
)

func ConfigureFeaturesFromConfig(config *Config) yamlfmt.FeatureList {
lineSep, err := config.LineEnding.Separator()
if err != nil {
lineSep = "\n"
}
features := []yamlfmt.Feature{}
configuredFeatures := []yamlfmt.Feature{}
if config.RetainLineBreaks || config.RetainLineBreaksSingle {
features = append(
features,
configuredFeatures = append(
configuredFeatures,
hotfix.MakeFeatureRetainLineBreak(lineSep, config.RetainLineBreaksSingle),
)
}
if config.TrimTrailingWhitespace {
features = append(
features,
trim.MakeFeatureTrimTrailingWhitespace(lineSep),
configuredFeatures = append(
configuredFeatures,
features.MakeFeatureTrimTrailingWhitespace(lineSep),
)
}
return features
if config.EOFNewline {
configuredFeatures = append(
configuredFeatures,
features.MakeFeatureEOFNewline(lineSep),
)
}
return configuredFeatures
}

// These features will directly use the `yaml.Node` type and
Expand Down
22 changes: 22 additions & 0 deletions formatters/basic/formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,25 @@ b: 2`
t.Fatalf("expected: '%s', got: '%s'", expectedYml, resultStr)
}
}

func TestEOFNewline(t *testing.T) {
config := basic.DefaultConfig()
config.RetainLineBreaks = false
config.EOFNewline = true
f := newFormatter(config)

yml := `a: 1
b: 2`
expectedYml := `a: 1
b: 2
`

result, err := f.Format([]byte(yml))
if err != nil {
t.Fatalf("expected formatting to pass, returned error: %v", err)
}
resultStr := string(result)
if resultStr != expectedYml {
t.Fatalf("expected: '%s', got: '%s'", expectedYml, resultStr)
}
}
8 changes: 8 additions & 0 deletions integrationtest/command/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,11 @@ func TestMultilineStringBug(t *testing.T) {
Update: *updateFlag,
}.Run(t)
}

func TestEOFNewline(t *testing.T) {
TestCase{
Dir: "eof_newline",
Command: yamlfmtWithArgs("-formatter eof_newline=true ."),
Update: *updateFlag,
}.Run(t)
}
2 changes: 2 additions & 0 deletions integrationtest/command/testdata/eof_newline/after/a.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# no newline at end
a: 1
2 changes: 2 additions & 0 deletions integrationtest/command/testdata/eof_newline/before/a.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# no newline at end
a: 1
Empty file.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ regex_exclude: []
formatter:
disallow_anchors: false
drop_merge_tag: false
eof_newline: false
include_document_start: true
indent: 2
indentless_arrays: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ regex_exclude: []
formatter:
disallow_anchors: false
drop_merge_tag: false
eof_newline: false
include_document_start: false
indent: 2
indentless_arrays: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ regex_exclude: []
formatter:
disallow_anchors: false
drop_merge_tag: false
eof_newline: false
include_document_start: true
indent: 2
indentless_arrays: false
Expand Down
37 changes: 37 additions & 0 deletions internal/features/eof_newline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2024 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 features

import (
"github.com/google/yamlfmt"
)

func MakeFeatureEOFNewline(linebreakStr string) yamlfmt.Feature {
return yamlfmt.Feature{
Name: "EOF Newline",
AfterAction: eofNewlineFeature(linebreakStr),
}
}

func eofNewlineFeature(linebreakStr string) yamlfmt.FeatureFunc {
return func(content []byte) ([]byte, error) {
// This check works in both linebreak modes.
if content[len(content)-1] != '\n' {
linebreakBytes := []byte(linebreakStr)
content = append(content, linebreakBytes...)
}
return content, nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package trim
package features

import (
"bufio"
Expand Down

0 comments on commit 7202c12

Please sign in to comment.