Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support KtLint 0.49.0, drop KtLint 0.46.0 #1706

Merged
merged 4 commits into from
May 22, 2023

Conversation

magneticflux-
Copy link
Contributor

Closes #1696

Please DO NOT FORCE PUSH. Don't worry about messy history, it's easier to do code review if we can tell what happened after the review, and force pushing breaks that.

Please make sure that your PR allows edits from maintainers. Sometimes its faster for us to just fix something than it is to describe how to fix it.

Allow edits from maintainers

After creating the PR, please add a commit that adds a bullet-point under the [Unreleased] section of CHANGES.md, plugin-gradle/CHANGES.md, and plugin-maven/CHANGES.md which includes:

  • a summary of the change
  • either
    • a link to the issue you are resolving (for small changes)
    • a link to the PR you just created (for big changes likely to have discussion)

If your change only affects a build plugin, and not the lib, then you only need to update the plugin-foo/CHANGES.md for that plugin.

If your change affects lib in an end-user-visible way (fixing a bug, updating a version) then you need to update CHANGES.md for both the lib and all build plugins. Users of a build plugin shouldn't have to refer to lib to see changes that affect them.

This makes it easier for the maintainers to quickly release your changes :)

magneticflux- and others added 3 commits May 18, 2023 12:28
Currently, we work around name-mangling issues with special Kotlin classes. The root issue is tracked here: pinterest/ktlint#2041

Also fixes the IntelliJ .editorconfig import order property to better match Eclipse formatting
Copy link
Member

@nedtwigg nedtwigg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I am baffled by how complex the KtLint API is, and how much it evolves. Can you describe why we need reflection? Where do these method names from from?

