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

Add option to use gitignore for excludes #158

Merged
merged 4 commits into from
Feb 4, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions cmd/yamlfmt/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,14 @@ func makeCommandConfigFromData(configData map[string]any) (*command.Config, erro
config.ContinueOnError = *flagContinueOnError
}

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

if config.GitignorePath == "" {
config.GitignorePath = *flagGitignorePath
}

// Overwrite config if includes are provided through args
if len(flag.Args()) > 0 {
config.Include = flag.Args()
Expand Down
2 changes: 2 additions & 0 deletions cmd/yamlfmt/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ operation without performing it.`)
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.")
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")
flagExclude = arrayFlag{}
flagFormatter = arrayFlag{}
flagExtensions = arrayFlag{}
Expand Down
26 changes: 18 additions & 8 deletions command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@ func NewFormatterConfig() FormatterConfig {
}

type Config struct {
Extensions []string `mapstructure:"extensions"`
Include []string `mapstructure:"include"`
Exclude []string `mapstructure:"exclude"`
RegexExclude []string `mapstructure:"regex_exclude"`
Doublestar bool `mapstructure:"doublestar"`
ContinueOnError bool `mapstructure:"continue_on_error"`
LineEnding yamlfmt.LineBreakStyle `mapstructure:"line_ending"`
FormatterConfig *FormatterConfig `mapstructure:"formatter,omitempty"`
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.
Expand Down Expand Up @@ -117,6 +119,14 @@ func (c *Command) Run() error {
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 {
log.Printf("path analysis found the following errors:\n%v", err)
Expand Down
22 changes: 12 additions & 10 deletions docs/command-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,18 @@ 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 | `-global_conf`| bool | `yamlfmt -no_global_conf` | Disable looking for the configuration file from the system config directory. |
| Doublstar | `-dstar` | boolean | `yamlfmt -dstar "**/*.yaml"` | Enable [Doublstar](./paths.md#doublestar) path collection mode. |
| Exclude | `-exclude` | []string | `yamlfmt -exclude ./not/,these_paths.yaml` | Patterns to exclude from path collection. These add to exclude patterns specified in the [config file](./config-file.md) |
| 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. |

#### String Array Flags

Expand Down
20 changes: 11 additions & 9 deletions docs/config-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ The command package defines the main command engine that `cmd/yamlfmt` uses. It

### Configuration

| Key | Type | Default | Description |
|:-------------------------|:---------------|:--------|:------------|
| 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. |
| `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 | default basic formatter | 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. |

## Formatter

Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ require (
github.com/RageCage64/multilinediff v0.2.0
github.com/bmatcuk/doublestar/v4 v4.6.0
github.com/braydonk/yaml v0.7.0
github.com/google/go-cmp v0.5.9
github.com/mitchellh/mapstructure v1.5.0
github.com/google/go-cmp v0.5.9
)

require github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvz
github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/braydonk/yaml v0.7.0 h1:ySkqO7r0MGoCNhiRJqE0Xe9yhINMyvOAB3nFjgyJn2k=
github.com/braydonk/yaml v0.7.0/go.mod h1:hcm3h581tudlirk8XEUPDBAimBPbmnL0Y45hCRl47N4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
12 changes: 10 additions & 2 deletions integrationtest/command/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ func TestMain(m *testing.M) {
m.Run()
}

func yamlfmtWithArgs(args string) string {
return fmt.Sprintf("%s -no_global_conf %s", yamlfmtBin, args)
}

func TestPathArg(t *testing.T) {
command.TestCase{
Dir: "path_arg",
Expand All @@ -43,6 +47,10 @@ func TestIncludeDocumentStart(t *testing.T) {
}.Run(t)
}

func yamlfmtWithArgs(args string) string {
return fmt.Sprintf("%s -no_global_conf %s", yamlfmtBin, args)
func TestGitignore(t *testing.T) {
command.TestCase{
Dir: "gitignore",
Command: yamlfmtWithArgs("-gitignore_excludes -gitignore_path .test_gitignore ."),
Update: *updateFlag,
}.Run(t)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
not_this_file.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
not_this_file.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
a:
b: 1
21 changes: 20 additions & 1 deletion path_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/bmatcuk/doublestar/v4"
"github.com/google/yamlfmt/internal/collections"
"github.com/google/yamlfmt/internal/logger"
ignore "github.com/sabhiram/go-gitignore"
)

type PathCollector interface {
Expand Down Expand Up @@ -73,7 +74,7 @@ func (c *FilepathCollector) CollectPaths() ([]string, error) {
}

pathsToFormatSlice := pathsToFormat.ToSlice()
logger.Debug(logger.DebugCodePaths, "paths to format: %s", pathsToFormatSlice)
logger.Debug(logger.DebugCodePaths, "paths to format: %s", pathsToFormat)
return pathsToFormatSlice, nil
}

Expand Down Expand Up @@ -146,3 +147,21 @@ func (c *DoublestarCollector) CollectPaths() ([]string, error) {
logger.Debug(logger.DebugCodePaths, "paths to format: %s", pathsToFormat)
return pathsToFormat, nil
}

func ExcludeWithGitignore(gitignorePath string, paths []string) ([]string, error) {
logger.Debug(logger.DebugCodePaths, "excluding paths with gitignore: %s", gitignorePath)
ignorer, err := ignore.CompileIgnoreFile(gitignorePath)
if err != nil {
return nil, err
}
pathsToFormat := []string{}
for _, path := range paths {
if ok, pattern := ignorer.MatchesPathHow(path); !ok {
pathsToFormat = append(pathsToFormat, path)
} else {
logger.Debug(logger.DebugCodePaths, "pattern %s matches %s, excluding", pattern.Line, path)
}
}
logger.Debug(logger.DebugCodePaths, "paths to format: %s", pathsToFormat)
return pathsToFormat, nil
}