Palantir Java 格式化工具
一款现代化、Lambda友好的120字符Java格式化工具。
该工具基于优秀的google-java-format,并受益于所有原作者的贡献。palantir-java-format 遵循相同的Apache 2.0 许可证。
自动格式化的优点
- 减少代码审查中的"细节"评论,让工程师专注于重要的逻辑而非纠结于空白
- 机器人生成的代码更改可自动格式化为高度可读的风格(我们大量使用refaster和error-prone)
- 提高所有代码库的一致性,使得参与其他项目时感觉更加熟悉
- 减少因琐碎原因导致的checkstyle失败构建
- 更容易培训新开发人员
自动格式化的缺点
- 如果你不喜欢格式化工具对代码的布局,可能需要引入新的函数/变量
- 格式化工具不如人类聪明,有时可能会产生可读性较差的代码(我们希望在可行的情况下修复这个问题)
许多其他编程语言已经热情地采用了格式化工具,包括typescript(prettier)、go(gofmt)、rust(rustfmt)。
动机与示例
(1) google-java-format 输出:
private static void configureResolvedVersionsWithVersionMapping(Project project) {
project.getPluginManager()
.withPlugin(
"maven-publish",
plugin -> {
project.getExtensions()
.getByType(PublishingExtension.class)
.getPublications()
.withType(MavenPublication.class)
.configureEach(
publication ->
publication.versionMapping(
mapping -> {
mapping.allVariants(
VariantVersionMappingStrategy
::fromResolutionResult);
}));
});
}
(1) palantir-java-format 输出:
private static void configureResolvedVersionsWithVersionMapping(Project project) {
project.getPluginManager().withPlugin("maven-publish", plugin -> {
project.getExtensions()
.getByType(PublishingExtension.class)
.getPublications()
.withType(MavenPublication.class)
.configureEach(publication -> publication.versionMapping(mapping -> {
mapping.allVariants(VariantVersionMappingStrategy::fromResolutionResult);
}));
});
}
(2) google-java-format 输出:
private static GradleException notFound(
String group, String name, Configuration configuration) {
String actual =
configuration.getIncoming().getResolutionResult().getAllComponents().stream()
.map(ResolvedComponentResult::getModuleVersion)
.map(
mvi ->
String.format(
"\t- %s:%s:%s",
mvi.getGroup(), mvi.getName(), mvi.getVersion()))
.collect(Collectors.joining("\n"));
// ...
}
(2) palantir-java-format 输出:
private static GradleException notFound(String group, String name, Configuration configuration) {
String actual = configuration.getIncoming().getResolutionResult().getAllComponents().stream()
.map(ResolvedComponentResult::getModuleVersion)
.map(mvi -> String.format("\t- %s:%s:%s", mvi.getGroup(), mvi.getName(), mvi.getVersion()))
.collect(Collectors.joining("\n"));
// ...
}
针对代码审查进行优化
尽管PJF有时会比其他格式化工具更倾向于内联代码,减少我们认为不必要的、对代码理解无帮助的换行,但在某些情况下,它也会将代码分成更多行,以提高清晰度和代码可审查性。
其中一个例子是长方法链。虽然其他格式化工具可能会将一个长方法调用链完全放在一行(如果能放得下),但这通常不会产生非常可读的结果:
var foo = SomeType.builder().thing1(thing1).thing2(thing2).thing3(thing3).build();
为了避免这种边缘情况,我们对链式方法调用采用80个字符的限制,即最后一个方法调用的点必须在该列之前,否则链不会内联。
var foo = SomeType.builder()
.thing1(thing1)
.thing2(thing2)
.thing3(thing3)
.build();
Palantir Java格式Gradle插件
你应该将此插件应用于所有需要格式化Java代码的项目,例如:
buildscript {
dependencies {
classpath 'com.palantir.javaformat:gradle-palantir-java-format:<版本>'
}
}
allprojects {
apply plugin: 'com.palantir.java-format'
}
应用此插件会自动配置IntelliJ,无论你是运行./gradlew idea
还是直接从IntelliJ导入项目,都会使用正确版本的格式化程序来格式化Java代码。
可以通过使用com.palantir.baseline-format Gradle插件来启用./gradlew format
。
Spotless
IntelliJ插件
palantir-java-format IntelliJ插件可从插件仓库获得。要安装它,请进入IDE设置并选择插件
类别。点击市场
标签,搜索palantir-java-format
插件,然后点击安装
按钮。
默认情况下,该插件在新项目中会被禁用,但如上所述,如果使用com.palantir.java-format
gradle插件,它将在IntelliJ中被推荐并自动配置。
要在当前项目中手动启用它,请转到文件→设置...→palantir-java-format设置
(在macOS上是IntelliJ IDEA→偏好设置...→其他设置→palantir-java-format设置
),然后勾选启用palantir-java-format
复选框。
要在新项目中默认启用它,请使用文件→其他设置→默认设置...
。
启用后,它将替换正常的重新格式化代码
操作,可以从代码
菜单触发,或使用Ctrl-Alt-L(默认)键盘快捷键。
运行IntelliJ插件的预发布版本
- 克隆此仓库
- 运行
./gradlew :idea-plugin:build
- 在IntelliJ中,从磁盘安装插件。构建产物位于
./idea-plugin/build/distributions/
未来工作
- 保留NON-NLS标记 - 这些是在实现NLS国际化时使用的注释,需要与它们所跟随的字符串保持在同一行。
许可证
(c) 版权所有 2019 Palantir Technologies Inc. 保留所有权利。
根据Apache许可证2.0版("许可证")获得许可;
除非遵守许可证,否则不得使用此文件。
你可以在以下网址获得许可证副本:
http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则根据许可证分发的软件是基于
"按原样"分发的,没有任何明示或暗示的担保或条件。
有关许可证下的特定语言管理权限和限制,请参阅许可证。
这是google-java-format的一个分支。 原始作品由Google根据相同许可证版权所有:
版权所有 2015 Google Inc.
根据Apache许可证2.0版("许可证")获得许可;
除非遵守许可证,否则不得使用此文件。
你可以在以下网址获得许可证副本:
http://www.apache.org/licenses/LICENSE-2.0
除非适用法律要求或书面同意,否则根据许可证分发的软件是基于
"按原样"分发的,没有任何明示或暗示的担保或条件。
有关许可证下的特定语言管理权限和限制,请参阅许可证。