Skip to content

Commit

Permalink
Improvement: Load palantir-java-format dynamically (#989)
Browse files Browse the repository at this point in the history
Load palantir-java-format dynamically from the same configuration set up by `com.palantir-java-format` which is also used to determine the version used by IntelliJ.
  • Loading branch information
dansanduleac authored and bulldozer-bot[bot] committed Oct 22, 2019
1 parent f124d2c commit 7ccb307
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 36 deletions.
7 changes: 7 additions & 0 deletions changelog/@unreleased/pr-989.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type: improvement
improvement:
description: Load palantir-java-format dynamically from the same configuration set
up by `com.palantir-java-format` which is also used to determine the version used
by IntelliJ.
links:
- https://github.com/palantir/gradle-baseline/pull/989
2 changes: 1 addition & 1 deletion gradle-baseline-java/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ dependencies {
compile 'net.ltgt.gradle:gradle-errorprone-plugin'
compile 'org.apache.maven.shared:maven-dependency-analyzer'
compile 'org.github.ngbinh.scalastyle:gradle-scalastyle-plugin_2.11'
implementation 'com.palantir.javaformat:palantir-java-format'
implementation 'com.palantir.javaformat:palantir-java-format-spi'
implementation 'com.palantir.javaformat:gradle-palantir-java-format'

testCompile gradleTestKit()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ public void apply(Project project) {
rootProject.getPluginManager().apply(BaselineConfig.class);
rootProject.getPluginManager().apply(BaselineCircleCi.class);
if (BaselineFormat.palantirJavaFormatterEnabled(project)) {
// This plugin currently sets up IntelliJ but could set up eclipse too in the future, so it doesn't
// belong in BaselineIdea.
rootProject.getPluginManager().apply("com.palantir.java-format");
rootProject.getPluginManager().apply("com.palantir.java-format-provider");
rootProject.getPluginManager().apply("com.palantir.java-format-idea");
}
rootProject.allprojects(proj -> {
proj.getPluginManager().apply(BaselineCheckstyle.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
package com.palantir.baseline.plugins;

import com.diffplug.gradle.spotless.SpotlessExtension;
import com.diffplug.spotless.FormatterFunc;
import com.palantir.javaformat.java.Formatter;
import com.palantir.javaformat.java.JavaFormatterOptions;
import com.palantir.javaformat.java.JavaFormatterOptions.Style;
import com.google.common.base.Preconditions;
import com.palantir.baseline.plugins.format.PalantirJavaFormatStep;
import com.palantir.javaformat.gradle.JavaFormatExtension;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -52,11 +51,8 @@ public void apply(Project project) {
spotlessExtension.java(java -> {
// Configure a lazy FileCollection then pass it as the target
ConfigurableFileCollection allJavaFiles = project.files();
project
.getConvention()
.getPlugin(JavaPluginConvention.class)
.getSourceSets()
.all(sourceSet -> allJavaFiles.from(
project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets().all(
sourceSet -> allJavaFiles.from(
sourceSet.getAllJava().filter(file -> !file.toString().contains(GENERATED_MARKER))));

java.target(allJavaFiles);
Expand All @@ -67,15 +63,24 @@ public void apply(Project project) {
if (eclipseFormattingEnabled(project) && palantirJavaFormatterEnabled(project)) {
throw new GradleException(
"Can't use both eclipse and palantir-java-format at the same time, please delete one of "
+ ECLIPSE_FORMATTING + " or " + PJF_PROPERTY + " from your gradle.properties");
+ ECLIPSE_FORMATTING
+ " or "
+ PJF_PROPERTY
+ " from your gradle.properties");
}

if (eclipseFormattingEnabled(project)) {
java.eclipse().configFile(project.file(eclipseXml.toString()));
}

if (palantirJavaFormatterEnabled(project)) {
java.customLazy("palantir-java-format", PalantirJavaFormatterFunc::new);
Preconditions.checkState(
project.getRootProject().getPluginManager().hasPlugin("com.palantir.java-format-provider"),
"Must apply `com.palantir.baseline` to root project when setting '%s'",
PJF_PROPERTY);
java.addStep(PalantirJavaFormatStep.create(
project.getRootProject().getConfigurations().getByName("palantirJavaFormat"),
project.getRootProject().getExtensions().getByType(JavaFormatExtension.class)));
}

java.trimTrailingWhitespace();
Expand All @@ -99,7 +104,7 @@ public void apply(Project project) {
});
project.getTasks().withType(JavaCompile.class).configureEach(spotlessJava::mustRunAfter);

//re-enable spotless checking, but lazily so it doesn't eagerly configure everything else
// re-enable spotless checking, but lazily so it doesn't eagerly configure everything else
project.getTasks().named(JavaBasePlugin.CHECK_TASK_NAME).configure(t -> {
t.dependsOn(project.getTasks().named("spotlessCheck"));
});
Expand All @@ -118,14 +123,4 @@ static boolean palantirJavaFormatterEnabled(Project project) {
static Path eclipseConfigFile(Project project) {
return project.getRootDir().toPath().resolve(".baseline/spotless/eclipse.xml");
}

private static class PalantirJavaFormatterFunc implements FormatterFunc {
private static final JavaFormatterOptions OPTIONS =
JavaFormatterOptions.builder().style(Style.PALANTIR).build();

@Override
public String apply(String input) throws Exception {
return Formatter.createFormatter(OPTIONS).formatSourceAndFixImports(input);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* (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.
*/

package com.palantir.baseline.plugins.format;

import com.diffplug.spotless.FileSignature;
import com.diffplug.spotless.FormatterFunc;
import com.diffplug.spotless.FormatterStep;
import com.google.common.base.Suppliers;
import com.palantir.javaformat.gradle.JavaFormatExtension;
import com.palantir.javaformat.java.FormatterService;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.function.Supplier;
import org.gradle.api.artifacts.Configuration;

public final class PalantirJavaFormatStep {

private static final String IMPL_CLASS = "com.palantir.javaformat.java.Formatter";

private PalantirJavaFormatStep() {}

private static final String NAME = "palantir-java-format";

/** Creates a step which formats everything - code, import order, and unused imports. */
public static FormatterStep create(Configuration palantirJavaFormat, JavaFormatExtension extension) {
ensureImplementationNotDirectlyLoadable();
Supplier<FormatterService> memoizedService = Suppliers.memoize(extension::serviceLoad);
return FormatterStep.createLazy(
NAME, () -> new State(palantirJavaFormat.getFiles(), memoizedService), State::createFormat);
}

static final class State implements Serializable {
private static final long serialVersionUID = 1L;

// Kept for state serialization purposes.
@SuppressWarnings("unused")
private final String stepName = NAME;

// Kept for state serialization purposes.
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final FileSignature jarsSignature;

// Transient as this is not serializable.
private final transient Supplier<FormatterService> memoizedFormatter;

/**
* Build a cacheable state for spotless from the given jars, that uses the given {@link FormatterService}.
*
* @param jars The jars that contain the palantir-java-format implementation. This is only used for caching and
* up-to-dateness purposes.
*/
State(Iterable<File> jars, Supplier<FormatterService> memoizedFormatter) throws IOException {
this.jarsSignature = FileSignature.signAsSet(jars);
this.memoizedFormatter = memoizedFormatter;
}

@SuppressWarnings("NullableProblems")
FormatterFunc createFormat() {
return memoizedFormatter.get()::formatSourceReflowStringsAndFixImports;
}
}

private static void ensureImplementationNotDirectlyLoadable() {
try {
PalantirJavaFormatStep.class.getClassLoader().loadClass(IMPL_CLASS);
} catch (ClassNotFoundException e) {
// expected
return;
}
throw new RuntimeException("Expected not be be able to load "
+ IMPL_CLASS
+ " via main class loader but was able to. Please ensure that `buildscript.configurations.classpath`"
+ " doesn't depend on `com.palantir.javaformat:palantir-java-format`.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,14 @@ class BaselineFormatIntegrationTest extends AbstractPluginTest {
buildFile << """
plugins {
id 'java'
id 'com.palantir.java-format'
id 'com.palantir.baseline-format'
}
repositories {
// to resolve the `palantirJavaFormat` configuration
maven { url 'https://dl.bintray.com/palantir/releases' }
jcenter()
}
""".stripIndent()
file('gradle.properties') << "com.palantir.baseline-format.palantir-java-format=true\n"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@
class MultilineStringConstant {

// NON-NLS comments are required for i18n, it's important they are kept with their strings.
private static final String MULTIPLE_LINE_NON_NLS = "field_0,"
+ //$NON-NLS-1$
"field_1,"
+ //$NON-NLS-1$
"field_2,"
+ //$NON-NLS-1$
"field_3,"
+ //$NON-NLS-1$
"field_4"; //$NON-NLS-1$
private static final String MULTIPLE_LINE_NON_NLS = "field_0," //$NON-NLS-1$
+ "field_1," //$NON-NLS-1$
+ "field_2," //$NON-NLS-1$
+ "field_3," //$NON-NLS-1$
+ "field_4"; //$NON-NLS-1$

private static final String MULTIPLE_LINE_NO_COMMENT =
"field_0," + "field_1," + "field_2," + "field_3," + "field_4";
Expand Down
2 changes: 1 addition & 1 deletion versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ com.google.errorprone:error_prone_test_helpers = 2.3.3
com.google.guava:guava = 27.1-jre
com.netflix.nebula:nebula-dependency-recommender = 9.0.0
com.palantir.configurationresolver:gradle-configuration-resolver-plugin = 0.4.0
com.palantir.javaformat:* = 0.2.7
com.palantir.javaformat:* = 0.3.0
com.palantir.safe-logging:* = 1.11.0
org.apache.maven.shared:maven-dependency-analyzer = 1.11.1
org.github.ngbinh.scalastyle:gradle-scalastyle-plugin_2.11 = 1.0.1
Expand Down

0 comments on commit 7ccb307

Please sign in to comment.