Skip to content

Commit

Permalink
Lazily check for foreign exes in case they aren't needed (#1257)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg committed Jul 27, 2022
2 parents 5ac8023 + ff1100c commit d78b6e3
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 24 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -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
* Clang and Black no longer break the build when the binary is unavailable, if they will not be run during that build ([#1257](https://github.com/diffplug/spotless/pull/1257)).

## [2.27.0] - 2022-06-30
### Added
Expand Down
36 changes: 20 additions & 16 deletions lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java
@@ -1,5 +1,5 @@
/*
* Copyright 2020-2021 DiffPlug
* Copyright 2020-2022 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -21,6 +21,7 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import javax.annotation.Nullable;

Expand Down Expand Up @@ -75,14 +76,13 @@ private State createState() throws IOException, InterruptedException {
"\n mac: brew install clang-format (TODO: how to specify version?)" +
"\n linux: apt install clang-format (try clang-format-{version} with dropped minor versions)" +
"\n github issue to handle this better: https://github.com/diffplug/spotless/issues/673";
String exeAbsPath = ForeignExe.nameAndVersion("clang-format", version)
final ForeignExe exe = ForeignExe.nameAndVersion("clang-format", version)
.pathToExe(pathToExe)
.fixCantFind(howToInstall)
.fixWrongVersion(
"You can tell Spotless to use the version you already have with {@code clangFormat('{versionFound}')}" +
"or you can download the currently specified version, {version}.\n" + howToInstall)
.confirmVersionAndGetAbsolutePath();
return new State(this, exeAbsPath);
"or you can download the currently specified version, {version}.\n" + howToInstall);
return new State(this, exe);
}

@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
Expand All @@ -91,24 +91,28 @@ static class State implements Serializable {
// used for up-to-date checks and caching
final String version;
final @Nullable String style;
final transient ForeignExe exe;
// used for executing
final transient List<String> args;
private transient @Nullable List<String> args;

State(ClangFormatStep step, String exeAbsPath) {
State(ClangFormatStep step, ForeignExe pathToExe) {
this.version = step.version;
this.style = step.style;
args = new ArrayList<>(2);
args.add(exeAbsPath);
if (style != null) {
args.add("--style=" + style);
}
this.exe = Objects.requireNonNull(pathToExe);
}

String format(ProcessRunner runner, String input, File file) throws IOException, InterruptedException {
String[] processArgs = args.toArray(new String[args.size() + 1]);
// add an argument to the end
processArgs[args.size()] = "--assume-filename=" + file.getName();
return runner.exec(input.getBytes(StandardCharsets.UTF_8), processArgs).assertExitZero(StandardCharsets.UTF_8);
if (args == null) {
final List<String> tmpArgs = new ArrayList<>();
tmpArgs.add(exe.confirmVersionAndGetAbsolutePath());
if (style != null) {
tmpArgs.add("--style=" + style);
}
args = tmpArgs;
}
final String[] processArgs = args.toArray(new String[args.size() + 1]);
processArgs[processArgs.length - 1] = "--assume-filename=" + file.getName();
return runner.exec(input.getBytes(StandardCharsets.UTF_8), args).assertExitZero(StandardCharsets.UTF_8);
}

FormatterFunc.Closeable toFunc() {
Expand Down
18 changes: 10 additions & 8 deletions lib/src/main/java/com/diffplug/spotless/python/BlackStep.java
Expand Up @@ -18,8 +18,7 @@
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

import javax.annotation.Nullable;
Expand Down Expand Up @@ -62,12 +61,11 @@ public FormatterStep create() {

private State createState() throws IOException, InterruptedException {
String trackingIssue = "\n github issue to handle this better: https://github.com/diffplug/spotless/issues/674";
String exeAbsPath = ForeignExe.nameAndVersion("black", version)
ForeignExe exeAbsPath = ForeignExe.nameAndVersion("black", version)
.pathToExe(pathToExe)
.versionRegex(Pattern.compile("(?:black, version|black,|version) (\\S*)"))
.fixCantFind("Try running {@code pip install black=={version}}, or else tell Spotless where it is with {@code black().pathToExe('path/to/executable')}" + trackingIssue)
.fixWrongVersion("Try running {@code pip install --force-reinstall black=={version}}, or else specify {@code black('{versionFound}')} to Spotless" + trackingIssue)
.confirmVersionAndGetAbsolutePath();
.fixWrongVersion("Try running {@code pip install --force-reinstall black=={version}}, or else specify {@code black('{versionFound}')} to Spotless" + trackingIssue);
return new State(this, exeAbsPath);
}

Expand All @@ -76,15 +74,19 @@ static class State implements Serializable {
private static final long serialVersionUID = -1825662356883926318L;
// used for up-to-date checks and caching
final String version;
final transient ForeignExe exe;
// used for executing
final transient List<String> args;
private transient @Nullable String[] args;

State(BlackStep step, String exeAbsPath) {
State(BlackStep step, ForeignExe exeAbsPath) {
this.version = step.version;
this.args = Arrays.asList(exeAbsPath, "-");
this.exe = Objects.requireNonNull(exeAbsPath);
}

String format(ProcessRunner runner, String input) throws IOException, InterruptedException {
if (args == null) {
args = new String[]{exe.confirmVersionAndGetAbsolutePath(), "-"};
}
return runner.exec(input.getBytes(StandardCharsets.UTF_8), args).assertExitZero(StandardCharsets.UTF_8);
}

Expand Down
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Expand Up @@ -3,6 +3,8 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).

## [Unreleased]
### Added
* Clang and Black no longer break the build when the binary is unavailable, if they will not be run during that build ([#1257](https://github.com/diffplug/spotless/pull/1257)).

## [6.8.0] - 2022-06-30
### Added
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Expand Up @@ -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
* Clang and Black no longer break the build when the binary is unavailable, if they will not be run during that build ([#1257](https://github.com/diffplug/spotless/pull/1257)).

## [2.23.0] - 2022-06-30
### Added
Expand Down

0 comments on commit d78b6e3

Please sign in to comment.