Skip to content

Commit

Permalink
feat: add flag to print resolved config
Browse files Browse the repository at this point in the history
  • Loading branch information
kachick committed May 10, 2024
1 parent 9311c40 commit dfad477
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 23 deletions.
4 changes: 4 additions & 0 deletions cmd/yamlfmt/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ operation without performing it.`)
flagConf *string = flag.String("conf", "", "Read yamlfmt config from this path")
flagGlobalConf *bool = flag.Bool("global_conf", false, fmt.Sprintf("Use global yamlfmt config from %s", globalConfFlagVar()))
flagDisableGlobalConf *bool = flag.Bool("no_global_conf", false, fmt.Sprintf("Disabled usage of global yamlfmt config from %s", globalConfFlagVar()))
flagResolvedConf *bool = flag.Bool("resolved_conf", false, "Print resolved config")
flagDoublestar *bool = flag.Bool("dstar", false, "Use doublestar globs for include and exclude")
flagQuiet *bool = flag.Bool("quiet", false, "Print minimal output to stdout")
flagContinueOnError *bool = flag.Bool("continue_on_error", false, "Continue to format files that didn't fail instead of exiting with code 1.")
Expand Down Expand Up @@ -97,6 +98,9 @@ func getOperationFromFlag() yamlfmt.Operation {
if *flagDry {
return yamlfmt.OperationDry
}
if *flagResolvedConf {
return yamlfmt.OperationPrintConfig
}
return yamlfmt.OperationFormat
}

Expand Down
63 changes: 52 additions & 11 deletions command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,61 @@ import (

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

"github.com/braydonk/yaml"
)

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

func (f *FormatterConfig) flatten() map[string]any {
flat := make(map[string]any, len(f.FormatterSettings)+1)
if f.Type == "" {
flat["type"] = yamlfmt.BasicFormatterType
} else {
flat["type"] = f.Type
}

for k, v := range f.FormatterSettings {
flat[k] = v
}

return flat
}

// NewFormatterConfig returns an empty formatter config with all fields initialized.
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"`
OutputFormat engine.EngineOutputFormat `mapstructure:"output_format"`
Extensions []string `mapstructure:"extensions" yaml:"extensions"`
Include []string `mapstructure:"include" yaml:"include"`
Exclude []string `mapstructure:"exclude" yaml:"exclude"`
RegexExclude []string `mapstructure:"regex_exclude" yaml:"regex_exclude"`
FormatterConfig *FormatterConfig `mapstructure:"formatter,omitempty" yaml:"-"`
Doublestar bool `mapstructure:"doublestar" yaml:"doublestar"`
ContinueOnError bool `mapstructure:"continue_on_error" yaml:"continue_on_error"`
LineEnding yamlfmt.LineBreakStyle `mapstructure:"line_ending" yaml:"line_ending"`
GitignoreExcludes bool `mapstructure:"gitignore_excludes" yaml:"gitignore_excludes"`
GitignorePath string `mapstructure:"gitignore_path" yaml:"gitignore_path"`
OutputFormat engine.EngineOutputFormat `mapstructure:"output_format" yaml:"output_format"`
}

func (c *Config) Marshal() ([]byte, error) {
conf, err := yaml.Marshal(c)
if err != nil {
return []byte{}, err
}
formatterConf, err := yaml.Marshal(struct {
Formatter map[string]any `yaml:"formatter"`
}{Formatter: c.FormatterConfig.flatten()})
if err != nil {
return []byte{}, err
}
return append(conf, formatterConf...), nil
}

type Command struct {
Expand Down Expand Up @@ -159,6 +190,16 @@ func (c *Command) Run() error {
return err
}
fmt.Print(string(out))
case yamlfmt.OperationPrintConfig:
conf, err := c.Config.Marshal()
if err != nil {
return err
}
formatted, err := formatter.Format(conf)
if err != nil {
return err
}
fmt.Println(string(formatted))
}

return nil
Expand Down
17 changes: 9 additions & 8 deletions docs/command-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,15 @@ All flags must be specified **before** any path arguments.

These flags adjust the command's mode of operation. All of these flags are booleans.

