Apache License 2.0

项目介绍

palantir/palantir-java-format 是一个托管在 GitHub 上的开源项目,主要使用 Java 编写,采用 Apache License 2.0 许可证,目前获得 924 个 Star、103 次 Fork。

仓库全名
palantir/palantir-java-format
开源许可证
Apache License 2.0
Star 数
924
Fork 数
103
未关闭 Issue
166

README 摘要

Palantir Java Format A modern, lambda-friendly, 120 character Java formatter. Eclipse plugin IntelliJ plugin Gradle plugin Spotless It is based on the excellent google-java-format, and benefits from the work of all the original authors. palantir-java-format is available under the same Apache 2.0 License. Upsides of automatic formatting reduce 'nit' comments in code reviews, allowing engineers to focus on the…

完整内容见 GitHub 原始 README 或本页 。

常见问题

palantir-java-format 用什么语言开发?

主要使用 Java 编写,采用 Apache License 2.0 许可证,目前有 924 个 Star。

palantir-java-format 可以免费商用吗?

仓库采用 Apache License 2.0 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 palantir-java-format 的源码?

可以直接克隆仓库:git clone https://github.com/palantir/palantir-java-format.git,默认分支为 develop;安装与运行步骤见仓库 README。

palantir-java-format 最近还在维护吗?

仓库最近一次更新为 2 天前,当前有 166 个未关闭 Issue;Star 数为 924,可作为社区活跃度的参考。

关于

GitHub 原始描述(英文)

A modern, lambda-friendly, 120 character Java formatter.

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
1380
价值分
602
活跃状态
活跃

语言占比

CSS
Groovy
HTML
Java
Shell
TypeScript

Release

README

Maven Central Gradle Plugin Portal Jetbrains Plugin License Autorelease

Palantir Java Format

A modern, lambda-friendly, 120 character Java formatter.

It is based on the excellent google-java-format, and benefits from the work of all the original authors. palantir-java-format is available under the same Apache 2.0 License.

Upsides of automatic formatting

  • reduce ‘nit’ comments in code reviews, allowing engineers to focus on the important logic rather than bikeshedding about whitespace
  • bot-authored code changes can be auto-formatted to a highly readable style (we use refaster and error-prone heavily)
  • increased consistency across all repos, so contributing to other projects feels familiar
  • reduce the number builds that trivially fail checkstyle
  • easier to onboard new devs

Downsides of automatic formatting

  • if you don’t like how the formatter laid out your code, you may need to introduce new functions/variables
  • the formatter is not as clever as humans are, so it can sometimes produce less readable code (we want to fix this where feasible)

Many other languages have already adopted formatters enthusiastically, including typescript (prettier), go (gofmt), rust (rustfmt).

Motivation & examples

(1) google-java-format output:

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 output:

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 output:

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 output:

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"));
    // ...
}

Optimised for code review

Even though PJF sometimes inlines code more than other formatters, reducing what we see as unnecessary breaks that don’t help code comprehension, there are also cases where it will split code into more lines too, in order to improve clarity and code reviewability.

One such case is long method chains. Whereas other formatters are content to completely one-line a long method call chain if it fits, it doesn’t usually produce a very readable result:

var foo = SomeType.builder().thing1(thing1).thing2(thing2).thing3(thing3).build();

To avoid this edge case, we employ a limit of 80 chars for chained method calls, such that the last method call dot must come before that column, or else the chain is not inlined.

var foo = SomeType.builder()
        .thing1(thing1)
        .thing2(thing2)
        .thing3(thing3)
        .build();

Palantir Java format Gradle plugin

You should apply this plugin to all projects where you want your java code formatted, e.g.

buildscript {
    dependencies {
        classpath 'com.palantir.javaformat:gradle-palantir-java-format:<version>'
    }
}
allprojects {
    apply plugin: 'com.palantir.java-format'
}

Applying this automatically configures IntelliJ, whether you run ./gradlew idea or import the project directly from IntelliJ, to use the correct version of the formatter when formatting java code.

./gradlew format can be enabled by using the com.palantir.baseline-format Gradle plugin.

Spotless

IntelliJ plugin

A palantir-java-format IntelliJ plugin is available from the plugin repository. To install it, go to your IDE’s settings and select the Plugins category. Click the Marketplace tab, search for the palantir-java-format plugin, and click the Install button.

The plugin will be disabled by default on new projects, but as mentioned above, if using the com.palantir.java-format gradle plugin, it will be recommended in IntelliJ, and automatically configured.

To manually enable it in the current project, go to File→Settings...→palantir-java-format Settings (or IntelliJ IDEA→Preferences...→Other Settings→palantir-java-format Settings on macOS) and check the Enable palantir-java-format checkbox.

To enable it by default in new projects, use File→Other Settings→Default Settings....

When enabled, it will replace the normal Reformat Code action, which can be triggered from the Code menu or with the Ctrl-Alt-L (by default) keyboard shortcut.

Running a pre-release version of the IntelliJ plugin

  1. Clone this repo
  2. run ./gradlew :idea-plugin:build
  3. In IntelliJ, install a plugin from disk. Build artifacts are located in ./idea-plugin/build/distributions/

Install plugin from disk

Java 21 Support

In 1211 we shipped Java 21 support. In order to use the Java 21 formatting capabilities, ensure that either:

  • the Gradle daemon and the Intellij Project SDK are set to Java 21
  • or that the gradle property palantir.native.formatter=true. This will run the formatter as a native image,
  • independent of the Gradle daemon/Intellij project JDK version.

Native image formatter

This comment explains why we switched to a native image for the formatter. The startup time for the native image esp. in Intellij is >10x faster than spinning up a new JVM process that does the formatting. However, the throughput of running the native image for a large set of files (eg. running ./gradlew spotlessApply) is considerably slower (eg. 30s using the Java implementation vs 1m20s using the native image implementation). Therefore, when running the formatter from spotlessApply we will default to using the Java implementation (if the Java version >= 21).

Future works

  • preserve NON-NLS markers - these are comments that are used when implementing NLS internationalisation, and need to stay on the same line with the strings they come after.

License

(c) Copyright 2019 Palantir Technologies Inc. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.

This is a fork of google-java-format. Original work copyrighted by Google under the same license:

Copyright 2015 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.

评论

暂无评论