From edd4df6e142d5c2b7091bf89358350e96f2ce8fd Mon Sep 17 00:00:00 2001 From: Nico Korthout Date: Tue, 30 Nov 2021 18:25:18 +0100 Subject: [PATCH 1/9] Add flexmark-java step Introduces a new step to natively format markdown. Previously markdown was only available to spotless through the use of prettier which requires nodejs. By natively supporting markdown, java users of spotless have one less dependency to worry about. This uses https://github.com/vsch/flexmark-java, a fork of commonmark-java that made it possible to parse many flavors of markdown into an AST and render it in some way. Among those renderers, there is the option to format to markdown. This renderer (or formatter) supports many formatting options. I've selected a few reasonable ones to get started. A test has been added which is inspired by the example from https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter. I've extended it with some interesting things the formatter seems to take care of. During development, I had some difficulties dealing with idempotency of the step. This is because the parser and formatter can be configured to use different flavors individually. Care should be taken to apply the same configurations to both the parser and formatter to keep it idempotent. --- .../spotless/markdown/FlexmarkStep.java | 157 ++++++++++++++++++ .../markdown/flexmark/FlexmarkFormatted.md | 64 +++++++ .../markdown/flexmark/FlexmarkUnformatted.md | 64 +++++++ .../spotless/markdown/FlexmarkStepTest.java | 32 ++++ 4 files changed, 317 insertions(+) create mode 100644 lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java create mode 100644 testlib/src/main/resources/markdown/flexmark/FlexmarkFormatted.md create mode 100644 testlib/src/main/resources/markdown/flexmark/FlexmarkUnformatted.md create mode 100644 testlib/src/test/java/com/diffplug/spotless/markdown/FlexmarkStepTest.java diff --git a/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java new file mode 100644 index 0000000000..57dfbda7dc --- /dev/null +++ b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java @@ -0,0 +1,157 @@ +/* + * Copyright 2016-2021 DiffPlug + * + * 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.diffplug.spotless.markdown; + +import java.io.Serializable; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.Objects; + +import com.diffplug.spotless.FormatterFunc; +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.JarState; +import com.diffplug.spotless.Provisioner; + +/** A step for flexmark-java. */ +public class FlexmarkStep { + // prevent direct instantiation + private FlexmarkStep() {} + + private static final String DEFAULT_VERSION = "0.62.2"; + private static final String NAME = "flexmark-java"; + private static final String MAVEN_COORDINATE = "com.vladsch.flexmark:flexmark-all:"; + + /** + * The emulation profile is used by both the parser and the formatter and generally determines the markdown flavor. + * COMMONMARK is the default defined by flexmark-java. It's defined here so it can be used in both the parser and + * the formatter, to keep the step idempotent. + */ + private static final String DEFAULT_EMULATION_PROFILE = "COMMONMARK"; + + /** Creates a formatter step for the default version. */ + public static FormatterStep create(Provisioner provisioner) { + return create(defaultVersion(), provisioner); + } + + /** Creates a formatter step for the given version. */ + public static FormatterStep create(String version, Provisioner provisioner) { + Objects.requireNonNull(version, "version"); + Objects.requireNonNull(provisioner, "provisioner"); + return FormatterStep.createLazy(NAME, + () -> new State(JarState.from(MAVEN_COORDINATE + version, provisioner)), + State::createFormat); + } + + public static String defaultVersion() { + return DEFAULT_VERSION; + } + + private static class State implements Serializable { + private static final long serialVersionUID = 1L; + + final JarState jarState; + + State(JarState jarState) { + this.jarState = jarState; + } + + FormatterFunc createFormat() throws Exception { + final ClassLoader classLoader = jarState.getClassLoader(); + + // flexmark-java has a separate parser and renderer (formatter) + // this is build from the example in https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter + + // first we need to create the parser and find the parse method + final Class parserClazz = classLoader.loadClass("com.vladsch.flexmark.parser.Parser"); + final Class parserBuilderClazz = classLoader.loadClass("com.vladsch.flexmark.parser.Parser$Builder"); + final Class parserEmulationProfileClazz = classLoader.loadClass("com.vladsch.flexmark.parser.ParserEmulationProfile"); + final Class dataHolderClazz = classLoader.loadClass("com.vladsch.flexmark.util.data.DataHolder"); + final Class dataKeyClazz = classLoader.loadClass("com.vladsch.flexmark.util.data.DataKey"); + final Object parserEmulationProfile = parserEmulationProfileClazz.getField(DEFAULT_EMULATION_PROFILE).get(null); + final Object parserOptions = buildParserOptions(classLoader, parserClazz, dataHolderClazz, dataKeyClazz, parserEmulationProfile); + final Object parserBuilder = parserClazz.getMethod("builder", dataHolderClazz).invoke(null, parserOptions); + final Object parser = parserBuilderClazz.getMethod("build").invoke(parserBuilder); + final Method parseMethod = parserClazz.getMethod("parse", String.class); + + // now we can create the formatter and find the render method + final Class formatterClazz = classLoader.loadClass("com.vladsch.flexmark.formatter.Formatter"); + final Class nodeClazz = classLoader.loadClass("com.vladsch.flexmark.util.ast.Node"); + final Class formatterBuilderClazz = classLoader.loadClass("com.vladsch.flexmark.formatter.Formatter$Builder"); + final Object formatterOptions = buildFormatterOptions( + classLoader, parserClazz, formatterClazz, dataKeyClazz, dataHolderClazz, parserOptions, parserEmulationProfile); + final Object formatterBuilder = formatterClazz.getMethod("builder", dataHolderClazz).invoke(null, formatterOptions); + final Object formatter = formatterBuilderClazz.getMethod("build").invoke(formatterBuilder); + final Method renderMethod = formatterClazz.getMethod("render", nodeClazz); + + // the input must be parsed by the parser and then rendered by the formatter + return input -> (String) renderMethod.invoke(formatter, parseMethod.invoke(parser, input)); + } + + private Object buildParserOptions( + ClassLoader classLoader, + Class parserClazz, + Class dataHolderClazz, + Class dataKeyClazz, + Object parserEmulationProfile) throws Exception { + final Class pegdownOptionsAdapterClazz = classLoader.loadClass("com.vladsch.flexmark.profile.pegdown.PegdownOptionsAdapter"); + final Class pegdownExtensionsClazz = classLoader.loadClass("com.vladsch.flexmark.parser.PegdownExtensions"); + final Class extensionClazz = classLoader.loadClass("com.vladsch.flexmark.util.misc.Extension"); + final Class mutableDataHolderClazz = classLoader.loadClass("com.vladsch.flexmark.util.data.MutableDataHolder"); + + final int pegDownExtensionsConstantAll = pegdownExtensionsClazz.getField("ALL").getInt(null); + final Object extensions = Array.newInstance(extensionClazz, 0); + final Class extensionArrayClazz = extensions.getClass(); + + final Object parserOptions = pegdownOptionsAdapterClazz + .getMethod("flexmarkOptions", Integer.TYPE, extensionArrayClazz) + .invoke(null, pegDownExtensionsConstantAll, extensions); + final Object mutableParserOptions = dataHolderClazz.getMethod("toMutable").invoke(parserOptions); + final Object parserEmulationProfileKey = parserClazz.getField("PARSER_EMULATION_PROFILE").get(null); + final Method mutableDataHolderSetMethod = mutableDataHolderClazz.getMethod("set", dataKeyClazz, Object.class); + mutableDataHolderSetMethod.invoke(mutableParserOptions, parserEmulationProfileKey, parserEmulationProfile); + return mutableParserOptions; + } + + /** + * Creates the formatter options, copies the parser extensions and changes defaults that make sense for a formatter. + * See: https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options + */ + private Object buildFormatterOptions( + ClassLoader classLoader, + Class parserClazz, + Class formatterClazz, + Class dataKeyClazz, + Class dataHolderClazz, + Object parserOptions, + Object parserEmulationProfile) throws Exception { + final Class mutableDataSetClazz = classLoader.loadClass("com.vladsch.flexmark.util.data.MutableDataSet"); + final Object formatterOptions = mutableDataSetClazz.getConstructor().newInstance(); + final Method mutableDataSetMethodSet = mutableDataSetClazz.getMethod("set", dataKeyClazz, Object.class); + + // copy the parser extensions like the example in https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter + final Object parserExtensions = parserClazz.getField("EXTENSIONS").get(null); + final Object copiedExtensions = dataKeyClazz.getMethod("get", dataHolderClazz).invoke(parserExtensions, parserOptions); + mutableDataSetMethodSet.invoke(formatterOptions, parserExtensions, copiedExtensions); + + // use the same emulation profile for the parser and the formatted, to make sure the step is idempotent + final Object formatterEmulationProfile = formatterClazz.getField("FORMATTER_EMULATION_PROFILE").get(null); + mutableDataSetMethodSet.invoke(formatterOptions, formatterEmulationProfile, parserEmulationProfile); + + return formatterOptions; + } + + } +} diff --git a/testlib/src/main/resources/markdown/flexmark/FlexmarkFormatted.md b/testlib/src/main/resources/markdown/flexmark/FlexmarkFormatted.md new file mode 100644 index 0000000000..d85efcff03 --- /dev/null +++ b/testlib/src/main/resources/markdown/flexmark/FlexmarkFormatted.md @@ -0,0 +1,64 @@ +# Heading + +----- + +paragraph text +lazy continuation +also note the empty line at the start of this file + +another paragraph, but this time it has many characters. So many in fact that it reaches over two hundred individual characters on just this one single line. Isn't that amazing? I'm also amazed that you're still reading this. High five! + +* list item +- changed list item marker +- with a space in front +* back to the other list item marker + +> block quote +> keeps going +> lazy continuation + +``` +code block + with uneven indent + with uneven indent + indented code +``` + +~~~info + with uneven indent + with uneven indent +indented code +~~~ + +with uneven indent +with uneven indent +indented text + +1. numbered item 1 +2. numbered item 2 + 1. numbered sub-item 1 + 2. numbered sub-item 2 + 3. numbered sub-item 3 +3. numbered item 3 + +- bullet item 1 +- bullet item 2 +- bullet item 3 + +1. numbered item 1 +2. numbered item 2 +3. numbered item 3 + - bullet item 1 + - bullet item 2 + - bullet item 3 + 1. numbered sub-item 1 + 2. numbered sub-item 2 + 3. numbered sub-item 3 + +## HEADER_CONNECTED_TO_HASH + +1 empty line between header and start of paragraph + +## HEADER WITH SPACES + +2 empty lines between header and start of paragraph diff --git a/testlib/src/main/resources/markdown/flexmark/FlexmarkUnformatted.md b/testlib/src/main/resources/markdown/flexmark/FlexmarkUnformatted.md new file mode 100644 index 0000000000..3682454761 --- /dev/null +++ b/testlib/src/main/resources/markdown/flexmark/FlexmarkUnformatted.md @@ -0,0 +1,64 @@ + +#Heading +----- +paragraph text +lazy continuation +also note the empty line at the start of this file + +another paragraph, but this time it has many characters. So many in fact that it reaches over two hundred individual characters on just this one single line. Isn't that amazing? I'm also amazed that you're still reading this. High five! + +* list item +- changed list item marker +- with a space in front +* back to the other list item marker + +> block quote +> keeps going +lazy continuation + +``` +code block + with uneven indent + with uneven indent + indented code +``` + +~~~info + with uneven indent + with uneven indent +indented code +~~~ + + with uneven indent + with uneven indent +indented text + +1. numbered item 1 +1. numbered item 2 + 1. numbered sub-item 1 + 1. numbered sub-item 2 + 1. numbered sub-item 3 +1. numbered item 3 + +- bullet item 1 +- bullet item 2 +- bullet item 3 + +1. numbered item 1 +1. numbered item 2 +1. numbered item 3 + - bullet item 1 + - bullet item 2 + - bullet item 3 + 1. numbered sub-item 1 + 1. numbered sub-item 2 + 1. numbered sub-item 3 + +##HEADER_CONNECTED_TO_HASH + +1 empty line between header and start of paragraph + +## HEADER WITH SPACES + + +2 empty lines between header and start of paragraph diff --git a/testlib/src/test/java/com/diffplug/spotless/markdown/FlexmarkStepTest.java b/testlib/src/test/java/com/diffplug/spotless/markdown/FlexmarkStepTest.java new file mode 100644 index 0000000000..191ffa4cb5 --- /dev/null +++ b/testlib/src/test/java/com/diffplug/spotless/markdown/FlexmarkStepTest.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2021 DiffPlug + * + * 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.diffplug.spotless.markdown; + +import org.junit.jupiter.api.Test; + +import com.diffplug.spotless.StepHarness; +import com.diffplug.spotless.TestProvisioner; + +class FlexmarkStepTest { + + @Test + void behavior() throws Exception { + StepHarness.forStep(FlexmarkStep.create(TestProvisioner.mavenCentral())) + .testResource( + "markdown/flexmark/FlexmarkUnformatted.md", + "markdown/flexmark/FlexmarkFormatted.md"); + } +} From 05ab0092d457ca943ef4616480acc0bd90e435c1 Mon Sep 17 00:00:00 2001 From: Nico Korthout Date: Thu, 2 Dec 2021 19:04:41 +0100 Subject: [PATCH 2/9] Add flexmark step to maven-plugin Introduces a markdown section to the maven-plugin's configuration parameters, which allows to specify the flexmark configuration. Example: ```xml ``` This works exactly the same as the configuration of the other steps By default all `.md` extented files are included, but as I understand it, this can be overwritten using: ```xml ... ``` --- .../spotless/maven/AbstractSpotlessMojo.java | 6 ++- .../spotless/maven/markdown/Flexmark.java | 35 +++++++++++++++ .../spotless/maven/markdown/Markdown.java | 44 +++++++++++++++++++ .../maven/MavenIntegrationHarness.java | 4 ++ .../maven/markdown/FlexmarkMavenTest.java | 33 ++++++++++++++ 5 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java create mode 100644 plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java create mode 100644 plugin-maven/src/test/java/com/diffplug/spotless/maven/markdown/FlexmarkMavenTest.java diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index 3a98ee240b..6238a47834 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -56,6 +56,7 @@ import com.diffplug.spotless.maven.groovy.Groovy; import com.diffplug.spotless.maven.java.Java; import com.diffplug.spotless.maven.kotlin.Kotlin; +import com.diffplug.spotless.maven.markdown.Markdown; import com.diffplug.spotless.maven.pom.Pom; import com.diffplug.spotless.maven.python.Python; import com.diffplug.spotless.maven.scala.Scala; @@ -141,6 +142,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo { @Parameter private Python python; + @Parameter + private Markdown markdown; + @Parameter(property = "spotlessFiles") private String filePatterns; @@ -290,7 +294,7 @@ private FileLocator getFileLocator() { } private List getFormatterFactories() { - return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, antlr4, pom, sql, python)) + return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, antlr4, pom, sql, python, markdown)) .filter(Objects::nonNull) .collect(toList()); } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java new file mode 100644 index 0000000000..6e64e26e15 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java @@ -0,0 +1,35 @@ +/* + * Copyright 2021 DiffPlug + * + * 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.diffplug.spotless.maven.markdown; + +import org.apache.maven.plugins.annotations.Parameter; + +import com.diffplug.spotless.FormatterStep; +import com.diffplug.spotless.markdown.FlexmarkStep; +import com.diffplug.spotless.maven.FormatterStepConfig; +import com.diffplug.spotless.maven.FormatterStepFactory; + +public class Flexmark implements FormatterStepFactory { + + @Parameter + private String version; + + @Override + public FormatterStep newFormatterStep(FormatterStepConfig config) { + String version = this.version != null ? this.version : FlexmarkStep.defaultVersion(); + return FlexmarkStep.create(version, config.getProvisioner()); + } +} diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java new file mode 100644 index 0000000000..153a3e31a1 --- /dev/null +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 DiffPlug + * + * 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.diffplug.spotless.maven.markdown; + +import java.util.Set; + +import com.diffplug.common.collect.ImmutableSet; +import com.diffplug.spotless.maven.FormatterFactory; +import com.diffplug.spotless.maven.generic.LicenseHeader; + +/** + * A {@link FormatterFactory} implementation that corresponds to {@code ...} configuration element. + *

