diff --git a/cmd/yamlfmt/flags.go b/cmd/yamlfmt/flags.go index 98de3c1..c6fdf96 100644 --- a/cmd/yamlfmt/flags.go +++ b/cmd/yamlfmt/flags.go @@ -34,7 +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") + flagPrintConf *bool = flag.Bool("print_conf", false, "Print 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.") @@ -98,7 +98,7 @@ func getOperationFromFlag() yamlfmt.Operation { if *flagDry { return yamlfmt.OperationDry } - if *flagResolvedConf { + if *flagPrintConf { return yamlfmt.OperationPrintConfig } return yamlfmt.OperationFormat diff --git a/command/command.go b/command/command.go index 984fb83..0813072 100644 --- a/command/command.go +++ b/command/command.go @@ -23,6 +23,7 @@ import ( "github.com/google/yamlfmt" "github.com/google/yamlfmt/engine" + "github.com/mitchellh/mapstructure" "github.com/braydonk/yaml" ) @@ -32,52 +33,23 @@ type FormatterConfig struct { 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" 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 + 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 { @@ -191,15 +163,29 @@ func (c *Command) Run() error { } fmt.Print(string(out)) case yamlfmt.OperationPrintConfig: - conf, err := c.Config.Marshal() + commandConfig := map[string]any{} + err = mapstructure.Decode(c.Config, &commandConfig) if err != nil { return err } - formatted, err := formatter.Format(conf) + delete(commandConfig, "formatter") + out, err := yaml.Marshal(commandConfig) if err != nil { return err } - fmt.Println(string(formatted)) + fmt.Print(string(out)) + + formatterConfigMap, err := formatter.ConfigMap() + if err != nil { + return err + } + out, err = yaml.Marshal(map[string]any{ + "formatter": formatterConfigMap, + }) + if err != nil { + return err + } + fmt.Print(string(out)) } return nil diff --git a/docs/command-usage.md b/docs/command-usage.md index 30907a2..3f0c6a1 100644 --- a/docs/command-usage.md +++ b/docs/command-usage.md @@ -59,15 +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. | -| 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. | +| Name | Flag | Example | Description | +| :------------ | :------------ | :-------------------------- | :-------------------------------------------------------- | +| Help | `-help` | `yamlfmt -help` | Print the command usage information. | +| Print Version | `-version` | `yamlfmt -version` | Print the yamlfmt version. | +| Print Config | `-print_conf` | `yamlfmt -print_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 diff --git a/docs/config-file.md b/docs/config-file.md index 9edc0a8..26b12aa 100644 --- a/docs/config-file.md +++ b/docs/config-file.md @@ -26,7 +26,7 @@ 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. +In the `-print_conf` flag, merged config values will be printed. ## Command diff --git a/formatter.go b/formatter.go index 42cdedc..2a17475 100644 --- a/formatter.go +++ b/formatter.go @@ -16,11 +16,10 @@ package yamlfmt import "fmt" -const BasicFormatterType string = "basic" - type Formatter interface { Type() string Format(yamlContent []byte) ([]byte, error) + ConfigMap() (map[string]any, error) } type Factory interface { diff --git a/formatters/basic/factory.go b/formatters/basic/factory.go index 147059b..eb536b0 100644 --- a/formatters/basic/factory.go +++ b/formatters/basic/factory.go @@ -22,7 +22,7 @@ import ( type BasicFormatterFactory struct{} func (f *BasicFormatterFactory) Type() string { - return yamlfmt.BasicFormatterType + return BasicFormatterType } func (f *BasicFormatterFactory) NewFormatter(configData map[string]interface{}) (yamlfmt.Formatter, error) { diff --git a/formatters/basic/formatter.go b/formatters/basic/formatter.go index 61f9eb4..377409b 100644 --- a/formatters/basic/formatter.go +++ b/formatters/basic/formatter.go @@ -21,8 +21,11 @@ import ( "github.com/braydonk/yaml" "github.com/google/yamlfmt" + "github.com/mitchellh/mapstructure" ) +const BasicFormatterType string = "basic" + type BasicFormatter struct { Config *Config Features yamlfmt.FeatureList @@ -32,7 +35,7 @@ type BasicFormatter struct { // yamlfmt.Formatter interface func (f *BasicFormatter) Type() string { - return yamlfmt.BasicFormatterType + return BasicFormatterType } func (f *BasicFormatter) Format(input []byte) ([]byte, error) { @@ -111,3 +114,13 @@ func (f *BasicFormatter) getNewEncoder(buf *bytes.Buffer) *yaml.Encoder { return e } + +func (f *BasicFormatter) ConfigMap() (map[string]any, error) { + configMap := map[string]any{} + err := mapstructure.Decode(f.Config, &configMap) + if err != nil { + return nil, err + } + configMap["type"] = BasicFormatterType + return configMap, err +} diff --git a/integrationtest/command/command_test.go b/integrationtest/command/command_test.go index 413ce8c..836c4d1 100644 --- a/integrationtest/command/command_test.go +++ b/integrationtest/command/command_test.go @@ -101,10 +101,25 @@ func TestDryQuiet(t *testing.T) { }.Run(t) } -func TestResolvedConf(t *testing.T) { +func TestPrintConfFlags(t *testing.T) { TestCase{ - Dir: "resolved_conf", - Command: yamlfmtWithArgs("-resolved_conf -continue_on_error=true -formatter retain_line_breaks=true"), + Dir: "print_conf_flags", + Command: yamlfmtWithArgs("-print_conf -continue_on_error=true -formatter retain_line_breaks=true"), + Update: *updateFlag, + }.Run(t) +} + +func TestPrintConfFile(t *testing.T) { + TestCase{ + Dir: "print_conf_file", + Command: yamlfmtWithArgs("-print_conf"), + Update: *updateFlag, + }.Run(t) +} +func TestPrintConfFlagsAndFile(t *testing.T) { + TestCase{ + Dir: "print_conf_flags_and_file", + Command: yamlfmtWithArgs("-print_conf -continue_on_error=true -formatter retain_line_breaks=true"), Update: *updateFlag, }.Run(t) } diff --git a/integrationtest/command/testdata/resolved_conf/after/a.yaml b/integrationtest/command/testdata/print_conf_file/after/a.yaml similarity index 100% rename from integrationtest/command/testdata/resolved_conf/after/a.yaml rename to integrationtest/command/testdata/print_conf_file/after/a.yaml diff --git a/integrationtest/command/testdata/resolved_conf/before/a.yaml b/integrationtest/command/testdata/print_conf_file/before/a.yaml similarity index 100% rename from integrationtest/command/testdata/resolved_conf/before/a.yaml rename to integrationtest/command/testdata/print_conf_file/before/a.yaml diff --git a/integrationtest/command/testdata/resolved_conf/stdout/stderr.txt b/integrationtest/command/testdata/print_conf_file/stdout/stderr.txt similarity index 100% rename from integrationtest/command/testdata/resolved_conf/stdout/stderr.txt rename to integrationtest/command/testdata/print_conf_file/stdout/stderr.txt diff --git a/integrationtest/command/testdata/print_conf_file/stdout/stdout.txt b/integrationtest/command/testdata/print_conf_file/stdout/stdout.txt new file mode 100644 index 0000000..10e2412 --- /dev/null +++ b/integrationtest/command/testdata/print_conf_file/stdout/stdout.txt @@ -0,0 +1,26 @@ +continue_on_error: false +doublestar: true +exclude: + - '**/templates/*.yaml' +extensions: + - yaml + - yml +gitignore_excludes: false +gitignore_path: .my_gitignore +include: [] +line_ending: crlf +output_format: default +regex_exclude: [] +formatter: + disallow_anchors: false + drop_merge_tag: false + include_document_start: true + indent: 2 + indentless_arrays: false + line_ending: crlf + max_line_length: 0 + pad_line_comments: 1 + retain_line_breaks: false + retain_line_breaks_single: true + scan_folded_as_literal: false + type: basic diff --git a/integrationtest/command/testdata/print_conf_flags/after/a.yaml b/integrationtest/command/testdata/print_conf_flags/after/a.yaml new file mode 100755 index 0000000..967c940 --- /dev/null +++ b/integrationtest/command/testdata/print_conf_flags/after/a.yaml @@ -0,0 +1,2 @@ +a: + b: 1 \ No newline at end of file diff --git a/integrationtest/command/testdata/print_conf_flags/before/a.yaml b/integrationtest/command/testdata/print_conf_flags/before/a.yaml new file mode 100644 index 0000000..967c940 --- /dev/null +++ b/integrationtest/command/testdata/print_conf_flags/before/a.yaml @@ -0,0 +1,2 @@ +a: + b: 1 \ No newline at end of file diff --git a/integrationtest/command/testdata/print_conf_flags/stdout/stderr.txt b/integrationtest/command/testdata/print_conf_flags/stdout/stderr.txt new file mode 100755 index 0000000..e69de29 diff --git a/integrationtest/command/testdata/print_conf_flags/stdout/stdout.txt b/integrationtest/command/testdata/print_conf_flags/stdout/stdout.txt new file mode 100644 index 0000000..19fdf6c --- /dev/null +++ b/integrationtest/command/testdata/print_conf_flags/stdout/stdout.txt @@ -0,0 +1,25 @@ +continue_on_error: true +doublestar: false +exclude: [] +extensions: + - yaml + - yml +gitignore_excludes: false +gitignore_path: .gitignore +include: [] +line_ending: lf +output_format: default +regex_exclude: [] +formatter: + disallow_anchors: false + drop_merge_tag: false + include_document_start: false + indent: 2 + indentless_arrays: false + line_ending: lf + max_line_length: 0 + pad_line_comments: 1 + retain_line_breaks: true + retain_line_breaks_single: false + scan_folded_as_literal: false + type: basic diff --git a/integrationtest/command/testdata/print_conf_flags_and_file/after/a.yaml b/integrationtest/command/testdata/print_conf_flags_and_file/after/a.yaml new file mode 100755 index 0000000..967c940 --- /dev/null +++ b/integrationtest/command/testdata/print_conf_flags_and_file/after/a.yaml @@ -0,0 +1,2 @@ +a: + b: 1 \ No newline at end of file diff --git a/integrationtest/command/testdata/print_conf_flags_and_file/before/a.yaml b/integrationtest/command/testdata/print_conf_flags_and_file/before/a.yaml new file mode 100644 index 0000000..967c940 --- /dev/null +++ b/integrationtest/command/testdata/print_conf_flags_and_file/before/a.yaml @@ -0,0 +1,2 @@ +a: + b: 1 \ No newline at end of file diff --git a/integrationtest/command/testdata/print_conf_flags_and_file/stdout/stderr.txt b/integrationtest/command/testdata/print_conf_flags_and_file/stdout/stderr.txt new file mode 100755 index 0000000..e69de29 diff --git a/integrationtest/command/testdata/print_conf_flags_and_file/stdout/stdout.txt b/integrationtest/command/testdata/print_conf_flags_and_file/stdout/stdout.txt new file mode 100644 index 0000000..777d2ac --- /dev/null +++ b/integrationtest/command/testdata/print_conf_flags_and_file/stdout/stdout.txt @@ -0,0 +1,26 @@ +continue_on_error: true +doublestar: true +exclude: + - '**/templates/*.yaml' +extensions: + - yaml + - yml +gitignore_excludes: false +gitignore_path: .my_gitignore +include: [] +line_ending: crlf +output_format: default +regex_exclude: [] +formatter: + disallow_anchors: false + drop_merge_tag: false + include_document_start: true + indent: 2 + indentless_arrays: false + line_ending: crlf + max_line_length: 0 + pad_line_comments: 1 + retain_line_breaks: true + retain_line_breaks_single: true + scan_folded_as_literal: false + type: basic diff --git a/integrationtest/command/testdata/resolved_conf/stdout/stdout.txt b/integrationtest/command/testdata/resolved_conf/stdout/stdout.txt deleted file mode 100644 index 48c5ff2..0000000 --- a/integrationtest/command/testdata/resolved_conf/stdout/stdout.txt +++ /dev/null @@ -1,17 +0,0 @@ -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 -