Comment on lines +80 to +86
try {
RULEID_METHOD = LintError.class.getMethod("getRuleId-6XN97os");
CREATE_RULESET_EXECUTION_METHOD = RuleExecutionEditorConfigPropertyKt.class.getMethod("createRuleSetExecutionEditorConfigProperty-fqiwTpU", String.class, RuleExecution.class);
CREATE_RULE_EXECUTION_METHOD = RuleExecutionEditorConfigPropertyKt.class.getMethod("createRuleExecutionEditorConfigProperty-U7AdEiY", String.class, RuleExecution.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the mangled method names for 0.49.X. They're unrepresentable in Java source because they contain a hyphen, and they're mangled in the first place because they deal with Kotlin value classes (and Valhalla isn't ready, so they implemented it like this first).
More info here: pinterest/ktlint#2041

@magneticflux-
Copy link
Contributor Author

magneticflux- commented May 20, 2023

The KtLint team were quick to respond ❤️ and published a snapshot version with a fix (labeled 0.49.2-SNAPSHOT, to be released as 0.50.0). Here's a patch from this PR to support 0.49.2-SNAPSHOT/0.50.0 for future use:

Subject: [PATCH] Support ktlint `0.49.2-SNAPSHOT`/`0.50.0` and drop support for `0.47.0`
---
Index: lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java
===================================================================
diff --git a/lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java b/lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java
deleted file mode 100644
--- a/lib/src/compatKtLint0Dot47Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot47Dot0Adapter.java	(revision 88845df2179c3ea457e67eff39f7b3541908363c)
+++ /dev/null	(revision 88845df2179c3ea457e67eff39f7b3541908363c)
@@ -1,139 +0,0 @@
-/*
- * Copyright 2022-2023 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.ktlint.compat;
-
-import static java.util.Collections.emptySet;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import com.pinterest.ktlint.core.KtLint;
-import com.pinterest.ktlint.core.LintError;
-import com.pinterest.ktlint.core.Rule;
-import com.pinterest.ktlint.core.RuleProvider;
-import com.pinterest.ktlint.core.api.DefaultEditorConfigProperties;
-import com.pinterest.ktlint.core.api.EditorConfigDefaults;
-import com.pinterest.ktlint.core.api.EditorConfigOverride;
-import com.pinterest.ktlint.core.api.UsesEditorConfigProperties;
-import com.pinterest.ktlint.ruleset.experimental.ExperimentalRuleSetProvider;
-import com.pinterest.ktlint.ruleset.standard.StandardRuleSetProvider;
-
-import kotlin.Pair;
-import kotlin.Unit;
-import kotlin.jvm.functions.Function2;
-
-public class KtLintCompat0Dot47Dot0Adapter implements KtLintCompatAdapter {
-
-	static class FormatterCallback implements Function2<LintError, Boolean, Unit> {
-		@Override
-		public Unit invoke(LintError lint, Boolean corrected) {
-			if (!corrected) {
-				KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId(), lint.getDetail());
-			}
-			return null;
-		}
-	}
-
-	@Override
-	public String format(final String text, Path path, final boolean isScript,
-			final boolean useExperimental,
-			Path editorConfigPath, final Map<String, String> userData,
-			final Map<String, Object> editorConfigOverrideMap) {
-		final FormatterCallback formatterCallback = new FormatterCallback();
-
-		Set<RuleProvider> allRuleProviders = new LinkedHashSet<>(
-				new StandardRuleSetProvider().getRuleProviders());
-		if (useExperimental) {
-			allRuleProviders.addAll(new ExperimentalRuleSetProvider().getRuleProviders());
-		}
-
-		EditorConfigOverride editorConfigOverride;
-		if (editorConfigOverrideMap.isEmpty()) {
-			editorConfigOverride = new EditorConfigOverride();
-		} else {
-			editorConfigOverride = createEditorConfigOverride(allRuleProviders.stream().map(
-					RuleProvider::createNewRuleInstance).collect(
-							Collectors.toList()),
-					editorConfigOverrideMap);
-		}
-
-		EditorConfigDefaults editorConfig;
-		if (editorConfigPath == null || !Files.exists(editorConfigPath)) {
-			editorConfig = EditorConfigDefaults.Companion.getEmptyEditorConfigDefaults();
-		} else {
-			editorConfig = EditorConfigDefaults.Companion.load(editorConfigPath);
-		}
-
-		return KtLint.INSTANCE.format(new KtLint.ExperimentalParams(
-				path.toFile().getAbsolutePath(),
-				text,
-				emptySet(),
-				allRuleProviders,
-				userData,
-				formatterCallback,
-				isScript,
-				null,
-				false,
-				editorConfig,
-				editorConfigOverride,
-				false));
-	}
-
-	/**
-	 * Create EditorConfigOverride from user provided parameters.
-	 * Calling this method requires KtLint 0.45.2.
-	 */
-	private static EditorConfigOverride createEditorConfigOverride(final List<Rule> rules, Map<String, Object> editorConfigOverrideMap) {
-		// Get properties from rules in the rule sets
-		Stream<UsesEditorConfigProperties.EditorConfigProperty<?>> ruleProperties = rules.stream()
-				.filter(rule -> rule instanceof UsesEditorConfigProperties)
-				.flatMap(rule -> ((UsesEditorConfigProperties) rule).getEditorConfigProperties().stream());
-
-		// get complete list of supported properties in DefaultEditorConfigProperties.INSTANCE
-		List<UsesEditorConfigProperties.EditorConfigProperty<?>> editorConfigProperties = new ArrayList<>(DefaultEditorConfigProperties.INSTANCE.getEditorConfigProperties());
-		editorConfigProperties.add(DefaultEditorConfigProperties.INSTANCE.getKtlintDisabledRulesProperty());
-
-		// Create a mapping of properties to their names based on rule properties and default properties
-		Map<String, UsesEditorConfigProperties.EditorConfigProperty<?>> supportedProperties = Stream
-				.concat(ruleProperties, editorConfigProperties.stream())
-				.distinct()
-				.collect(Collectors.toMap(property -> property.getType().getName(), property -> property));
-
-		// Create config properties based on provided property names and values
-		@SuppressWarnings("unchecked")
-		Pair<UsesEditorConfigProperties.EditorConfigProperty<?>, ?>[] properties = editorConfigOverrideMap.entrySet().stream()
-				.map(entry -> {
-					UsesEditorConfigProperties.EditorConfigProperty<?> property = supportedProperties.get(entry.getKey());
-					if (property != null) {
-						return new Pair<>(property, entry.getValue());
-					} else {
-						return null;
-					}
-				})
-				.filter(Objects::nonNull)
-				.toArray(Pair[]::new);
-
-		return EditorConfigOverride.Companion.from(properties);
-	}
-}
Index: lib/src/compatKtLint0Dot50Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot50Dot0Adapter.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/src/compatKtLint0Dot50Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot50Dot0Adapter.java b/lib/src/compatKtLint0Dot50Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot50Dot0Adapter.java
new file mode 100644
--- /dev/null	(date 1684552679289)
+++ b/lib/src/compatKtLint0Dot50Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot50Dot0Adapter.java	(date 1684552679289)
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2023 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.ktlint.compat;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.pinterest.ktlint.rule.engine.api.Code;
+import com.pinterest.ktlint.rule.engine.api.EditorConfigDefaults;
+import com.pinterest.ktlint.rule.engine.api.EditorConfigOverride;
+import com.pinterest.ktlint.rule.engine.api.KtLintRuleEngine;
+import com.pinterest.ktlint.rule.engine.api.LintError;
+import com.pinterest.ktlint.rule.engine.core.api.Rule;
+import com.pinterest.ktlint.rule.engine.core.api.RuleId;
+import com.pinterest.ktlint.rule.engine.core.api.RuleProvider;
+import com.pinterest.ktlint.rule.engine.core.api.RuleSetId;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.CodeStyleEditorConfigPropertyKt;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EditorConfigProperty;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.EndOfLinePropertyKt;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.IndentSizeEditorConfigPropertyKt;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.IndentStyleEditorConfigPropertyKt;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.InsertFinalNewLineEditorConfigPropertyKt;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.MaxLineLengthEditorConfigPropertyKt;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.RuleExecution;
+import com.pinterest.ktlint.rule.engine.core.api.editorconfig.RuleExecutionEditorConfigPropertyKt;
+import com.pinterest.ktlint.ruleset.standard.StandardRuleSetProvider;
+
+import kotlin.Pair;
+import kotlin.Unit;
+import kotlin.jvm.functions.Function2;
+
+public class KtLintCompat0Dot50Dot0Adapter implements KtLintCompatAdapter {
+
+	private static final Logger logger = LoggerFactory.getLogger(KtLintCompat0Dot50Dot0Adapter.class);
+
+	private static final List<EditorConfigProperty<?>> DEFAULT_EDITOR_CONFIG_PROPERTIES;
+
+	static {
+		List<EditorConfigProperty<?>> list = new ArrayList<>();
+		list.add(CodeStyleEditorConfigPropertyKt.getCODE_STYLE_PROPERTY());
+		list.add(EndOfLinePropertyKt.getEND_OF_LINE_PROPERTY());
+		list.add(IndentSizeEditorConfigPropertyKt.getINDENT_SIZE_PROPERTY());
+		list.add(IndentStyleEditorConfigPropertyKt.getINDENT_STYLE_PROPERTY());
+		list.add(InsertFinalNewLineEditorConfigPropertyKt.getINSERT_FINAL_NEWLINE_PROPERTY());
+		list.add(MaxLineLengthEditorConfigPropertyKt.getMAX_LINE_LENGTH_PROPERTY());
+		list.add(RuleExecutionEditorConfigPropertyKt.getEXPERIMENTAL_RULES_EXECUTION_PROPERTY());
+		DEFAULT_EDITOR_CONFIG_PROPERTIES = Collections.unmodifiableList(list);
+	}
+
+	static class FormatterCallback implements Function2<LintError, Boolean, Unit> {
+
+		@Override
+		public Unit invoke(LintError lint, Boolean corrected) {
+			if (!corrected) {
+				KtLintCompatReporting.report(lint.getLine(), lint.getCol(), lint.getRuleId().getValue(), lint.getDetail());
+			}
+			return Unit.INSTANCE;
+		}
+	}
+
+	@Override
+	public String format(final String text, Path path, final boolean isScript,
+			final boolean useExperimental,
+			Path editorConfigPath, final Map<String, String> userData,
+			final Map<String, Object> editorConfigOverrideMap) {
+		final FormatterCallback formatterCallback = new FormatterCallback();
+
+		Set<RuleProvider> allRuleProviders = new LinkedHashSet<>(
+				new StandardRuleSetProvider().getRuleProviders());
+
+		// TODO: Should we keep `useExperimental` now that ktlint uses an EditorConfig property for this purpose?
+		if (useExperimental) {
+			String experimentalRulesPropertyName = RuleExecutionEditorConfigPropertyKt.getEXPERIMENTAL_RULES_EXECUTION_PROPERTY().getName();
+			Object experimentalOverride = editorConfigOverrideMap.get(experimentalRulesPropertyName);
+			if (experimentalOverride != null) {
+				logger.warn("`useExperimental` parameter is `true` and `ktlint_experimental` property is set, `useExperimental` will take priority!");
+				editorConfigOverrideMap.put(experimentalRulesPropertyName, "enabled");
+			}
+		}
+
+		EditorConfigOverride editorConfigOverride;
+		if (editorConfigOverrideMap.isEmpty()) {
+			editorConfigOverride = EditorConfigOverride.Companion.getEMPTY_EDITOR_CONFIG_OVERRIDE();
+		} else {
+			editorConfigOverride = createEditorConfigOverride(allRuleProviders.stream().map(
+					RuleProvider::createNewRuleInstance).collect(Collectors.toList()),
+					editorConfigOverrideMap);
+		}
+		EditorConfigDefaults editorConfig;
+		if (editorConfigPath == null || !Files.exists(editorConfigPath)) {
+			editorConfig = EditorConfigDefaults.Companion.getEMPTY_EDITOR_CONFIG_DEFAULTS();
+		} else {
+			editorConfig = EditorConfigDefaults.Companion.load(editorConfigPath);
+		}
+
+		return new KtLintRuleEngine(
+				allRuleProviders,
+				editorConfig,
+				editorConfigOverride,
+				false,
+				path.getFileSystem())
+				.format(Code.Companion.fromPath(path), formatterCallback);
+	}
+
+	/**
+	 * Create EditorConfigOverride from user provided parameters.
+	 */
+	private static EditorConfigOverride createEditorConfigOverride(final List<Rule> rules, Map<String, Object> editorConfigOverrideMap) {
+		// Get properties from rules in the rule sets
+		Stream<EditorConfigProperty<?>> ruleProperties = rules.stream()
+				.flatMap(rule -> rule.getUsesEditorConfigProperties().stream());
+
+		// Create a mapping of properties to their names based on rule properties and default properties
+		Map<String, EditorConfigProperty<?>> supportedProperties = Stream
+				.concat(ruleProperties, DEFAULT_EDITOR_CONFIG_PROPERTIES.stream())
+				.distinct()
+				.collect(Collectors.toMap(EditorConfigProperty::getName, property -> property));
+
+		// Create config properties based on provided property names and values
+		@SuppressWarnings("unchecked")
+		Pair<EditorConfigProperty<?>, ?>[] properties = editorConfigOverrideMap.entrySet().stream()
+				.map(entry -> {
+					EditorConfigProperty<?> property = supportedProperties.get(entry.getKey());
+					if (property != null) {
+						return new Pair<>(property, entry.getValue());
+					} else if (entry.getKey().startsWith("ktlint_")) {
+						String[] parts = entry.getKey().substring(7).split("_", 2);
+						if (parts.length == 1) {
+							// convert ktlint_{ruleset} to RuleSetId
+							RuleSetId id = new RuleSetId(parts[0]);
+							property = RuleExecutionEditorConfigPropertyKt.createRuleSetExecutionEditorConfigProperty(id, RuleExecution.disabled);
+						} else {
+							// convert ktlint_{ruleset}_{rulename} to RuleId
+							RuleId id = new RuleId(parts[0] + ":" + parts[1]);
+							property = RuleExecutionEditorConfigPropertyKt.createRuleExecutionEditorConfigProperty(id, RuleExecution.disabled);
+						}
+						return new Pair<>(property, entry.getValue());
+					} else {
+						return null;
+					}
+				})
+				.filter(Objects::nonNull)
+				.toArray(Pair[]::new);
+
+		return EditorConfigOverride.Companion.from(properties);
+	}
+}
Index: lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java b/lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java
--- a/lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java	(revision 88845df2179c3ea457e67eff39f7b3541908363c)
+++ b/lib/src/ktlint/java/com/diffplug/spotless/glue/ktlint/KtlintFormatterFunc.java	(date 1684552679281)
@@ -38,17 +38,16 @@
 	public KtlintFormatterFunc(String version, boolean isScript, boolean useExperimental, FileSignature editorConfigPath, Map<String, String> userData,
 			Map<String, Object> editorConfigOverrideMap) {
 		int minorVersion = Integer.parseInt(version.split("\\.")[1]);
-		if (minorVersion >= 49) {
+		if (minorVersion >= 50 || minorVersion == 49 && Integer.parseInt(version.split("\\.")[2]) == 2) {
+			this.adapter = new KtLintCompat0Dot50Dot0Adapter();
+		} else if (minorVersion == 49) {
 			// Packages and modules moved around (`ktlint-core` -> `ktlint-rule-engine`)
 			// Experimental ruleset was replaced by implementing `Rule.Experimental` and checking the `ktlint_experimental` `.editorconfig` property
 			// `RuleId` and `RuleSetId` became inline classes (mangled to be unrepresentable in Java source code, so reflection is needed), tracked here: https://github.com/pinterest/ktlint/issues/2041
 			this.adapter = new KtLintCompat0Dot49Dot0Adapter();
-		} else if (minorVersion == 48) {
+		} else {
 			// ExperimentalParams lost two constructor arguments, EditorConfigProperty moved to its own class
 			this.adapter = new KtLintCompat0Dot48Dot0Adapter();
-		} else {
-			// rename RuleSet to RuleProvider
-			this.adapter = new KtLintCompat0Dot47Dot0Adapter();
 		}
 		this.editorConfigPath = editorConfigPath;
 		this.useExperimental = useExperimental;
Index: lib/src/testCompatKtLint0Dot50Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot50Dot0AdapterTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/src/testCompatKtLint0Dot50Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot50Dot0AdapterTest.java b/lib/src/testCompatKtLint0Dot50Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot50Dot0AdapterTest.java
new file mode 100644
--- /dev/null	(date 1684552679298)
+++ b/lib/src/testCompatKtLint0Dot50Dot0/java/com/diffplug/spotless/glue/ktlint/compat/KtLintCompat0Dot50Dot0AdapterTest.java	(date 1684552679298)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2023 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.ktlint.compat;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+public class KtLintCompat0Dot50Dot0AdapterTest {
+	@Test
+	public void testDefaults(@TempDir Path path) throws IOException {
+		KtLintCompat0Dot50Dot0Adapter KtLintCompat0Dot50Dot0Adapter = new KtLintCompat0Dot50Dot0Adapter();
+		String text = loadAndWriteText(path, "EmptyClassBody.kt");
+		final Path filePath = Paths.get(path.toString(), "EmptyClassBody.kt");
+
+		Map<String, String> userData = new HashMap<>();
+
+		Map<String, Object> editorConfigOverrideMap = new HashMap<>();
+
+		String formatted = KtLintCompat0Dot50Dot0Adapter.format(text, filePath, false, false, null, userData, editorConfigOverrideMap);
+		assertEquals("class EmptyClassBody\n", formatted);
+	}
+
+	@Test
+	public void testEditorConfigCanDisable(@TempDir Path path) throws IOException {
+		KtLintCompat0Dot50Dot0Adapter KtLintCompat0Dot50Dot0Adapter = new KtLintCompat0Dot50Dot0Adapter();
+		String text = loadAndWriteText(path, "FailsNoSemicolons.kt");
+		final Path filePath = Paths.get(path.toString(), "FailsNoSemicolons.kt");
+
+		Map<String, String> userData = new HashMap<>();
+
+		Map<String, Object> editorConfigOverrideMap = new HashMap<>();
+		editorConfigOverrideMap.put("indent_style", "tab");
+		editorConfigOverrideMap.put("ktlint_standard_no-semi", "disabled");
+
+		String formatted = KtLintCompat0Dot50Dot0Adapter.format(text, filePath, false, false, null, userData, editorConfigOverrideMap);
+		assertEquals("class FailsNoSemicolons {\n\tval i = 0;\n}\n", formatted);
+	}
+
+	private static String loadAndWriteText(Path path, String name) throws IOException {
+		try (InputStream is = KtLintCompat0Dot50Dot0AdapterTest.class.getResourceAsStream("/" + name)) {
+			Files.copy(is, path.resolve(name));
+		}
+		return new String(Files.readAllBytes(path.resolve(name)), StandardCharsets.UTF_8);
+	}
+
+}
Index: lib/src/testCompatKtLint0Dot50Dot0/resources/EmptyClassBody.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/src/testCompatKtLint0Dot50Dot0/resources/EmptyClassBody.kt b/lib/src/testCompatKtLint0Dot50Dot0/resources/EmptyClassBody.kt
new file mode 100644
--- /dev/null	(date 1684552679268)
+++ b/lib/src/testCompatKtLint0Dot50Dot0/resources/EmptyClassBody.kt	(date 1684552679268)
@@ -0,0 +1,3 @@
+class EmptyClassBody {
+
+}
Index: lib/src/testCompatKtLint0Dot50Dot0/resources/FailsNoSemicolons.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/src/testCompatKtLint0Dot50Dot0/resources/FailsNoSemicolons.kt b/lib/src/testCompatKtLint0Dot50Dot0/resources/FailsNoSemicolons.kt
new file mode 100644
--- /dev/null	(date 1684552679261)
+++ b/lib/src/testCompatKtLint0Dot50Dot0/resources/FailsNoSemicolons.kt	(date 1684552679261)
@@ -0,0 +1,3 @@
+class FailsNoSemicolons {
+	val i = 0;
+}
Index: lib/build.gradle
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/lib/build.gradle b/lib/build.gradle
--- a/lib/build.gradle	(revision 88845df2179c3ea457e67eff39f7b3541908363c)
+++ b/lib/build.gradle	(date 1684552679306)
@@ -44,9 +44,9 @@
 			// we will support no more than 2 breaking changes at a time = 3 incompatible versions
 			// we will try to drop down to only one version if a stable API can be maintained for a full year
 			versions = [
-				'0.47.0',
 				'0.48.0',
 				'0.49.0',
+				'0.50.0',
 			]
 			targetSourceSetName = 'ktlint'
 		}
@@ -58,6 +58,13 @@
 	dependsOn(tasks.named("testCompatibility"))
 }
 
+repositories {
+	mavenCentral()
+	maven {
+		url "https://oss.sonatype.org/content/repositories/snapshots"
+	}
+}
+
 dependencies {
 	compileOnly 'org.slf4j:slf4j-api:2.0.0'
 	testCommonImplementation 'org.slf4j:slf4j-api:2.0.0'
@@ -95,21 +102,24 @@
 			strictly '1.7' // for JDK 8 compatibility
 		}
 	}
-	// ktlint
-	String VER_KTLINT='0.47.1'
+	// ktlint patch version of oldest supported version
+	String VER_KTLINT='0.48.2'
 	ktlintCompileOnly "com.pinterest:ktlint:$VER_KTLINT"
 	ktlintCompileOnly "com.pinterest.ktlint:ktlint-core:$VER_KTLINT"
 	ktlintCompileOnly "com.pinterest.ktlint:ktlint-ruleset-experimental:$VER_KTLINT"
 	ktlintCompileOnly "com.pinterest.ktlint:ktlint-ruleset-standard:$VER_KTLINT"
-	compatKtLint0Dot47Dot0CompileOnly 'com.pinterest.ktlint:ktlint-core:0.47.0'
-	compatKtLint0Dot47Dot0CompileOnly 'com.pinterest.ktlint:ktlint-ruleset-experimental:0.47.0'
-	compatKtLint0Dot47Dot0CompileOnly 'com.pinterest.ktlint:ktlint-ruleset-standard:0.47.0'
+	// Oldest ktlint supported version
 	compatKtLint0Dot48Dot0CompileAndTestOnly 'com.pinterest.ktlint:ktlint-core:0.48.0'
 	compatKtLint0Dot48Dot0CompileAndTestOnly 'com.pinterest.ktlint:ktlint-ruleset-experimental:0.48.0'
 	compatKtLint0Dot48Dot0CompileAndTestOnly 'com.pinterest.ktlint:ktlint-ruleset-standard:0.48.0'
+	// Second ktlint supported version
 	compatKtLint0Dot49Dot0CompileAndTestOnly 'com.pinterest.ktlint:ktlint-rule-engine:0.49.0'
 	compatKtLint0Dot49Dot0CompileAndTestOnly 'com.pinterest.ktlint:ktlint-ruleset-standard:0.49.0'
 	compatKtLint0Dot49Dot0CompileAndTestOnly 'org.slf4j:slf4j-api:2.0.0'
+	// Latest ktlint supported version
+	compatKtLint0Dot50Dot0CompileAndTestOnly 'com.pinterest.ktlint:ktlint-rule-engine:0.49.2-SNAPSHOT'
+	compatKtLint0Dot50Dot0CompileAndTestOnly 'com.pinterest.ktlint:ktlint-ruleset-standard:0.49.2-SNAPSHOT'
+	compatKtLint0Dot50Dot0CompileAndTestOnly 'org.slf4j:slf4j-api:2.0.0'
 	// palantirJavaFormat
 	palantirJavaFormatCompileOnly 'com.palantir.javaformat:palantir-java-format:1.1.0' 	// this version needs to stay compilable against Java 8 for CI Job testNpm
 	// scalafmt

@nedtwigg nedtwigg merged commit d107957 into diffplug:main May 22, 2023
@magneticflux- magneticflux- deleted the issue-1696-ktlint-update-0.49.0 branch May 22, 2023 22:29
@nedtwigg
Copy link
Member

Released in plugin-gradle 6.19.0 and plugin-maven 2.37.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for ktlint 0.49.0
2 participants