summaryrefslogtreecommitdiff
path: root/vendor/github.com/google/yamlfmt/command
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/google/yamlfmt/command')
-rw-r--r--vendor/github.com/google/yamlfmt/command/command.go258
1 files changed, 258 insertions, 0 deletions
diff --git a/vendor/github.com/google/yamlfmt/command/command.go b/vendor/github.com/google/yamlfmt/command/command.go
new file mode 100644
index 0000000..3224f46
--- /dev/null
+++ b/vendor/github.com/google/yamlfmt/command/command.go
@@ -0,0 +1,258 @@
+// Copyright 2022 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 command
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+
+ "github.com/google/yamlfmt"
+ "github.com/google/yamlfmt/engine"
+ "github.com/mitchellh/mapstructure"
+
+ "github.com/braydonk/yaml"
+)
+
+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)}
+}
+
+type Config struct {
+ Extensions []string `mapstructure:"extensions"`
+ MatchType yamlfmt.MatchType `mapstructure:"match_type"`
+ 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 yamlfmt.Operation
+ Registry *yamlfmt.Registry
+ Config *Config
+ Quiet bool
+}
+
+func (c *Command) Run() error {
+ formatter, err := c.getFormatter()
+ if err != nil {
+ return err
+ }
+
+ lineSepChar, err := c.Config.LineEnding.Separator()
+ if err != nil {
+ return err
+ }
+
+ eng := &engine.ConsecutiveEngine{
+ LineSepCharacter: lineSepChar,
+ Formatter: formatter,
+ Quiet: c.Quiet,
+ ContinueOnError: c.Config.ContinueOnError,
+ OutputFormat: c.Config.OutputFormat,
+ }
+
+ collectedPaths, err := c.collectPaths()
+ if err != nil {
+ return err
+ }
+ if c.Config.GitignoreExcludes {
+ newPaths, err := yamlfmt.ExcludeWithGitignore(c.Config.GitignorePath, collectedPaths)
+ if err != nil {
+ return err
+ }
+ collectedPaths = newPaths
+ }
+
+ paths, err := c.analyzePaths(collectedPaths)
+ if err != nil {
+ fmt.Printf("path analysis found the following errors:\n%v", err)
+ fmt.Println("Continuing...")
+ }
+
+ switch c.Operation {
+ case yamlfmt.OperationFormat:
+ out, err := eng.Format(paths)
+ if out != nil {
+ fmt.Print(out)
+ }
+ if err != nil {
+ return err
+ }
+ case yamlfmt.OperationLint:
+ out, err := eng.Lint(paths)
+ if err != nil {
+ return err
+ }
+ if out != nil {
+ // This will be picked up by log.Fatal in main() and
+ // cause an exit code of 1, which is a critical
+ // component of the lint functionality.
+ return errors.New(out.String())
+ }
+ case yamlfmt.OperationDry:
+ out, err := eng.DryRun(paths)
+ if err != nil {
+ return err
+ }
+ if out != nil {
+ fmt.Print(out)
+ } else if !c.Quiet {
+ fmt.Println("No files will be changed.")
+ }
+ case yamlfmt.OperationStdin:
+ stdinYaml, err := readFromStdin()
+ if err != nil {
+ return err
+ }
+ out, err := eng.FormatContent(stdinYaml)
+ if err != nil {
+ return err
+ }
+ fmt.Print(string(out))
+ case yamlfmt.OperationPrintConfig:
+ commandConfig := map[string]any{}
+ err = mapstructure.Decode(c.Config, &commandConfig)
+ if err != nil {
+ return err
+ }
+ delete(commandConfig, "formatter")
+ out, err := yaml.Marshal(commandConfig)
+ if err != nil {
+ return err
+ }
+ 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
+}
+
+func (c *Command) getFormatter() (yamlfmt.Formatter, error) {
+ var factoryType string
+
+ // In the existing codepaths, this value is always set. But
+ // it's a habit of mine to check anything that can possibly be nil
+ // if I remember that to be the case. :)
+ if c.Config.FormatterConfig != nil {
+ factoryType = c.Config.FormatterConfig.Type
+
+ // The line ending set within the formatter settings takes precedence over setting
+ // it from the top level config. If it's not set in formatter settings, then
+ // we use the value from the top level.
+ if _, ok := c.Config.FormatterConfig.FormatterSettings["line_ending"]; !ok {
+ c.Config.FormatterConfig.FormatterSettings["line_ending"] = c.Config.LineEnding
+ }
+ }
+
+ factory, err := c.Registry.GetFactory(factoryType)
+ if err != nil {
+ return nil, err
+ }
+ return factory.NewFormatter(c.Config.FormatterConfig.FormatterSettings)
+}
+
+func (c *Command) collectPaths() ([]string, error) {
+ collector, err := c.makePathCollector()
+ if err != nil {
+ return nil, err
+ }
+
+ return collector.CollectPaths()
+}
+
+func (c *Command) analyzePaths(paths []string) ([]string, error) {
+ analyzer, err := c.makeAnalyzer()
+ if err != nil {
+ return nil, err
+ }
+ includePaths, _, err := analyzer.ExcludePathsByContent(paths)
+ return includePaths, err
+}
+
+func (c *Command) makePathCollector() (yamlfmt.PathCollector, error) {
+ switch c.Config.MatchType {
+ case yamlfmt.MatchTypeDoublestar:
+ return &yamlfmt.DoublestarCollector{
+ Include: c.Config.Include,
+ Exclude: c.Config.Exclude,
+ }, nil
+ case yamlfmt.MatchTypeGitignore:
+ files := c.Config.Include
+ if len(files) == 0 {
+ files = []string{yamlfmt.DefaultPatternFile}
+ }
+
+ patternFile, err := yamlfmt.NewPatternFileCollector(files...)
+ if err != nil {
+ return nil, fmt.Errorf("NewPatternFile(%q): %w", files, err)
+ }
+
+ return patternFile, nil
+ default:
+ return &yamlfmt.FilepathCollector{
+ Include: c.Config.Include,
+ Exclude: c.Config.Exclude,
+ Extensions: c.Config.Extensions,
+ }, nil
+ }
+}
+
+func (c *Command) makeAnalyzer() (yamlfmt.ContentAnalyzer, error) {
+ return yamlfmt.NewBasicContentAnalyzer(c.Config.RegexExclude)
+}
+
+func readFromStdin() ([]byte, error) {
+ stdin := bufio.NewReader(os.Stdin)
+ data := []byte{}
+ for {
+ b, err := stdin.ReadByte()
+ if err != nil {
+ if err == io.EOF {
+ break
+ } else {
+ return nil, err
+ }
+ }
+ data = append(data, b)
+ }
+ return data, nil
+}