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

engine: add output format support #170

Merged
merged 2 commits into from
May 3, 2024
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
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ YAMLFMT_BIN ?= $(shell pwd)/dist/yamlfmt
.PHONY: integrationtest
integrationtest:
$(MAKE) build
go test -tags=integration_test ./integrationtest/command
go test -v -tags=integration_test ./integrationtest/command

.PHONY: integrationtest_v
integrationtest_v:
Expand All @@ -28,11 +28,19 @@ integrationtest_stdout:
$(MAKE) build
go test -v -tags=integration_test ./integrationtest/command -stdout

.PHONY: integrationtest_local_update
.PHONY: integrationtest_update
integrationtest_update:
$(MAKE) build
go test -tags=integration_test ./integrationtest/command -update

.PHONY: command_test_case
command_test_case:
ifndef TESTNAME
$(error "TESTNAME undefined")
endif
mkdir -p integrationtest/command/testdata/$(TESTNAME)/before && \
mkdir -p integrationtest/command/testdata/$(TESTNAME)/stdout

.PHONY: install
install:
go install ./cmd/yamlfmt
Expand Down
12 changes: 6 additions & 6 deletions cmd/yamlfmt/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func validatePath(path string) error {
}

func makeCommandConfigFromData(configData map[string]any) (*command.Config, error) {
config := command.NewConfig()
config := command.Config{FormatterConfig: command.NewFormatterConfig()}
err := mapstructure.Decode(configData, &config)
if err != nil {
return nil, err
Expand Down Expand Up @@ -253,23 +253,23 @@ func makeCommandConfigFromData(configData map[string]any) (*command.Config, erro
config.Extensions = []string{"yaml", "yml"}
}

// Default to doublestar flag if not set in config
// Apply the general rule that the config takes precedence over
// the command line flags.
if !config.Doublestar {
config.Doublestar = *flagDoublestar
}

// Default to continue_on_error flag if not set in config
if !config.ContinueOnError {
config.ContinueOnError = *flagContinueOnError
}

if !config.GitignoreExcludes {
config.GitignoreExcludes = *flagGitignoreExcludes
}

if config.GitignorePath == "" {
config.GitignorePath = *flagGitignorePath
}
if config.OutputFormat == "" {
config.OutputFormat = getOutputFormatFromFlag()
}

// Overwrite config if includes are provided through args
if len(flag.Args()) > 0 {
Expand Down
18 changes: 12 additions & 6 deletions cmd/yamlfmt/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import (
"runtime"
"strings"

"github.com/google/yamlfmt/command"
"github.com/google/yamlfmt"
"github.com/google/yamlfmt/engine"
)

var (
Expand All @@ -38,6 +39,7 @@ operation without performing it.`)
flagContinueOnError *bool = flag.Bool("continue_on_error", false, "Continue to format files that didn't fail instead of exiting with code 1.")
flagGitignoreExcludes *bool = flag.Bool("gitignore_excludes", false, "Use a gitignore file for excludes")
flagGitignorePath *string = flag.String("gitignore_path", ".gitignore", "Path to gitignore file to use")
flagOutputFormat *string = flag.String("output_format", "default", "The engine output format")
flagExclude = arrayFlag{}
flagFormatter = arrayFlag{}
flagExtensions = arrayFlag{}
Expand Down Expand Up @@ -85,17 +87,21 @@ func configureHelp() {
}
}

func getOperationFromFlag() command.Operation {
func getOperationFromFlag() yamlfmt.Operation {
if *flagIn || isStdinArg() {
return command.OperationStdin
return yamlfmt.OperationStdin
}
if *flagLint {
return command.OperationLint
return yamlfmt.OperationLint
}
if *flagDry {
return command.OperationDry
return yamlfmt.OperationDry
}
return command.OperationFormat
return yamlfmt.OperationFormat
}

func getOutputFormatFromFlag() engine.EngineOutputFormat {
return engine.EngineOutputFormat(*flagOutputFormat)
}

func isStdinArg() bool {
Expand Down
4 changes: 3 additions & 1 deletion cmd/yamlfmt/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"flag"
"fmt"
"log"
"os"

"github.com/google/yamlfmt"
"github.com/google/yamlfmt/command"
Expand All @@ -29,7 +30,8 @@ var version string = "0.11.0"

func main() {
if err := run(); err != nil {
log.Fatal(err)
l := log.New(os.Stderr, "", 0)
l.Fatal(err)
}
}

Expand Down
69 changes: 29 additions & 40 deletions command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,53 +19,38 @@ import (
"errors"
"fmt"
"io"
"log"
"os"

"github.com/google/yamlfmt"
"github.com/google/yamlfmt/engine"
)

type Operation int

const (
OperationFormat Operation = iota
OperationLint
OperationDry
OperationStdin
)

type FormatterConfig struct {
Type string `mapstructure:"type"`
FormatterSettings map[string]any `mapstructure:",remain"`
}

// NewFormatterConfig returns an empty formatter config with all fields initialized.
func NewFormatterConfig() FormatterConfig {
return FormatterConfig{FormatterSettings: make(map[string]any)}
func NewFormatterConfig() *FormatterConfig {
return &FormatterConfig{FormatterSettings: make(map[string]any)}
}

type Config struct {
Extensions []string `mapstructure:"extensions"`
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
RegexExclude []string `mapstructure:"regex_exclude"`
FormatterConfig *FormatterConfig `mapstructure:"formatter,omitempty"`
Doublestar bool `mapstructure:"doublestar"`
ContinueOnError bool `mapstructure:"continue_on_error"`
LineEnding yamlfmt.LineBreakStyle `mapstructure:"line_ending"`
GitignoreExcludes bool `mapstructure:"gitignore_excludes"`
GitignorePath string `mapstructure:"gitignore_path"`
}

// NewConfig returns an empty config with all fields initialized.
func NewConfig() Config {
formatterConfig := NewFormatterConfig()
return Config{FormatterConfig: &formatterConfig}
Extensions []string `mapstructure:"extensions"`
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
RegexExclude []string `mapstructure:"regex_exclude"`
FormatterConfig *FormatterConfig `mapstructure:"formatter,omitempty"`
Doublestar bool `mapstructure:"doublestar"`
ContinueOnError bool `mapstructure:"continue_on_error"`
LineEnding yamlfmt.LineBreakStyle `mapstructure:"line_ending"`
GitignoreExcludes bool `mapstructure:"gitignore_excludes"`
GitignorePath string `mapstructure:"gitignore_path"`
OutputFormat engine.EngineOutputFormat `mapstructure:"output_format"`
}

type Command struct {
Operation Operation
Operation yamlfmt.Operation
Registry *yamlfmt.Registry
Config *Config
Quiet bool
Expand Down Expand Up @@ -113,6 +98,7 @@ func (c *Command) Run() error {
Formatter: formatter,
Quiet: c.Quiet,
ContinueOnError: c.Config.ContinueOnError,
OutputFormat: c.Config.OutputFormat,
}

collectedPaths, err := c.collectPaths()
Expand All @@ -129,17 +115,20 @@ func (c *Command) Run() error {

paths, err := c.analyzePaths(collectedPaths)
if err != nil {
log.Printf("path analysis found the following errors:\n%v", err)
log.Println("Continuing...")
fmt.Printf("path analysis found the following errors:\n%v", err)
fmt.Println("Continuing...")
}

switch c.Operation {
case OperationFormat:
err := eng.Format(paths)
case yamlfmt.OperationFormat:
out, err := eng.Format(paths)
if out != nil {
fmt.Print(out)
}
if err != nil {
return err
}
case OperationLint:
case yamlfmt.OperationLint:
out, err := eng.Lint(paths)
if err != nil {
return err
Expand All @@ -150,17 +139,17 @@ func (c *Command) Run() error {
// component of the lint functionality.
return errors.New(out.String())
}
case OperationDry:
case yamlfmt.OperationDry:
out, err := eng.DryRun(paths)
if err != nil {
return err
}
if out.Message == "" && out.Files.ChangedCount() == 0 {
log.Print("No files will be changed.")
if out != nil {
fmt.Print(out)
} else {
log.Print(out)
fmt.Print("No files will be changed.")
}
case OperationStdin:
case yamlfmt.OperationStdin:
stdinYaml, err := readFromStdin()
if err != nil {
return err
Expand All @@ -169,7 +158,7 @@ func (c *Command) Run() error {
if err != nil {
return err
}
fmt.Print(string(out))
fmt.Print(out)
}

return nil
Expand Down
25 changes: 13 additions & 12 deletions docs/command-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,19 @@ These flags will configure the underlying behaviour of the command.

The string array flags can be a bit confusing. See the [String Array Flags](#string-array-flags) section for more information.

| Name | Flag | Type | Example | Description |
|:----------------------|:----------------------|:---------|:----------------------------------------------------------|:------------|
| Config File Path | `-conf` | string | `yamlfmt -conf ./config/.yamlfmt` | Specify a path to read a [configuration file](./config-file.md) from. |
| Global Config | `-global_conf` | bool | `yamlfmt -global_conf` | Force yamlfmt to use the configuration file from the system config directory. |
| Disable Global Config | `-no_global_conf` | bool | `yamlfmt -no_global_conf` | Disable looking for the configuration file from the system config directory. |
| Doublestar | `-dstar` | bool | `yamlfmt -dstar "**/*.yaml"` | Enable [Doublestar](./paths.md#doublestar) path collection mode. Note that doublestar patterns should be specified with quotes in bash to prevent shell expansion. |
| Exclude | `-exclude` | []string | `yamlfmt -exclude ./not/,these_paths.yaml` | Patterns to exclude from path collection. These are in addition to the exclude patterns specified in the [config file](./config-file.md) |
| Gitignore Excludes | `-gitignore_excludes` | bool | `yamlfmt -gitignore_excludes` | Use a gitignore file to exclude paths. This is in addition to otherwise specified exclude patterns. |
| Gitignore Path | `-gitignore_path` | string | `yamlfmt -gitignore_path .special_gitignore` | Specify a path to a gitignore file to use. Defaults to `.gitignore` (in working directory). |
| Extensions | `-extensions` | []string | `yamlfmt -extensions yaml,yml` | Extensions to use in standard path collection. Has no effect in Doublestar mode. These add to extensions specified in the [config file](./config-file.md)
| Formatter Config | `-formatter` | []string | `yamlfmt -formatter indent=2,include_document_start=true` | Provide configuration values for the formatter. See [Formatter Configuration Options](./config-file.md#basic-formatter) for options. Each field is specified as `configkey=value`. |
| Debug Logging | `-debug` | []string | `yamlfmt -debug paths,config` | Enable debug logging. See [Debug Logging](#debug-logging) for more information. |
| Name | Flag | Type | Example | Description |
|:----------------------|:----------------------|:------------------|:----------------------------------------------------------|:------------|
| Config File Path | `-conf` | string | `yamlfmt -conf ./config/.yamlfmt` | Specify a path to read a [configuration file](./config-file.md) from. |
| Global Config | `-global_conf` | bool | `yamlfmt -global_conf` | Force yamlfmt to use the configuration file from the system config directory. |
| Disable Global Config | `-no_global_conf` | bool | `yamlfmt -no_global_conf` | Disable looking for the configuration file from the system config directory. |
| Doublestar | `-dstar` | bool | `yamlfmt -dstar "**/*.yaml"` | Enable [Doublestar](./paths.md#doublestar) path collection mode. Note that doublestar patterns should be specified with quotes in bash to prevent shell expansion. |
| Exclude | `-exclude` | []string | `yamlfmt -exclude ./not/,these_paths.yaml` | Patterns to exclude from path collection. These are in addition to the exclude patterns specified in the [config file](./config-file.md) |
| Gitignore Excludes | `-gitignore_excludes` | bool | `yamlfmt -gitignore_excludes` | Use a gitignore file to exclude paths. This is in addition to otherwise specified exclude patterns. |
| Gitignore Path | `-gitignore_path` | string | `yamlfmt -gitignore_path .special_gitignore` | Specify a path to a gitignore file to use. Defaults to `.gitignore` (in working directory). |
| Extensions | `-extensions` | []string | `yamlfmt -extensions yaml,yml` | Extensions to use in standard path collection. Has no effect in Doublestar mode. These add to extensions specified in the [config file](./config-file.md)
| Formatter Config | `-formatter` | []string | `yamlfmt -formatter indent=2,include_document_start=true` | Provide configuration values for the formatter. See [Formatter Configuration Options](./config-file.md#basic-formatter) for options. Each field is specified as `configkey=value`. |
| Debug Logging | `-debug` | []string | `yamlfmt -debug paths,config` | Enable debug logging. See [Debug Logging](#debug-logging) for more information. |
| Output Format | `-output_format` | `default`, `line` | `yamlfmt -output_format line` | Choose a different output format. Defaults to `default`. See [Output docs](./output.md) for more information. |

#### String Array Flags

Expand Down
19 changes: 10 additions & 9 deletions docs/config-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ The command package defines the main command engine that `cmd/yamlfmt` uses. It
| Key | Type | Default | Description |
|:-------------------------|:---------------|:-------------|:------------|
| `line_ending` | `lf` or `crlf` | `crlf` on Windows, `lf` otherwise | Parse and write the file with "lf" or "crlf" line endings. This global setting will override any formatter `line_ending` options. |
| `doublestar` | bool | false | Use [doublestar](https://github.com/bmatcuk/doublestar) for include and exclude paths. (This was the default before 0.7.0) |
| `continue_on_error` | bool | false | Continue formatting and don't exit with code 1 when there is an invalid yaml file found. |
| `include` | []string | [] | The paths for the command to include for formatting. See [Specifying Paths][] for more details. |
| `exclude` | []string | [] | The paths for the command to exclude from formatting. See [Specifying Paths][] for more details. |
| `gitignore_excludes` | bool | false | Use gitignore files for exclude paths. This is in addition to the patterns from the `exclude` option. |
| `gitignore_path` | string | `.gitignore` | The path to the gitignore file to use. |
| `regex_exclude` | []string | [] | Regex patterns to match file contents for, if the file content matches the regex the file will be excluded. Use [Golang regexes](https://regex101.com/). |
| `extensions` | []string | [] | The extensions to use for standard mode path collection. See [Specifying Paths][] for more details. |
| `formatter` | map[string]any | `type: basic` | Formatter settings. See [Formatter](#formatter) for more details. |
| `doublestar` | bool | false | Use [doublestar](https://github.com/bmatcuk/doublestar) for include and exclude paths. (This was the default before 0.7.0) |
| `continue_on_error` | bool | false | Continue formatting and don't exit with code 1 when there is an invalid yaml file found. |
| `include` | []string | [] | The paths for the command to include for formatting. See [Specifying Paths][] for more details. |
| `exclude` | []string | [] | The paths for the command to exclude from formatting. See [Specifying Paths][] for more details. |
| `gitignore_excludes` | bool | false | Use gitignore files for exclude paths. This is in addition to the patterns from the `exclude` option. |
| `gitignore_path` | string | `.gitignore` | The path to the gitignore file to use. |
| `regex_exclude` | []string | [] | Regex patterns to match file contents for, if the file content matches the regex the file will be excluded. Use [Golang regexes](https://regex101.com/). |
| `extensions` | []string | [] | The extensions to use for standard mode path collection. See [Specifying Paths][] for more details. |
| `formatter` | map[string]any | `type: basic` | Formatter settings. See [Formatter](#formatter) for more details. |
| `output_format` | `default` or `line` | `default` | The output format to use. See [Output docs](./output.md) for more details. |

## Formatter

Expand Down
34 changes: 34 additions & 0 deletions docs/output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Output

The tool supports different output formats when writing to stdout/stderr. This can be configured through either a command line flag `-output_format` or through the `output_format` configuration field in the [config file](./config-file.md).

The following values are supported:

## `default`

Example:
```
The following formatting differences were found:

y.yaml:
a: a:
- b: 1 b: 1
+
z.yaml:
a: a:
- b: 1 b: 1
+
x.yaml:
a: a:
- b: 1 b: 1
+
```

## `line`

Example:
```
x.yaml: formatting difference found
y.yaml: formatting difference found
z.yaml: formatting difference found
```
Loading
Loading