diff --git a/settings.gradle b/settings.gradle index 9f28667..7cbc561 100644 --- a/settings.gradle +++ b/settings.gradle @@ -55,3 +55,4 @@ rootProject.name = 'immaculate' include 'wrapper' include 'wrapper:eclipse-jdt' include 'wrapper:google-java-format' +include 'wrapper:palantir-java-format' diff --git a/src/main/java/dev/lukebemish/immaculate/FormattingWorkflow.java b/src/main/java/dev/lukebemish/immaculate/FormattingWorkflow.java index 4e85401..57fbb5d 100644 --- a/src/main/java/dev/lukebemish/immaculate/FormattingWorkflow.java +++ b/src/main/java/dev/lukebemish/immaculate/FormattingWorkflow.java @@ -4,6 +4,7 @@ import dev.lukebemish.immaculate.steps.EclipseJdtFormatStep; import dev.lukebemish.immaculate.steps.GoogleJavaFormatStep; import dev.lukebemish.immaculate.steps.LinewiseStep; +import dev.lukebemish.immaculate.steps.PalantirJavaFormatStep; import org.gradle.api.Action; import org.gradle.api.Named; import org.gradle.api.NamedDomainObjectFactory; @@ -96,6 +97,10 @@ public void google(Action action) { step("google", GoogleJavaFormatStep.class, action); } + public void palantir(Action action) { + step("palantir", PalantirJavaFormatStep.class, action); + } + public void eclipse(Action action) { step("eclipse", EclipseJdtFormatStep.class, action); } @@ -129,7 +134,7 @@ public FormattingWorkflow() { registerStepType(clazz); } for (Class clazz : List.of( - GoogleJavaFormatStep.class, EclipseJdtFormatStep.class + GoogleJavaFormatStep.class, EclipseJdtFormatStep.class, PalantirJavaFormatStep.class )) { registerFormatterStepType(clazz); } diff --git a/src/main/java/dev/lukebemish/immaculate/steps/PalantirJavaFormatStep.java b/src/main/java/dev/lukebemish/immaculate/steps/PalantirJavaFormatStep.java new file mode 100644 index 0000000..4461992 --- /dev/null +++ b/src/main/java/dev/lukebemish/immaculate/steps/PalantirJavaFormatStep.java @@ -0,0 +1,56 @@ +package dev.lukebemish.immaculate.steps; + +import dev.lukebemish.immaculate.ForkFormatterSpec; +import dev.lukebemish.immaculate.ImmaculatePlugin; +import java.util.List; +import javax.inject.Inject; +import org.gradle.api.Project; +import org.gradle.api.artifacts.Dependency; +import org.gradle.api.model.ObjectFactory; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.Internal; +import org.gradle.jvm.toolchain.JavaToolchainService; + +public abstract class PalantirJavaFormatStep extends WrapperFormattingStep { + + private static final String MAVEN_PATH = "com.palantir.javaformat:palantir-java-format"; + private static final String DEFAULT_VERSION = "2.50.0"; + private static final List GOOGLE_JAVA_FORMAT_ADD_EXPORTS = List.of( + "jdk.compiler/com.sun.tools.javac.api", "jdk.compiler/com.sun.tools.javac.code", + "jdk.compiler/com.sun.tools.javac.file", "jdk.compiler/com.sun.tools.javac.parser", + "jdk.compiler/com.sun.tools.javac.tree", "jdk.compiler/com.sun.tools.javac.util" + ); + private final transient Property formatterDependency; + + @SuppressWarnings("UnstableApiUsage") + @Inject + public PalantirJavaFormatStep(final String name, final String workflowName, final Project project, final ObjectFactory objectFactory, final JavaToolchainService javaToolchainService) { + super(name, workflowName, project, objectFactory, javaToolchainService); + this.getDependencies().getRuntime().add("dev.lukebemish.immaculate.wrapper:palantir-java-format", dep -> { + if (ImmaculatePlugin.PLUGIN_VERSION != null) { + dep.version(constraint -> + constraint.require(ImmaculatePlugin.PLUGIN_VERSION) + ); + } + }); + this.formatterDependency = objectFactory.property(Dependency.class); + this.formatterDependency.convention(this.getDependencies().module(MAVEN_PATH + ":" + DEFAULT_VERSION)); + this.getDependencies().getRuntime().add(this.formatterDependency); + } + + @Internal + protected Property getGoogleJavaFormatter() { + return this.formatterDependency; + } + + @SuppressWarnings("UnstableApiUsage") + public void version(final String version) { + this.formatterDependency.set(this.getDependencies().module(MAVEN_PATH + ":" + version)); + } + + @Override + protected void configureSpec(final ForkFormatterSpec spec) { + GOOGLE_JAVA_FORMAT_ADD_EXPORTS.forEach(e -> spec.getJvmArgs().addAll("--add-exports", e + "=ALL-UNNAMED")); + spec.getWrapperClass().set("dev.lukebemish.immaculate.wrapper.palantirjavaformat.PalantirJavaFormatWrapper"); + } +} diff --git a/testproject/src/main/java/test/Test.java b/testproject/src/main/java/test/Test.java index 236a281..51cd9d7 100644 --- a/testproject/src/main/java/test/Test.java +++ b/testproject/src/main/java/test/Test.java @@ -9,4 +9,24 @@ public class Test { @Deprecated public void test() {} + + 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); + })); + }); + } } diff --git a/wrapper/palantir-java-format/build.gradle b/wrapper/palantir-java-format/build.gradle new file mode 100644 index 0000000..28129d7 --- /dev/null +++ b/wrapper/palantir-java-format/build.gradle @@ -0,0 +1,22 @@ +dependencies { + compileOnly 'com.palantir.javaformat:palantir-java-format:2.50.0' + implementation project(':wrapper') +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + managedVersioning.publishing.sign(signing, it) + managedVersioning.publishing.pom(it, github_repo, license) + pom { + name = 'Immaculate -- Palantir Java Format Wrapper' + description = 'A wrapper around the Palantir java formatter' + } + } + } +} + +tasks.named('publishCentral') { + dependsOn tasks.publish +} diff --git a/wrapper/palantir-java-format/src/main/java/dev/lukebemish/immaculate/wrapper/palantirjavaformat/PalantirJavaFormatWrapper.java b/wrapper/palantir-java-format/src/main/java/dev/lukebemish/immaculate/wrapper/palantirjavaformat/PalantirJavaFormatWrapper.java new file mode 100644 index 0000000..73ae3e5 --- /dev/null +++ b/wrapper/palantir-java-format/src/main/java/dev/lukebemish/immaculate/wrapper/palantirjavaformat/PalantirJavaFormatWrapper.java @@ -0,0 +1,47 @@ +package dev.lukebemish.immaculate.wrapper.palantirjavaformat; + +import com.palantir.javaformat.java.Main; +import dev.lukebemish.immaculate.wrapper.Wrapper; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; + +public class PalantirJavaFormatWrapper implements Wrapper { + + private final String[] args; + + public PalantirJavaFormatWrapper(final String[] args) { + this.args = args; + } + + @Override + public String format(final String fileName, final String text) { + final ByteArrayInputStream inStream = new ByteArrayInputStream(text.getBytes()); + final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + final PrintWriter outWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))); + final PrintWriter errWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.err, StandardCharsets.UTF_8))); + final var formatter = new Main(outWriter, errWriter, inStream); + final String[] fullArgs = new String[this.args.length + 1]; + fullArgs[this.args.length] = "-"; + System.arraycopy(this.args, 0, fullArgs, 0, this.args.length); + try { + final int ok = formatter.format(fullArgs); + if (ok != 0) { + throw new RuntimeException("Failed to format " + fileName + ", exit code: " + ok); + } + } catch (final Exception e) { + if (e instanceof final RuntimeException runtimeException) { + throw runtimeException; + } else { + throw new RuntimeException(e); + } + } finally { + errWriter.flush(); + outWriter.flush(); + } + return outputStream.toString(StandardCharsets.UTF_8); + } +}