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

feat: gitignore support #832

Merged
merged 12 commits into from
Apr 20, 2024
Merged

feat: gitignore support #832

merged 12 commits into from
Apr 20, 2024

Conversation

dsherret
Copy link
Member

@dsherret dsherret commented Mar 17, 2024

Takes the .gitignore into account when figuring out what to format. Files that are excluded via the .gitignore can be unexcluded via a negated exclude pattern.

Breaking:

  • Negated exclude patterns are no longer inverted since they are used to unexclude an excluded gitignore pattern (but nobody should have been writing negated exclude patterns anyway... I probably just inverted them originally because I was lazy).

Closes #378
Closes #833

@dsherret
Copy link
Member Author

FYI @bradzacher, if you have the time, it would be interesting to know how this impacts Canva's codebase and if there's anything that should change in this PR to make things easier. I'm sure there's probably some edge case that this doesn't take into account.

@bradzacher
Copy link

What's the best way to grab a binary for this PR? Checkout and build?

@dsherret
Copy link
Member Author

dsherret commented Mar 26, 2024

@bradzacher oh, sorry! Yeah, checkout and build.

git clone https://github.com/dprint/dprint
gh pr checkout 832
cargo build # creates ./target/debug/dprint

@dsherret
Copy link
Member Author

dsherret commented Apr 2, 2024

I'll probably merge this one over the weekend then we can address any issues in followups.

@bradzacher
Copy link

Yeah I gotta figure out how to test this out cos we currently have everything wired into nix as a binary deployment setup.

So replacing the dprint binary without a github release url will take a sec.
I'll have time to take a look today.

@bradzacher
Copy link

bradzacher commented Apr 3, 2024

Testing the two binaries:

  • dprint 0.45.0
    • output-file-paths | wc -l 79789
  • this branch
    • output-file-paths | wc -l 79797

It looks like there are some incorrectly included files due to this behaviour.
For example we have:

{
  "includes": [
	"*.json",
    "!some/path/to/**/*.json",
  ],
}

And then

# some/path/to/a/file/.gitignore
!content.json

Currently some/path/to/a/file/content.json is ignored by dprint.
With this change it will no longer be ignored.

Another example would be that we have:

{
  "excludes": [
    "**/.vscode/*",
    "!**/.vscode/extensions.json",
    "!**/.vscode/OWNERS",
    "!**/.vscode/README.md",
    "!**/.vscode/*.css-data.json"
  ],
}

And we have

# root .gitignore

# ignore VS Code personal settings
**/.vscode/*
# except extensions recommendations
!**/.vscode/extensions.json
!**/.vscode/OWNERS
!**/.vscode/README.md
!**/.vscode/*.css-data.json

And with this change those files are now included to be formatted.

@dsherret
Copy link
Member Author

dsherret commented Apr 3, 2024

Thanks! Will investigate soon.

@bradzacher
Copy link

bradzacher commented Apr 3, 2024

One final example.
We have:

# root .gitignore

**/target

# some/folder/.gitignore

# don't exclude this target folder
!/target

And then

{
  "excludes": [
    "!web/src/ui/publish/menu/publish_app/target",
  ]
}

Those files under /target are now included --- which is technically the correct behaviour -- this is a bug in our config generation logic!

@bradzacher
Copy link

bradzacher commented Apr 3, 2024

So (as you may guess) we have config generation logic at play here.
For a .gitignore:

  • if the file is ignored then we generate an exclude for it
  • if the file is "unignored" (eg ! prefixed) then we generate a ! exclude for it

We also have logic based on .gitattributes - one can tag a path like

some/path/thats/formatted/**/*.json dprint-formatted=true
some/path/not/formatted/**/*.json dprint-formatted=false

And we generate include and ! include respectively.

The logic itself is pretty simple - it's just that it does generate a pretty cooked config file which has includes, excludes, not includes and not excludes.

@dsherret
Copy link
Member Author

Currently some/path/to/a/file/content.json is ignored by dprint.
With this change it will no longer be ignored.

Hmmm... tried this one out and it seemed to work. Maybe I'm doing something wrong in this test case: daf4c8a#diff-38287cc5b9dd24e7cd7e8e42fec4f0ece050cef16b7bcc5344138143f4e95413R493

Maybe the real world example is slightly different?

Another example would be that we have:

For this one, I'm going to go with the new behaviour because it makes unignoring gitignored files possible. Previously dprint would treat negative globs the same as positive globs in "excludes" (so it would just take the ! and remove it 😅). Now negative globs can be used as a way to unexclude gitignored files.

@dsherret dsherret marked this pull request as ready for review April 20, 2024 19:22
@dsherret
Copy link
Member Author

Going to merge this one for the time being. We can follow up with fixes after.

@dsherret dsherret merged commit 96035cd into main Apr 20, 2024
10 checks passed
@dsherret dsherret deleted the feat_gitignore_support branch April 20, 2024 19:23
@joscha
Copy link
Contributor

joscha commented Apr 20, 2024

The logic itself is pretty simple - it's just that it does generate a pretty cooked config file which has includes, excludes, not includes and not excludes.

😬 I feel compelled to say sorry at this juncture XD

@bradzacher
Copy link

Cycling back here.

A few weeks ago I was able to update our config setup to remove a whole bunch of lines. TL;DR - our Java team decided to stop using google-java-formatter (via dprint) and go back to intellij-format. So that meant there was a bunch of folder opt-ins and opt-outs that I could remove.

That change cut ~200 lines of includes (and !includes) from the dprint.json - ~20% shorter.

Last week I updated Canva to dprint 0.47.1.
Interesting to note that that upgrade in of itself made dprint match some more files - but all the newly matched files were supposed to be matched (i.e. were accidentally excluded before).

Today I updated our dprint.json generator to stop considering .gitignore files. This resulted in ~600 lines of excludes being removed -- our config is now another 65% shorter! It also caused dprint to match another 16 files that (as before) were previously accidentally excluded!

So big win all round on the config front!


I'm guessing all of this config simplification will also help us with issues like this one: #877

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dprint attempts to format files in .git First-class support for .gitignore and .gitattributes
3 participants