Skip to content
Merged
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))

## [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);
}
}

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