diff --git a/build.gradle b/build.gradle index 771501ed5..bc2dc8793 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,3 @@ -import com.palantir.javaformat.java.* - buildscript { repositories { maven { url "https://palantir.bintray.com/releases" } diff --git a/changelog/@unreleased/pr-26.v2.yml b/changelog/@unreleased/pr-26.v2.yml new file mode 100644 index 000000000..edac14a6f --- /dev/null +++ b/changelog/@unreleased/pr-26.v2.yml @@ -0,0 +1,6 @@ +type: improvement +improvement: + description: When using the gradle plugin, users will receive a notification to + install the IntelliJ plugin + links: + - https://github.com/palantir/palantir-java-format/pull/26 diff --git a/gradle-palantir-java-format/build.gradle b/gradle-palantir-java-format/build.gradle index 54facc5be..8f7956944 100644 --- a/gradle-palantir-java-format/build.gradle +++ b/gradle-palantir-java-format/build.gradle @@ -20,3 +20,9 @@ gradlePlugin { } } } + +idea { + module { + sourceDirs += sourceSets.main.groovy.srcDirs + } +} diff --git a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigureExternalDependenciesXml.java b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigureExternalDependenciesXml.java new file mode 100644 index 000000000..72cd43b08 --- /dev/null +++ b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigureExternalDependenciesXml.java @@ -0,0 +1,14 @@ +package com.palantir.javaformat.gradle; + +import groovy.util.Node; + +public class ConfigureExternalDependenciesXml extends UpdateIntellijXmlTask { + public ConfigureExternalDependenciesXml() { + getXmlFile().set(getProject().file(".idea/externalDependencies.xml")); + } + + @Override + protected final void configure(Node rootNode) { + ConfigureJavaFormatterXml.configureExternalDependencies(rootNode); + } +} diff --git a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigureJavaFormatterXml.groovy b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigureJavaFormatterXml.groovy index 2a25a0cd2..d3f75f3f7 100644 --- a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigureJavaFormatterXml.groovy +++ b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigureJavaFormatterXml.groovy @@ -1,7 +1,7 @@ package com.palantir.javaformat.gradle class ConfigureJavaFormatterXml { - static void configure(Node rootNode, List uris) { + static void configureJavaFormat(Node rootNode, List uris) { def settings = matchOrCreateChild(rootNode, 'component', [name: 'PalantirJavaFormatSettings']) // enable matchOrCreateChild(settings, 'option', [name: 'enabled']).attributes().put('value', 'true') @@ -14,6 +14,11 @@ class ConfigureJavaFormatterXml { } } + static void configureExternalDependencies(Node rootNode) { + def externalDependencies = matchOrCreateChild(rootNode, 'component', [name: 'ExternalDependencies']) + matchOrCreateChild(externalDependencies, 'plugin', [id: 'palantir-java-format']) + } + private static Node matchOrCreateChild(Node base, String name, Map attributes = [:], Map defaults = [:]) { def child = base[name].find { it.attributes().entrySet().containsAll(attributes.entrySet()) } if (child) { diff --git a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigurePalantirJavaFormatXml.java b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigurePalantirJavaFormatXml.java index 4194ac80b..6b41e5c76 100644 --- a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigurePalantirJavaFormatXml.java +++ b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/ConfigurePalantirJavaFormatXml.java @@ -1,30 +1,15 @@ package com.palantir.javaformat.gradle; -import com.google.common.collect.ImmutableMap; -import com.google.common.io.Files; import groovy.util.Node; -import groovy.util.XmlNodePrinter; -import groovy.util.XmlParser; -import java.io.BufferedWriter; import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; import java.net.URI; -import java.nio.charset.Charset; import java.util.List; import java.util.stream.Collectors; -import javax.xml.parsers.ParserConfigurationException; -import org.gradle.api.DefaultTask; import org.gradle.api.artifacts.Configuration; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Classpath; -import org.gradle.api.tasks.OutputFile; -import org.gradle.api.tasks.PathSensitive; -import org.gradle.api.tasks.PathSensitivity; -import org.gradle.api.tasks.TaskAction; -import org.xml.sax.SAXException; -public class ConfigurePalantirJavaFormatXml extends DefaultTask { +public class ConfigurePalantirJavaFormatXml extends UpdateIntellijXmlTask { private final Property implConfiguration = getProject().getObjects().property(Configuration.class); @Classpath @@ -32,36 +17,13 @@ Property getImplConfiguration() { return implConfiguration; } - @PathSensitive(PathSensitivity.RELATIVE) - @OutputFile - File getOutputFile() { - return getProject().file(".idea/palantir-java-format.xml"); + public ConfigurePalantirJavaFormatXml() { + getXmlFile().set(getProject().file(".idea/palantir-java-format.xml")); } - @TaskAction - public void run() { - File configurationFile = getOutputFile(); - Node rootNode; - if (configurationFile.isFile()) { - try { - rootNode = new XmlParser().parse(configurationFile); - } catch (IOException | SAXException | ParserConfigurationException e) { - throw new RuntimeException("Couldn't parse existing configuration file: " + configurationFile, e); - } - } else { - rootNode = new Node(null, "project", ImmutableMap.of("version", "4")); - } - + @Override + protected final void configure(Node rootNode) { List uris = implConfiguration.get().getFiles().stream().map(File::toURI).collect(Collectors.toList()); - ConfigureJavaFormatterXml.configure(rootNode, uris); - - try (BufferedWriter writer = Files.newWriter(configurationFile, Charset.defaultCharset()); - PrintWriter printWriter = new PrintWriter(writer)) { - XmlNodePrinter nodePrinter = new XmlNodePrinter(printWriter); - nodePrinter.setPreserveWhitespace(true); - nodePrinter.print(rootNode); - } catch (IOException e) { - throw new RuntimeException("Failed to write back to configuration file: " + configurationFile, e); - } + ConfigureJavaFormatterXml.configureJavaFormat(rootNode, uris); } } diff --git a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/JavaFormatPlugin.java b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/JavaFormatPlugin.java index 18bd40954..1d56e0452 100644 --- a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/JavaFormatPlugin.java +++ b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/JavaFormatPlugin.java @@ -24,8 +24,10 @@ import java.util.stream.Collectors; import org.gradle.api.Plugin; import org.gradle.api.Project; +import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.plugins.ExtensionAware; +import org.gradle.api.provider.Provider; import org.gradle.plugins.ide.idea.model.IdeaModel; import org.jetbrains.gradle.ext.TaskTriggersConfig; @@ -68,21 +70,31 @@ private static void configureLegacyIdea(Project project, Configuration implConfi ideaModel.getProject().getIpr().withXml(xmlProvider -> { // this block is lazy List uris = implConfiguration.getFiles().stream().map(File::toURI).collect(Collectors.toList()); - ConfigureJavaFormatterXml.configure(xmlProvider.asNode(), uris); + ConfigureJavaFormatterXml.configureJavaFormat(xmlProvider.asNode(), uris); + ConfigureJavaFormatterXml.configureExternalDependencies(xmlProvider.asNode()); }); } private static void configureIntelliJImport(Project project, Configuration implConfiguration) { project.getPluginManager().apply("org.jetbrains.gradle.plugin.idea-ext"); - ConfigurePalantirJavaFormatXml fixPalantirJavaFormatXmlTask = project.getTasks() - .create("fixPalantirJavaFormatXml", ConfigurePalantirJavaFormatXml.class, task -> { + Provider configurePalantirJavaFormatXmlTask = project.getTasks() + .register("configurePalantirJavaFormatXml", ConfigurePalantirJavaFormatXml.class, task -> { task.getImplConfiguration().set(implConfiguration); }); + Provider configurePalantirJavaFormatPluginDependencyXml = project.getTasks() + .register("configurePalantirJavaFormatPluginDependencyXml", ConfigureExternalDependenciesXml.class); + + Task palantirJavaFormatIntellij = project.getTasks().create("palantirJavaFormatIntellij", task -> { + task.setDescription("Configure IntelliJ directory-based repository after importing"); + task.setGroup(UpdateIntellijXmlTask.INTELLIJ_TASK_GROUP); + task.dependsOn(configurePalantirJavaFormatXmlTask, configurePalantirJavaFormatPluginDependencyXml); + }); + ExtensionAware ideaProject = (ExtensionAware) project.getExtensions().getByType(IdeaModel.class).getProject(); ExtensionAware settings = (ExtensionAware) ideaProject.getExtensions().getByName("settings"); TaskTriggersConfig taskTriggers = settings.getExtensions().getByType(TaskTriggersConfig.class); - taskTriggers.afterSync(fixPalantirJavaFormatXmlTask); + taskTriggers.beforeSync(palantirJavaFormatIntellij); } } diff --git a/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/UpdateIntellijXmlTask.java b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/UpdateIntellijXmlTask.java new file mode 100644 index 000000000..3b8667f0d --- /dev/null +++ b/gradle-palantir-java-format/src/main/groovy/com/palantir/javaformat/gradle/UpdateIntellijXmlTask.java @@ -0,0 +1,63 @@ +package com.palantir.javaformat.gradle; + +import com.google.common.collect.ImmutableMap; +import com.google.common.io.Files; +import groovy.util.Node; +import groovy.util.XmlNodePrinter; +import groovy.util.XmlParser; +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.Charset; +import javax.xml.parsers.ParserConfigurationException; +import org.gradle.api.DefaultTask; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.OutputFile; +import org.gradle.api.tasks.PathSensitive; +import org.gradle.api.tasks.PathSensitivity; +import org.gradle.api.tasks.TaskAction; +import org.xml.sax.SAXException; + +public abstract class UpdateIntellijXmlTask extends DefaultTask { + private final Property xmlFile = getProject().getObjects().property(File.class); + static final String INTELLIJ_TASK_GROUP = "intellij"; + + protected abstract void configure(Node rootNode); + + public UpdateIntellijXmlTask() { + setGroup(INTELLIJ_TASK_GROUP); + } + + @PathSensitive(PathSensitivity.RELATIVE) + @OutputFile + protected final Property getXmlFile() { + return xmlFile; + } + + @TaskAction + public final void run() { + File configurationFile = getXmlFile().get(); + Node rootNode; + if (configurationFile.isFile()) { + try { + rootNode = new XmlParser().parse(configurationFile); + } catch (IOException | SAXException | ParserConfigurationException e) { + throw new RuntimeException("Couldn't parse existing configuration file: " + configurationFile, e); + } + } else { + rootNode = new Node(null, "project", ImmutableMap.of("version", "4")); + } + + configure(rootNode); + + try (BufferedWriter writer = Files.newWriter(configurationFile, Charset.defaultCharset()); + PrintWriter printWriter = new PrintWriter(writer)) { + XmlNodePrinter nodePrinter = new XmlNodePrinter(printWriter); + nodePrinter.setPreserveWhitespace(true); + nodePrinter.print(rootNode); + } catch (IOException e) { + throw new RuntimeException("Failed to write back to configuration file: " + configurationFile, e); + } + } +} diff --git a/gradle-palantir-java-format/src/test/groovy/com/palantir/javaformat/gradle/ConfigureJavaFormatterXmlTest.groovy b/gradle-palantir-java-format/src/test/groovy/com/palantir/javaformat/gradle/ConfigureJavaFormatterXmlTest.groovy index 9675876fd..db2add4ce 100644 --- a/gradle-palantir-java-format/src/test/groovy/com/palantir/javaformat/gradle/ConfigureJavaFormatterXmlTest.groovy +++ b/gradle-palantir-java-format/src/test/groovy/com/palantir/javaformat/gradle/ConfigureJavaFormatterXmlTest.groovy @@ -50,7 +50,7 @@ class ConfigureJavaFormatterXmlTest extends Specification { def node = new XmlParser().parseText(MISSING_ENTIRE_BLOCK) when: - ConfigureJavaFormatterXml.configure(node, ['foo', 'bar'].collect { URI.create(it) }) + ConfigureJavaFormatterXml.configureJavaFormat(node, ['foo', 'bar'].collect { URI.create(it) }) then: xmlToString(node) == EXPECTED @@ -60,7 +60,7 @@ class ConfigureJavaFormatterXmlTest extends Specification { def node = new XmlParser().parseText(MISSING_CLASS_PATH) when: - ConfigureJavaFormatterXml.configure(node, ['foo', 'bar'].collect { URI.create(it) }) + ConfigureJavaFormatterXml.configureJavaFormat(node, ['foo', 'bar'].collect { URI.create(it) }) then: xmlToString(node) == """\ @@ -83,7 +83,7 @@ class ConfigureJavaFormatterXmlTest extends Specification { def node = new XmlParser().parseText(EXISTING_CLASS_PATH) when: - ConfigureJavaFormatterXml.configure(node, ['foo', 'bar'].collect { URI.create(it) }) + ConfigureJavaFormatterXml.configureJavaFormat(node, ['foo', 'bar'].collect { URI.create(it) }) then: xmlToString(node) == EXPECTED