From 1cbe523dba200baedf98f676ab3d9ead1950e276 Mon Sep 17 00:00:00 2001 From: bh-tt Date: Mon, 11 Jul 2022 16:44:24 +0200 Subject: [PATCH 1/5] Lazily check for foreign exes which may not be necessary for the current build --- .../spotless/cpp/ClangFormatStep.java | 56 ++++++++++--------- .../diffplug/spotless/python/BlackStep.java | 18 +++--- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java b/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java index 5256739004..e038aaec90 100644 --- a/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java +++ b/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java @@ -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; @@ -68,21 +69,20 @@ public FormatterStep create() { private State createState() throws IOException, InterruptedException { String howToInstall = "" + - "You can download clang-format from https://releases.llvm.org and " + - "then point Spotless to it with {@code pathToExe('/path/to/clang-format')} " + - "or you can use your platform's package manager:" + - "\n win: choco install llvm --version {version} (try dropping version if it fails)" + - "\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) - .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); + "You can download clang-format from https://releases.llvm.org and " + + "then point Spotless to it with {@code pathToExe('/path/to/clang-format')} " + + "or you can use your platform's package manager:" + + "\n win: choco install llvm --version {version} (try dropping version if it fails)" + + "\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"; + 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); + return new State(this, exe); } @SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") @@ -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 ForeignExe exe; // used for executing - final transient List args; + private @Nullable List 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 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() { diff --git a/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java b/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java index 6a03d0d808..b3f0c434f3 100644 --- a/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java +++ b/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java @@ -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; @@ -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); } @@ -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 ForeignExe exe; // used for executing - final transient List args; + private @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); } From 387b14db43054b4c2b2d2b01e1b0c9cccaff9394 Mon Sep 17 00:00:00 2001 From: bh-tt Date: Mon, 11 Jul 2022 16:50:14 +0200 Subject: [PATCH 2/5] Add to CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 7f6160b600..90b9ed95b3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( * Bump default `diktat` version to latest `1.1.0` -> `1.2.1` ([#1246](https://github.com/diffplug/spotless/pull/1246)) * Minimum supported version also bumped to `1.2.1` (diktat is based on ktlint and has the same backward compatibility issues). * Bump default `ktfmt` version to latest `0.37` -> `0.39` ([#1240](https://github.com/diffplug/spotless/pull/1240)) +* 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.26.2] - 2022-06-11 ### Fixed From 2338473edf8086c4d54b5053ffd89208c923d88c Mon Sep 17 00:00:00 2001 From: bh-tt Date: Wed, 13 Jul 2022 08:54:00 +0200 Subject: [PATCH 3/5] Transient State fields, fix CHANGES --- CHANGES.md | 4 ++-- .../main/java/com/diffplug/spotless/cpp/ClangFormatStep.java | 4 ++-- lib/src/main/java/com/diffplug/spotless/python/BlackStep.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 90b9ed95b3..4b0b1b0e2f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,7 +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 * Support for `MAC_CLASSIC` (`\r`) line ending ([#1243](https://github.com/diffplug/spotless/pull/1243) fixes [#1196](https://github.com/diffplug/spotless/issues/1196)) @@ -20,7 +21,6 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( * Bump default `diktat` version to latest `1.1.0` -> `1.2.1` ([#1246](https://github.com/diffplug/spotless/pull/1246)) * Minimum supported version also bumped to `1.2.1` (diktat is based on ktlint and has the same backward compatibility issues). * Bump default `ktfmt` version to latest `0.37` -> `0.39` ([#1240](https://github.com/diffplug/spotless/pull/1240)) -* 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.26.2] - 2022-06-11 ### Fixed diff --git a/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java b/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java index e038aaec90..aced507ee5 100644 --- a/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java +++ b/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java @@ -91,9 +91,9 @@ static class State implements Serializable { // used for up-to-date checks and caching final String version; final @Nullable String style; - final ForeignExe exe; + final transient ForeignExe exe; // used for executing - private @Nullable List args; + private transient @Nullable List args; State(ClangFormatStep step, ForeignExe pathToExe) { this.version = step.version; diff --git a/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java b/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java index b3f0c434f3..bf98a3a091 100644 --- a/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java +++ b/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java @@ -74,9 +74,9 @@ static class State implements Serializable { private static final long serialVersionUID = -1825662356883926318L; // used for up-to-date checks and caching final String version; - final ForeignExe exe; + final transient ForeignExe exe; // used for executing - private @Nullable String[] args; + private transient @Nullable String[] args; State(BlackStep step, ForeignExe exeAbsPath) { this.version = step.version; From 82353fd251ccce18c2eb5f2cf900775270513d16 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 26 Jul 2022 16:17:59 -0700 Subject: [PATCH 4/5] spotlessApply --- .../spotless/cpp/ClangFormatStep.java | 30 +++++++++---------- .../diffplug/spotless/python/BlackStep.java | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java b/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java index aced507ee5..2bff28e64e 100644 --- a/lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java +++ b/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. @@ -69,19 +69,19 @@ public FormatterStep create() { private State createState() throws IOException, InterruptedException { String howToInstall = "" + - "You can download clang-format from https://releases.llvm.org and " + - "then point Spotless to it with {@code pathToExe('/path/to/clang-format')} " + - "or you can use your platform's package manager:" + - "\n win: choco install llvm --version {version} (try dropping version if it fails)" + - "\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"; - 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); + "You can download clang-format from https://releases.llvm.org and " + + "then point Spotless to it with {@code pathToExe('/path/to/clang-format')} " + + "or you can use your platform's package manager:" + + "\n win: choco install llvm --version {version} (try dropping version if it fails)" + + "\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"; + 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); return new State(this, exe); } @@ -106,7 +106,7 @@ String format(ProcessRunner runner, String input, File file) throws IOException, final List tmpArgs = new ArrayList<>(); tmpArgs.add(exe.confirmVersionAndGetAbsolutePath()); if (style != null) { - tmpArgs.add("--style="+ style); + tmpArgs.add("--style=" + style); } args = tmpArgs; } diff --git a/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java b/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java index bf98a3a091..9bce2241dd 100644 --- a/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java +++ b/lib/src/main/java/com/diffplug/spotless/python/BlackStep.java @@ -85,7 +85,7 @@ static class State implements Serializable { String format(ProcessRunner runner, String input) throws IOException, InterruptedException { if (args == null) { - args = new String[] {exe.confirmVersionAndGetAbsolutePath(), "-"}; + args = new String[]{exe.confirmVersionAndGetAbsolutePath(), "-"}; } return runner.exec(input.getBytes(StandardCharsets.UTF_8), args).assertExitZero(StandardCharsets.UTF_8); } From 1ab9b311c8a308dc79cff3fa72069708c21e92a4 Mon Sep 17 00:00:00 2001 From: Ned Twigg Date: Tue, 26 Jul 2022 16:22:54 -0700 Subject: [PATCH 5/5] Update changelogs. --- CHANGES.md | 3 ++- plugin-gradle/CHANGES.md | 2 ++ plugin-maven/CHANGES.md | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 4b0b1b0e2f..bed2af6281 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,7 +11,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format ( ## [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)) +* 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 * Support for `MAC_CLASSIC` (`\r`) line ending ([#1243](https://github.com/diffplug/spotless/pull/1243) fixes [#1196](https://github.com/diffplug/spotless/issues/1196)) diff --git a/plugin-gradle/CHANGES.md b/plugin-gradle/CHANGES.md index 02d8da736d..43a1fb1d24 100644 --- a/plugin-gradle/CHANGES.md +++ b/plugin-gradle/CHANGES.md @@ -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 diff --git a/plugin-maven/CHANGES.md b/plugin-maven/CHANGES.md index 2cc389b7d3..3499aeab36 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 +* 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