-
Notifications
You must be signed in to change notification settings - Fork 460
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
Make it easy to integrate native formatters #672
Conversation
…ages to FormatterFunc.Closeable.ofDangerous(). It would be preferable to not use the dangerous method outside of test harnesses, but that doesn't need to happen right now.
Shipped in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, I can see you put a lot of work into this PR, so very well done @nedtwigg! 👏
There's just one minor documentation mistake that I found and a query I have regarding some new tests, but other that, this LGTM.
def special = [ | ||
'Npm', | ||
'Black', | ||
'Clang' | ||
] | ||
|
||
tasks.named('test') { | ||
useJUnit { excludeCategories special.collect { "com.diffplug.spotless.category.${it}Test" } as String[] } | ||
} | ||
|
||
special.forEach { | ||
def category = "com.diffplug.spotless.category.${it}Test" | ||
tasks.register("${it}Test", Test) { | ||
useJUnit { includeCategories category } | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell, these new Test
tasks are not being run on CircleCI yet (although I'd love to be corrected on this!), and regardless I think we'd need Node.js, Python and Clang installed on our CircleCI setup for those tests to work, and I can't see any CircleCI-related changes in this PR, so I'm a little confused. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another good catch! None of this is being exercised on CircleCI right now, which is a problem. I did extensive testing on my personal win and mac machines, but this should definitely be tested better.
It's easy to write a cross-platform "machine preparation script" for black
, but it's a little bit trickier for clang-format
. On mac, brew
gives you 10.0.1
and its hard to get anything else. On windows, choco
gives you 10.0.0
, and it's hard to get anything else. And those will both change over time - the llvm website seems to advertise for 12.0
, which apparently hasn't made it into package managers yet. If your team is all on the same platform (fairly common), then none of this is a problem: "just run brew install clang-format
"
It would be easy to make a docker image which has been prepared for specific versions for running blackTest
and clangTest
. However, if a contributor wants to run these tests, they'll have to do that preparation manually, which is a pain. When I went back and forth between win and mac, I just changed the versions in the tests, which isn't great.
Testing would be a lot easier if #673 and #674 were implemented. So my testing plan was: when someone has a good idea/PR for improving either of those issues, then that's when we'll run the tests on CI, since it'll be a lot easier at that point.
In the meantime, I'll commit to be being the human-test-runner for PRs which affect these native formatters, and I'm very open to a PR which adds a prepared docker image to offload that burden onto CI :D
As always, thanks very much for the review @jbduncan, very helpful and much appreciated 😃 |
@nedtwigg Sorry for the late reply, you're very welcome. I acknowledge that enabling CI for the tests for the native formatters is hard, given the lack of OS package managers' ability to download specific versions of dependencies. So I'm happy enough to leave them as a manual process! Thanks for enlightening me. |
This PR is a framework for finding native formatters, shelling out to them, and determining their version. By pinning their version, we can safely use all of our up-to-dateness and caching infrastructure. We gracefully handle the following situations:
For all of these cases, we provide actionable advice for the user, along with a complete snapshot of what went wrong with the native executable (we called with these args, we got this response, etc). It would be even better if we could install and version these formatters for the user, but that can be tackled in future PRs.
Here is how the code works:
ProcessRunner
makes it easy to efficiently and debuggably call foreign executables, and stuff their stdout into strings.ForeignExe
finds executables on the path (or other strategies), and confirms that they have the correct version (to facilitate Spotless' caching). If the executable is not present or the wrong version, it points the user towards how to fix the problem.spotless/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java
Lines 63 to 68 in 608e128
spotless/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java
Lines 84 to 91 in 608e128
spotless/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java
Lines 70 to 83 in 608e128
spotless/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java
Lines 106 to 116 in 608e128
FormatterFunc.Closeable
now has new methods which make resource-handling safer. The old method is still available asofDangerous
, but it should not be used outside of a testing situation. There are some legacy usages ofofDangerous
in the codebase, and it would be nice to fix them, but the existing usages are using it safely.