+ * It defines a formatter for Markdown files that can execute both language agnostic (e.g. {@link LicenseHeader}) + * and markdown-specific (e.g. {@link Flexmark}) steps. + */ +public class Markdown extends FormatterFactory { + @Override + public Set defaultIncludes() { + return ImmutableSet.of("*.md", "**/*.md"); + } + + @Override + public String licenseHeaderDelimiter() { + return null; + } + + public void addFlexmark(Flexmark flexmark) { + addStepFactory(flexmark); + } +} diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java index fa5224bb8d..cbfa6aa850 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java @@ -138,6 +138,10 @@ protected void writePomWithPomSteps(String... steps) throws IOException { writePom(groupWithSteps("pom", including("pom_test.xml"), steps)); } + protected void writePomWithMarkdownSteps(String... steps) throws IOException { + writePom(groupWithSteps("markdown", steps)); + } + protected void writePom(String... configuration) throws IOException { writePom(null, configuration); } diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/markdown/FlexmarkMavenTest.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/markdown/FlexmarkMavenTest.java new file mode 100644 index 0000000000..a623ca7f3c --- /dev/null +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/markdown/FlexmarkMavenTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021 DiffPlug + * + * 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.diffplug.spotless.maven.markdown; + +import org.junit.jupiter.api.Test; + +import com.diffplug.spotless.maven.MavenIntegrationHarness; + +public class FlexmarkMavenTest extends MavenIntegrationHarness { + + @Test + public void testFlexmarkWithDefaultConfig() throws Exception { + writePomWithMarkdownSteps(""); + + setFile("markdown_test.md").toResource("markdown/flexmark/FlexmarkUnformatted.md"); + mavenRunner().withArguments("spotless:apply").runNoError().error(); + assertFile("markdown_test.md").sameAsResource("markdown/flexmark/FlexmarkFormatted.md"); + } + +} From 18582f6981ff18d27cb7c381a195a387b31ae639 Mon Sep 17 00:00:00 2001 From: Nico Korthout Date: Sat, 11 Dec 2021 12:34:18 +0100 Subject: [PATCH 3/9] Convert flexmark to compile-only sourceset This converts the flexmark step to use the compile-only flexmark glue code, which makes using the library specific code much easier by avoiding the java reflection api. --- lib/build.gradle | 6 +- .../glue/markdown/FlexmarkFormatterFunc.java | 91 ++++++++++++++++++ .../spotless/markdown/FlexmarkStep.java | 94 +------------------ 3 files changed, 100 insertions(+), 91 deletions(-) create mode 100644 lib/src/flexmark/java/com/diffplug/spotless/glue/markdown/FlexmarkFormatterFunc.java diff --git a/lib/build.gradle b/lib/build.gradle index 4798a29b5b..e49d13f5d5 100644 --- a/lib/build.gradle +++ b/lib/build.gradle @@ -8,7 +8,8 @@ apply from: rootProject.file('gradle/java-publish.gradle') def NEEDS_GLUE = [ 'sortPom', - 'ktlint' + 'ktlint', + 'flexmark' ] for (glue in NEEDS_GLUE) { sourceSets.register(glue) { @@ -32,6 +33,9 @@ dependencies { ktlintCompileOnly "com.pinterest:ktlint:$VER_KTLINT" ktlintCompileOnly "com.pinterest.ktlint:ktlint-core:$VER_KTLINT" ktlintCompileOnly "com.pinterest.ktlint:ktlint-ruleset-standard:$VER_KTLINT" + + // used for markdown formatting + flexmarkCompileOnly 'com.vladsch.flexmark:flexmark-all:0.62.2' } // we'll hold the core lib to a high standard diff --git a/lib/src/flexmark/java/com/diffplug/spotless/glue/markdown/FlexmarkFormatterFunc.java b/lib/src/flexmark/java/com/diffplug/spotless/glue/markdown/FlexmarkFormatterFunc.java new file mode 100644 index 0000000000..dccb4fee7c --- /dev/null +++ b/lib/src/flexmark/java/com/diffplug/spotless/glue/markdown/FlexmarkFormatterFunc.java @@ -0,0 +1,91 @@ +/* + * Copyright 2021 DiffPlug + * + * 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.diffplug.spotless.glue.markdown; + +import com.vladsch.flexmark.formatter.Formatter; +import com.vladsch.flexmark.parser.Parser; +import com.vladsch.flexmark.parser.ParserEmulationProfile; +import com.vladsch.flexmark.parser.PegdownExtensions; +import com.vladsch.flexmark.profile.pegdown.PegdownOptionsAdapter; +import com.vladsch.flexmark.util.ast.Document; +import com.vladsch.flexmark.util.data.MutableDataHolder; +import com.vladsch.flexmark.util.data.MutableDataSet; + +import com.diffplug.spotless.FormatterFunc; + +/** + * The formatter function for flexmark-java. + */ +public class FlexmarkFormatterFunc implements FormatterFunc { + + /** + * The emulation profile is used by both the parser and the formatter and generally determines the markdown flavor. + * COMMONMARK is the default defined by flexmark-java. + */ + private static final String DEFAULT_EMULATION_PROFILE = "COMMONMARK"; + + private final Parser parser; + private final Formatter formatter; + + public FlexmarkFormatterFunc() { + // flexmark-java has a separate parser and renderer (formatter) + // this is build from the example in https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter + + // The emulation profile generally determines the markdown flavor. We use the same one for both the parser and + // the formatter, to make sure this formatter func is idempotent. + final ParserEmulationProfile emulationProfile = ParserEmulationProfile.valueOf(DEFAULT_EMULATION_PROFILE); + + final MutableDataHolder parserOptions = createParserOptions(emulationProfile); + final MutableDataHolder formatterOptions = createFormatterOptions(parserOptions, emulationProfile); + + parser = Parser.builder(parserOptions).build(); + formatter = Formatter.builder(formatterOptions).build(); + } + + /** + * Creates the parser options. + * See: https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options + * + * @param emulationProfile the emulation profile (or flavor of markdown) the parser should use + * @return the created parser options + */ + private static MutableDataHolder createParserOptions(ParserEmulationProfile emulationProfile) { + final MutableDataHolder parserOptions = PegdownOptionsAdapter.flexmarkOptions(PegdownExtensions.ALL).toMutable(); + parserOptions.set(Parser.PARSER_EMULATION_PROFILE, emulationProfile); + return parserOptions; + } + + /** + * Creates the formatter options, copies the parser extensions and changes defaults that make sense for a formatter. + * See: https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options + * + * @param parserOptions the options used for the parser + * @param emulationProfile the emulation profile (or flavor of markdown) the formatter should use + * @return the created formatter options + */ + private static MutableDataHolder createFormatterOptions(MutableDataHolder parserOptions, ParserEmulationProfile emulationProfile) { + final MutableDataHolder formatterOptions = new MutableDataSet(); + formatterOptions.set(Parser.EXTENSIONS, Parser.EXTENSIONS.get(parserOptions)); + formatterOptions.set(Formatter.FORMATTER_EMULATION_PROFILE, emulationProfile); + return formatterOptions; + } + + @Override + public String apply(String input) throws Exception { + final Document parsedMarkdown = parser.parse(input); + return formatter.render(parsedMarkdown); + } +} diff --git a/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java index 57dfbda7dc..fbb5affa5b 100644 --- a/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java +++ b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java @@ -16,8 +16,7 @@ package com.diffplug.spotless.markdown; import java.io.Serializable; -import java.lang.reflect.Array; -import java.lang.reflect.Method; +import java.lang.reflect.Constructor; import java.util.Objects; import com.diffplug.spotless.FormatterFunc; @@ -34,13 +33,6 @@ private FlexmarkStep() {} private static final String NAME = "flexmark-java"; private static final String MAVEN_COORDINATE = "com.vladsch.flexmark:flexmark-all:"; - /** - * The emulation profile is used by both the parser and the formatter and generally determines the markdown flavor. - * COMMONMARK is the default defined by flexmark-java. It's defined here so it can be used in both the parser and - * the formatter, to keep the step idempotent. - */ - private static final String DEFAULT_EMULATION_PROFILE = "COMMONMARK"; - /** Creates a formatter step for the default version. */ public static FormatterStep create(Provisioner provisioner) { return create(defaultVersion(), provisioner); @@ -70,87 +62,9 @@ private static class State implements Serializable { FormatterFunc createFormat() throws Exception { final ClassLoader classLoader = jarState.getClassLoader(); - - // flexmark-java has a separate parser and renderer (formatter) - // this is build from the example in https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter - - // first we need to create the parser and find the parse method - final Class parserClazz = classLoader.loadClass("com.vladsch.flexmark.parser.Parser"); - final Class parserBuilderClazz = classLoader.loadClass("com.vladsch.flexmark.parser.Parser$Builder"); - final Class parserEmulationProfileClazz = classLoader.loadClass("com.vladsch.flexmark.parser.ParserEmulationProfile"); - final Class dataHolderClazz = classLoader.loadClass("com.vladsch.flexmark.util.data.DataHolder"); - final Class dataKeyClazz = classLoader.loadClass("com.vladsch.flexmark.util.data.DataKey"); - final Object parserEmulationProfile = parserEmulationProfileClazz.getField(DEFAULT_EMULATION_PROFILE).get(null); - final Object parserOptions = buildParserOptions(classLoader, parserClazz, dataHolderClazz, dataKeyClazz, parserEmulationProfile); - final Object parserBuilder = parserClazz.getMethod("builder", dataHolderClazz).invoke(null, parserOptions); - final Object parser = parserBuilderClazz.getMethod("build").invoke(parserBuilder); - final Method parseMethod = parserClazz.getMethod("parse", String.class); - - // now we can create the formatter and find the render method - final Class formatterClazz = classLoader.loadClass("com.vladsch.flexmark.formatter.Formatter"); - final Class nodeClazz = classLoader.loadClass("com.vladsch.flexmark.util.ast.Node"); - final Class formatterBuilderClazz = classLoader.loadClass("com.vladsch.flexmark.formatter.Formatter$Builder"); - final Object formatterOptions = buildFormatterOptions( - classLoader, parserClazz, formatterClazz, dataKeyClazz, dataHolderClazz, parserOptions, parserEmulationProfile); - final Object formatterBuilder = formatterClazz.getMethod("builder", dataHolderClazz).invoke(null, formatterOptions); - final Object formatter = formatterBuilderClazz.getMethod("build").invoke(formatterBuilder); - final Method renderMethod = formatterClazz.getMethod("render", nodeClazz); - - // the input must be parsed by the parser and then rendered by the formatter - return input -> (String) renderMethod.invoke(formatter, parseMethod.invoke(parser, input)); - } - - private Object buildParserOptions( - ClassLoader classLoader, - Class parserClazz, - Class dataHolderClazz, - Class dataKeyClazz, - Object parserEmulationProfile) throws Exception { - final Class pegdownOptionsAdapterClazz = classLoader.loadClass("com.vladsch.flexmark.profile.pegdown.PegdownOptionsAdapter"); - final Class pegdownExtensionsClazz = classLoader.loadClass("com.vladsch.flexmark.parser.PegdownExtensions"); - final Class extensionClazz = classLoader.loadClass("com.vladsch.flexmark.util.misc.Extension"); - final Class mutableDataHolderClazz = classLoader.loadClass("com.vladsch.flexmark.util.data.MutableDataHolder"); - - final int pegDownExtensionsConstantAll = pegdownExtensionsClazz.getField("ALL").getInt(null); - final Object extensions = Array.newInstance(extensionClazz, 0); - final Class extensionArrayClazz = extensions.getClass(); - - final Object parserOptions = pegdownOptionsAdapterClazz - .getMethod("flexmarkOptions", Integer.TYPE, extensionArrayClazz) - .invoke(null, pegDownExtensionsConstantAll, extensions); - final Object mutableParserOptions = dataHolderClazz.getMethod("toMutable").invoke(parserOptions); - final Object parserEmulationProfileKey = parserClazz.getField("PARSER_EMULATION_PROFILE").get(null); - final Method mutableDataHolderSetMethod = mutableDataHolderClazz.getMethod("set", dataKeyClazz, Object.class); - mutableDataHolderSetMethod.invoke(mutableParserOptions, parserEmulationProfileKey, parserEmulationProfile); - return mutableParserOptions; - } - - /** - * Creates the formatter options, copies the parser extensions and changes defaults that make sense for a formatter. - * See: https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options - */ - private Object buildFormatterOptions( - ClassLoader classLoader, - Class parserClazz, - Class formatterClazz, - Class dataKeyClazz, - Class dataHolderClazz, - Object parserOptions, - Object parserEmulationProfile) throws Exception { - final Class mutableDataSetClazz = classLoader.loadClass("com.vladsch.flexmark.util.data.MutableDataSet"); - final Object formatterOptions = mutableDataSetClazz.getConstructor().newInstance(); - final Method mutableDataSetMethodSet = mutableDataSetClazz.getMethod("set", dataKeyClazz, Object.class); - - // copy the parser extensions like the example in https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter - final Object parserExtensions = parserClazz.getField("EXTENSIONS").get(null); - final Object copiedExtensions = dataKeyClazz.getMethod("get", dataHolderClazz).invoke(parserExtensions, parserOptions); - mutableDataSetMethodSet.invoke(formatterOptions, parserExtensions, copiedExtensions); - - // use the same emulation profile for the parser and the formatted, to make sure the step is idempotent - final Object formatterEmulationProfile = formatterClazz.getField("FORMATTER_EMULATION_PROFILE").get(null); - mutableDataSetMethodSet.invoke(formatterOptions, formatterEmulationProfile, parserEmulationProfile); - - return formatterOptions; + final Class formatterFunc = classLoader.loadClass("com.diffplug.spotless.glue.markdown.FlexmarkFormatterFunc"); + final Constructor constructor = formatterFunc.getConstructor(); + return (FormatterFunc) constructor.newInstance(); } } From 6476c045c649c83ab7111e4de0fc5b2529698e4f Mon Sep 17 00:00:00 2001 From: Nico Korthout Date: Fri, 17 Dec 2021 14:47:40 +0100 Subject: [PATCH 4/9] Document flexmark formatter --- README.md | 2 ++ plugin-maven/README.md | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/README.md b/README.md index bdf428eb46..89ceb38139 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ lib('kotlin.KtLintStep') +'{{yes}} | {{yes}} lib('kotlin.KtfmtStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('kotlin.DiktatStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('markdown.FreshMarkStep') +'{{yes}} | {{no}} | {{no}} | {{no}} |', +lib('markdown.FlexmarkStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |', lib('npm.PrettierFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('npm.TsFmtFormatterStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |', lib('pom.SortPomStepStep') +'{{no}} | {{yes}} | {{no}} | {{no}} |', @@ -103,6 +104,7 @@ extra('wtp.EclipseWtpFormatterStep') +'{{yes}} | {{yes}} | [`kotlin.KtfmtStep`](lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`kotlin.DiktatStep`](lib/src/main/java/com/diffplug/spotless/kotlin/DiktatStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`markdown.FreshMarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: | +| [`markdown.FlexmarkStep`](lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: | | [`npm.PrettierFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/PrettierFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`npm.TsFmtFormatterStep`](lib/src/main/java/com/diffplug/spotless/npm/TsFmtFormatterStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: | | [`pom.SortPomStepStep`](lib/src/main/java/com/diffplug/spotless/pom/SortPomStepStep.java) | :white_large_square: | :+1: | :white_large_square: | :white_large_square: | diff --git a/plugin-maven/README.md b/plugin-maven/README.md index a4ff8d6006..005f125df7 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -56,6 +56,7 @@ user@machine repo % mvn spotless:check - [Antlr4](#antlr4) ([antlr4formatter](#antlr4formatter)) - [Sql](#sql) ([dbeaver](#dbeaver)) - [Maven Pom](#maven-pom) ([sortPom](#sortpom)) + - [Markdown](#markdown) ([flexmark](#flexmark)) - [Typescript](#typescript) ([tsfmt](#tsfmt), [prettier](#prettier)) - Multiple languages - [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection)) @@ -585,6 +586,30 @@ All configuration settings are optional, they are described in detail [here](htt ``` +## Markdown + +[code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java). [available steps](https://github.com/diffplug/spotless/tree/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown). + +```xml + + + + + *.md + **/*.md + + + + + +``` + +### Flexmark + +[homepage](https://github.com/vsch/flexmark-java). [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Flexmark.java). Flexmark is a flexible Commonmark/Markdown parser that can be used to format Markdown files. It supports different [flavors of Markdown](https://github.com/vsch/flexmark-java#markdown-processor-emulation) and [many formatting options](https://github.com/vsch/flexmark-java/wiki/Markdown-Formatter#options). + +Currently, none of the available options can be configured yet. It uses only the default options together with `COMMONMARK` as `FORMATTER_EMULATION_PROFILE`. + ## Typescript From 3877fc02217552e06559003918d645b195b0a0bc Mon Sep 17 00:00:00 2001 From: Nico Korthout Date: Fri, 17 Dec 2021 14:48:12 +0100 Subject: [PATCH 5/9] Add changelog entries --- CHANGES.md | 2 ++ plugin-maven/CHANGES.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 0749319dfe..44d7e22c26 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ This document is intended for Spotless developers. We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`). ## [Unreleased] +### Added +* Added support for Markdown with `flexmark` at `0.62.2` ([#1011](https://github.com/diffplug/spotless/pull/1011)). ## [2.20.3] - 2021-12-15 ### Fixed diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 51ba44cee0..92c190ac81 100644 --- a/plugin-maven/CHANGES.md +++ b/plugin-maven/CHANGES.md @@ -3,6 +3,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`). ## [Unreleased] +### Added +* Added support for Markdown with `flexmark` at `0.62.2` ([#1011](https://github.com/diffplug/spotless/pull/1011)). ## [2.17.7] - 2021-12-16 ### Fixed From 1ef8e6065314492c162f2ee2010b729cd3b7904b Mon Sep 17 00:00:00 2001 From: Nico Korthout Date: Sat, 18 Dec 2021 11:48:12 +0100 Subject: [PATCH 6/9] Fix jarstate comments None of these jars contain anything Eclipse related. They do however contain the formatter and this might be interesting information. --- .../java/com/diffplug/spotless/java/GoogleJavaFormatStep.java | 2 +- lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java | 2 +- lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java | 2 +- .../main/java/com/diffplug/spotless/markdown/FlexmarkStep.java | 1 + .../main/java/com/diffplug/spotless/markdown/FreshMarkStep.java | 2 +- 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java index d61a42a917..02ac90f729 100644 --- a/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java +++ b/lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java @@ -115,7 +115,7 @@ public static boolean defaultReflowLongStrings() { static final class State implements Serializable { private static final long serialVersionUID = 1L; - /** The jar that contains the eclipse formatter. */ + /** The jar that contains the formatter. */ final JarState jarState; final String stepName; final String version; diff --git a/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java b/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java index 0265ef499a..1db75a4e1f 100644 --- a/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java +++ b/lib/src/main/java/com/diffplug/spotless/kotlin/KtLintStep.java @@ -82,7 +82,7 @@ static final class State implements Serializable { /** Are the files being linted Kotlin script files. */ private final boolean isScript; private final String pkg; - /** The jar that contains the eclipse formatter. */ + /** The jar that contains the formatter. */ final JarState jarState; private final TreeMap userData; private final boolean useParams; diff --git a/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java b/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java index 4bce6754c6..1a1371702f 100644 --- a/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java +++ b/lib/src/main/java/com/diffplug/spotless/kotlin/KtfmtStep.java @@ -108,7 +108,7 @@ static final class State implements Serializable { * Option that allows to apply formatting options to perform a 4 spaces block and continuation indent. */ private final Style style; - /** The jar that contains the eclipse formatter. */ + /** The jar that contains the formatter. */ final JarState jarState; State(String version, Provisioner provisioner, Style style) throws IOException { diff --git a/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java index fbb5affa5b..19550b6e44 100644 --- a/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java +++ b/lib/src/main/java/com/diffplug/spotless/markdown/FlexmarkStep.java @@ -54,6 +54,7 @@ public static String defaultVersion() { private static class State implements Serializable { private static final long serialVersionUID = 1L; + /** The jar that contains the formatter. */ final JarState jarState; State(JarState jarState) { diff --git a/lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java b/lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java index 11f10bebd5..2190af88e7 100644 --- a/lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java +++ b/lib/src/main/java/com/diffplug/spotless/markdown/FreshMarkStep.java @@ -65,7 +65,7 @@ public static String defaultVersion() { private static class State implements Serializable { private static final long serialVersionUID = 1L; - /** The jar that contains the eclipse formatter. */ + /** The jar that contains the formatter. */ final JarState jarState; final NavigableMap properties; From e85c7ab07fcce1165682c81ded91c11c81557cb4 Mon Sep 17 00:00:00 2001 From: Nico Korthout Date: Sat, 18 Dec 2021 12:04:35 +0100 Subject: [PATCH 7/9] Warn multimodule users about **/*.md includes Including '**/*.md' means that all md files in all sub directories are found. In a multi-module maven project, where spotless is run for each module it would mean that markdown files in sub modules are also found by modules at a higher level of the module hierarchie (i.e. sub modules are sub directories of an other module). This means that files would be processed by the formatter multiple times. Which is obviously less performant. Generally, users should be proteced from this, by decent default settings. However, if we would not include '**/*.md' users might be surprised to learn that some of their files are left untouched. Instead, I chose to warn multi-module users specifically about this. Because the impact (and surprise) of not formatting files in nested folder structures is likely greater than the hit in performance due to processing the files multiple times. Also note that the first problem occurs for both regular maven projects as well as multi-module projects and the latter only occurs on multi-module projects. --- plugin-maven/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 005f125df7..3323d5c65b 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -594,6 +594,7 @@ All configuration settings are optional, they are described in detail [here](htt + *.md **/*.md From 540aeadc3f959938b7840cf516206f36fedfe4a3 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 23 Dec 2021 11:33:57 -0800 Subject: [PATCH 8/9] Remove default includes for the maven markdown extension, too project-specific. --- plugin-maven/README.md | 5 +---- .../com/diffplug/spotless/maven/AbstractSpotlessMojo.java | 2 +- .../java/com/diffplug/spotless/maven/markdown/Markdown.java | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/plugin-maven/README.md b/plugin-maven/README.md index 3323d5c65b..be014d99f4 100644 --- a/plugin-maven/README.md +++ b/plugin-maven/README.md @@ -593,10 +593,7 @@ All configuration settings are optional, they are described in detail [here](htt ```xml - - - - *.md + **/*.md diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java index 6238a47834..8b6b502865 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/AbstractSpotlessMojo.java @@ -264,7 +264,7 @@ private Set getIncludes(FormatterFactory formatterFactory) throws MojoEx Set configuredIncludes = formatterFactory.includes(); Set includes = configuredIncludes.isEmpty() ? formatterFactory.defaultIncludes() : configuredIncludes; if (includes.isEmpty()) { - throw new MojoExecutionException("You must specify some files to include, such as 'src/**'"); + throw new MojoExecutionException("You must specify some files to include, such as 'src/**/*.blah'"); } return includes; } diff --git a/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java b/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java index 153a3e31a1..2ba9b1f58f 100644 --- a/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java +++ b/plugin-maven/src/main/java/com/diffplug/spotless/maven/markdown/Markdown.java @@ -15,9 +15,9 @@ */ package com.diffplug.spotless.maven.markdown; +import java.util.Collections; import java.util.Set; -import com.diffplug.common.collect.ImmutableSet; import com.diffplug.spotless.maven.FormatterFactory; import com.diffplug.spotless.maven.generic.LicenseHeader; @@ -30,7 +30,7 @@ public class Markdown extends FormatterFactory { @Override public Set defaultIncludes() { - return ImmutableSet.of("*.md", "**/*.md"); + return Collections.emptySet(); } @Override From 0fcfee5554aa270c96d9e7147b841b1de657654b Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Thu, 23 Dec 2021 11:47:37 -0800 Subject: [PATCH 9/9] Fix flexmark maven tests. --- .../com/diffplug/spotless/maven/MavenIntegrationHarness.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java index d5e9d10df8..e1c6027eee 100644 --- a/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java +++ b/plugin-maven/src/test/java/com/diffplug/spotless/maven/MavenIntegrationHarness.java @@ -140,7 +140,7 @@ protected void writePomWithPomSteps(String... steps) throws IOException { } protected void writePomWithMarkdownSteps(String... steps) throws IOException { - writePom(groupWithSteps("markdown", steps)); + writePom(groupWithSteps("markdown", including("**/*.md"), steps)); } protected void writePom(String... configuration) throws IOException {