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

IntelliJ formatter #2020

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (

## [Unreleased]

* Support for `idea` ([#2020](https://github.com/diffplug/spotless/pull/2020))
nedtwigg marked this conversation as resolved.
Show resolved Hide resolved

## [2.45.0] - 2024-01-23
### Added
* Support for `gofmt` ([#2001](https://github.com/diffplug/spotless/pull/2001))
Expand Down
1 change: 1 addition & 0 deletions gradle/special-tests.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ def special = [
'Buf',
'Clang',
'gofmt',
'idea',
'Npm',
'Shfmt'
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.diffplug.spotless.java;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.diffplug.spotless.ForeignExe;
import com.diffplug.spotless.FormatterFunc;
import com.diffplug.spotless.ProcessRunner;

public final class IdeaFormatterFunc implements FormatterFunc.NeedsFile {

private static final Logger LOGGER =
LoggerFactory.getLogger(IdeaStep.class);

private static final String DEFAULT_IDEA = "idea";

private String binaryPath;
private String configPath;
private boolean withDefaults;

private IdeaFormatterFunc(boolean withDefaults, String binaryPath,
String configPath) {
this.withDefaults = withDefaults;
this.configPath = configPath;
this.binaryPath = Objects.requireNonNullElse(binaryPath, DEFAULT_IDEA);
resolveFullBinaryPathAndCheckVersion();
}

private void resolveFullBinaryPathAndCheckVersion() {
var exe = ForeignExe.nameAndVersion(this.binaryPath, "IntelliJ IDEA")
.versionRegex(Pattern.compile("(IntelliJ IDEA) .*"))
.fixCantFind("IDEA executable cannot be found on your machine, "
+ "please install it and put idea binary to PATH; or report the problem")
.fixWrongVersion("Provided binary is not IDEA, "
+ "please check it and fix the problem; or report the problem");
try {
this.binaryPath = exe.confirmVersionAndGetAbsolutePath();
} catch (IOException e) {
throw new IllegalArgumentException("binary cannot be found", e);
} catch (InterruptedException e) {
throw new IllegalArgumentException(
"binary cannot be found, process was interrupted", e);
}
nedtwigg marked this conversation as resolved.
Show resolved Hide resolved
}

public static IdeaFormatterFunc allowingDefaultsWithCustomBinary(
String binaryPath, String configPath) {
return new IdeaFormatterFunc(true, binaryPath, configPath);
}

public static IdeaFormatterFunc noDefaultsWithCustomBinary(
String binaryPath, String configPath) {
return new IdeaFormatterFunc(false, binaryPath, configPath);
}

@Override
public String applyWithFile(String unix, File file) throws Exception {
List<String> params = getParams(file);

try (ProcessRunner runner = new ProcessRunner()) {
var result = runner.exec(params);

LOGGER.debug("command finished with stdout: {}",
result.assertExitZero(StandardCharsets.UTF_8));

return Files.readString(file.toPath());
}
}

private List<String> getParams(File file) {
var builder = Stream.<String>builder();
builder.add(binaryPath);
builder.add("format");
if (withDefaults) {
builder.add("-allowDefaults");
}
if (configPath != null) {
builder.add("-s");
builder.add(configPath);
}
builder.add(file.toString());
return builder.build().collect(Collectors.toList());
}

}
39 changes: 39 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/java/IdeaStep.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.diffplug.spotless.java;

import com.diffplug.spotless.FormatterStep;

public final class IdeaStep {

private IdeaStep() {}

public static FormatterStep create() {
return create(true);
}

public static FormatterStep create(boolean withDefaults) {
return create(true, null);
}

public static FormatterStep create(boolean withDefaults,
String binaryPath) {
return create(withDefaults, binaryPath, null);
}

public static FormatterStep create(boolean withDefaults,
String binaryPath, String configPath) {
IdeaFormatterFunc formatterFunc =
getFormatterFunc(withDefaults, binaryPath, configPath);
// TODO: make it lazy
return FormatterStep.createNeverUpToDate("IDEA", formatterFunc);
}

private static IdeaFormatterFunc getFormatterFunc(boolean withDefaults,
String binaryPath, String configPath) {
if (withDefaults) {
return IdeaFormatterFunc
.allowingDefaultsWithCustomBinary(binaryPath, configPath);
}
return IdeaFormatterFunc.noDefaultsWithCustomBinary(binaryPath, configPath);
}

}
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (

## [Unreleased]

* Support for `idea` ([#2020](https://github.com/diffplug/spotless/pull/2020))

## [6.25.0] - 2024-01-23
### Added
* Maven / Gradle - Support for formatting Java Docs for the Palantir formatter ([#2009](https://github.com/diffplug/spotless/pull/2009))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import com.diffplug.spotless.java.CleanthatJavaStep;
import com.diffplug.spotless.java.FormatAnnotationsStep;
import com.diffplug.spotless.java.GoogleJavaFormatStep;
import com.diffplug.spotless.java.IdeaStep;
import com.diffplug.spotless.java.ImportOrderStep;
import com.diffplug.spotless.java.PalantirJavaFormatStep;
import com.diffplug.spotless.java.RemoveUnusedImportsStep;
Expand Down Expand Up @@ -313,6 +314,45 @@ public EclipseConfig withP2Mirrors(Map<String, String> mirrors) {

}

public IdeaConfig idea() {
return new IdeaConfig();
}

public class IdeaConfig {
String binaryPath;
String configPath;
boolean withDefaults = false;

IdeaConfig() {
addStep(createStep());
}

private FormatterStep createStep() {
return IdeaStep.create(withDefaults, binaryPath);
}

public IdeaConfig binaryPath(String binaryPath) {
Objects.requireNonNull(binaryPath);
this.binaryPath = binaryPath;
replaceStep(createStep());
return this;
}

public IdeaConfig configPath(String configPath) {
Objects.requireNonNull(configPath);
this.configPath = configPath;
replaceStep(createStep());
return this;
}

public IdeaConfig withDefaults(Boolean withDefaults) {
Objects.requireNonNull(withDefaults);
this.withDefaults = withDefaults;
replaceStep(createStep());
return this;
}
}

/** Removes newlines between type annotations and types. */
public FormatAnnotationsConfig formatAnnotations() {
return new FormatAnnotationsConfig();
Expand Down Expand Up @@ -400,7 +440,7 @@ public CleanthatJavaConfig clearMutators() {
}

// An id of a mutator (see IMutator.getIds()) or
// tThe fully qualified name of a class implementing eu.solven.cleanthat.engine.java.refactorer.meta.IMutator
// The fully qualified name of a class implementing eu.solven.cleanthat.engine.java.refactorer.meta.IMutator
public CleanthatJavaConfig addMutator(String mutator) {
this.mutators.add(mutator);
replaceStep(createStep());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2020-2024 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.gradle.spotless;

import java.io.IOException;

import org.junit.jupiter.api.Test;
import com.diffplug.spotless.tag.IdeaTest;

@IdeaTest
class JavaIdeaTest extends GradleIntegrationHarness {
@Test
void idea() throws IOException {
setFile("build.gradle").toLines(
"plugins {",
" id 'com.diffplug.spotless'",
"}",
"spotless {",
" java {",
" target file('test.java')",
" idea().binaryPath('idea').withDefaults(true)",
" }",
"}");

setFile("test.java").toResource("java/idea/full.dirty.java");
gradleRunner().withArguments("spotlessApply").build();
assertFile("test.java").notSameAsResource("java/idea/full.dirty.java");
}
}
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (

## [Unreleased]

* Support for `idea` ([#2020](https://github.com/diffplug/spotless/pull/2020))

## [2.43.0] - 2024-01-23
### Added
* Support for formatting shell scripts via [shfmt](https://github.com/mvdan/sh). ([#1998](https://github.com/diffplug/spotless/issues/1998))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2016-2024 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.java;

import org.apache.maven.plugins.annotations.Parameter;
import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.java.IdeaStep;
import com.diffplug.spotless.maven.FormatterStepConfig;
import com.diffplug.spotless.maven.FormatterStepFactory;

public class Idea implements FormatterStepFactory {

@Parameter
private String binaryPath;

@Parameter
private String configPath;

@Parameter
private Boolean withDefaults = false;

@Override
public FormatterStep newFormatterStep(FormatterStepConfig config) {
return IdeaStep.create(withDefaults, binaryPath, configPath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ public void addImportOrder(ImportOrder importOrder) {
addStepFactory(importOrder);
}

public void addIdea(Idea idea) {
addStepFactory(idea);
}

public void addPalantirJavaFormat(PalantirJavaFormat palantirJavaFormat) {
addStepFactory(palantirJavaFormat);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.maven.java;

import org.junit.jupiter.api.Test;

import com.diffplug.spotless.maven.MavenIntegrationHarness;

@com.diffplug.spotless.tag.IdeaTest
class IdeaTest extends MavenIntegrationHarness {
@Test
void idea() throws Exception {
setFile("test.java").toResource("java/cleanthat/MultipleMutators.dirty.test");
writePomWithJavaSteps(
"<idea>",
" <binaryPath>idea</binaryPath>",
" <withDefaults>true</withDefaults>",
"</idea>");

mavenRunner().withArguments("spotless:apply").runNoError();

assertFile("test.java").notSameAsResource("java/cleanthat/MultipleMutators.dirty.test");
}
}
12 changes: 12 additions & 0 deletions testlib/src/main/java/com/diffplug/spotless/ResourceHarness.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,18 @@ public void hasContent(String expected) {
hasContent(expected, StandardCharsets.UTF_8);
}

public void hasDifferentContent(String expected) {
hasDifferentContent(expected, StandardCharsets.UTF_8);
}

public void hasContent(String expected, Charset charset) {
assertThat(file).usingCharset(charset).hasContent(expected);
}

public void hasDifferentContent(String expected, Charset charset) {
assertThat(file).usingCharset(charset).isNotEqualTo(expected);
}

public void hasLines(String... lines) {
hasContent(String.join("\n", Arrays.asList(lines)));
}
Expand All @@ -163,6 +171,10 @@ public void sameAsResource(String resource) throws IOException {
hasContent(getTestResource(resource));
}

public void notSameAsResource(String resource) throws IOException {
hasDifferentContent(getTestResource(resource));
}

public void matches(Consumer<AbstractCharSequenceAssert<?, String>> conditions) throws IOException {
String content = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
conditions.accept(assertThat(content));
Expand Down
Loading
Loading