| Name | Flag | Example | Description |
| :------------ | :--------- | :-------------------------- | :-------------------------------------------------------- |
| Help | `-help` | `yamlfmt -help` | Print the command usage information. |
| Print Version | `-version` | `yamlfmt -version` | Print the yamlfmt version. |
| Dry Run | `-dry` | `yamlfmt -dry .` | Use [Dry Run](#dry-run) mode |
| Lint | `-lint` | `yamlfmt -lint .` | Use [Lint](#lint) mode |
| Quiet Mode | `-quiet` | `yamlfmt -dry -quiet .` | Use quiet mode. Only has effect in Dry Run or Lint modes. |
| Read Stdin | `-in` | `cat x.yaml \| yamlfmt -in` | Read input from stdin and output result to stdout. |
| Name | Flag | Example | Description |
| :------------ | :--------------- | :------------------------ | :-------------------------------------------------------- |
| Help | `-help` | `yamlfmt -help` | Print the command usage information. |
| Print Version | `-version` | `yamlfmt -version` | Print the yamlfmt version. |
| Print Config | `-resolved_conf` | `yamlfmt -resolved_conf` | Print the merged configuration to use. |
| Dry Run | `-dry` | `yamlfmt -dry .` | Use [Dry Run](#dry-run) mode |
| Lint | `-lint` | `yamlfmt -lint .` | Use [Lint](#lint) mode |
| Quiet Mode | `-quiet` | `yamlfmt -dry -quiet .` | Use quiet mode. Only has effect in Dry Run or Lint modes. |
| Read Stdin | `-in` | `cat x.yaml \| yamlfmt -in` | Read input from stdin and output result to stdout. |

### Configuration Flags

Expand Down
2 changes: 2 additions & 0 deletions docs/config-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ If the flag `-global_conf` is passed, all other steps will be circumvented and t

In the `-conf` flag, the config file can be named anything. As long as it's valid yaml, yamlfmt will read it as a config file. This can be useful for applying unique configs to different directories in a project. The automatic discovery paths do need to use one of the known names.

In the `-resolved_conf` flag, merged config values will be printed.

## Command

The command package defines the main command engine that `cmd/yamlfmt` uses. It uses the top level configuration that any run of the yamlfmt command will use.
Expand Down
1 change: 1 addition & 0 deletions engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
OperationLint
OperationDry
OperationStdin
OperationPrintConfig
)

type Engine interface {
Expand Down
2 changes: 2 additions & 0 deletions formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package yamlfmt

import "fmt"

const BasicFormatterType string = "basic"

type Formatter interface {
Type() string
Format(yamlContent []byte) ([]byte, error)
Expand Down
2 changes: 1 addition & 1 deletion formatters/basic/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
type BasicFormatterFactory struct{}

func (f *BasicFormatterFactory) Type() string {
return BasicFormatterType
return yamlfmt.BasicFormatterType
}

func (f *BasicFormatterFactory) NewFormatter(configData map[string]interface{}) (yamlfmt.Formatter, error) {
Expand Down
4 changes: 1 addition & 3 deletions formatters/basic/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ import (
"github.com/google/yamlfmt"
)

const BasicFormatterType string = "basic"

type BasicFormatter struct {
Config *Config
Features yamlfmt.FeatureList
Expand All @@ -34,7 +32,7 @@ type BasicFormatter struct {
// yamlfmt.Formatter interface

func (f *BasicFormatter) Type() string {
return BasicFormatterType
return yamlfmt.BasicFormatterType
}

func (f *BasicFormatter) Format(input []byte) ([]byte, error) {
Expand Down
8 changes: 8 additions & 0 deletions integrationtest/command/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,11 @@ func TestDryQuiet(t *testing.T) {
Update: *updateFlag,
}.Run(t)
}

func TestResolvedConf(t *testing.T) {
TestCase{
Dir: "resolved_conf",
Command: yamlfmtWithArgs("-resolved_conf -continue_on_error=true -formatter retain_line_breaks=true"),
Update: *updateFlag,
}.Run(t)
}
2 changes: 2 additions & 0 deletions integrationtest/command/testdata/resolved_conf/after/a.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: 1
2 changes: 2 additions & 0 deletions integrationtest/command/testdata/resolved_conf/before/a.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: 1
Empty file.
17 changes: 17 additions & 0 deletions integrationtest/command/testdata/resolved_conf/stdout/stdout.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
extensions:
- yaml
- yml
include: []
exclude: []
regex_exclude: []
doublestar: false
continue_on_error: true
line_ending: lf
gitignore_excludes: false
gitignore_path: .gitignore
output_format: default
formatter:
line_ending: lf
retain_line_breaks: true
type: basic

0 comments on commit dfad477

Please sign in to comment.