Skip to content

Commit

Permalink
Add option to use gitignore for excludes (#158)
Browse files Browse the repository at this point in the history
* Add option to use gitignore for excludes

* I wonder how long this typo has been here

* lol this one too I guess

* more docs rewording
  • Loading branch information
braydonk committed Feb 4, 2024
1 parent f33dc61 commit b9587d5
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 31 deletions.
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
}

0 comments on commit b9587d5

Please sign in to comment.