-
Notifications
You must be signed in to change notification settings - Fork 460
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement
buf format
Gradle step (#1208)
- Loading branch information
Showing
16 changed files
with
422 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
lib/src/main/java/com/diffplug/spotless/protobuf/BufStep.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/* | ||
* 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.protobuf; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.Serializable; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.regex.Pattern; | ||
|
||
import javax.annotation.Nullable; | ||
|
||
import com.diffplug.spotless.ForeignExe; | ||
import com.diffplug.spotless.FormatterFunc; | ||
import com.diffplug.spotless.FormatterStep; | ||
import com.diffplug.spotless.ProcessRunner; | ||
|
||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; | ||
|
||
public class BufStep { | ||
public static String name() { | ||
return "buf"; | ||
} | ||
|
||
public static String defaultVersion() { | ||
return "1.24.0"; | ||
} | ||
|
||
private final String version; | ||
private final @Nullable String pathToExe; | ||
|
||
private BufStep(String version, @Nullable String pathToExe) { | ||
this.version = version; | ||
this.pathToExe = pathToExe; | ||
} | ||
|
||
public static BufStep withVersion(String version) { | ||
return new BufStep(version, null); | ||
} | ||
|
||
public BufStep withPathToExe(String pathToExe) { | ||
return new BufStep(version, pathToExe); | ||
} | ||
|
||
public FormatterStep create() { | ||
return FormatterStep.createLazy(name(), this::createState, State::toFunc); | ||
} | ||
|
||
private State createState() throws IOException, InterruptedException { | ||
String instructions = "https://docs.buf.build/installation"; | ||
String exeAbsPath = ForeignExe.nameAndVersion("buf", version) | ||
.pathToExe(pathToExe) | ||
.versionRegex(Pattern.compile("(\\S*)")) | ||
.fixCantFind("Try following the instructions at " + instructions + ", or else tell Spotless where it is with {@code buf().pathToExe('path/to/executable')}") | ||
.confirmVersionAndGetAbsolutePath(); | ||
return new State(this, exeAbsPath); | ||
} | ||
|
||
@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") | ||
static class State implements Serializable { | ||
private static final long serialVersionUID = -1825662356883926318L; | ||
// used for up-to-date checks and caching | ||
final String version; | ||
// used for executing | ||
final transient List<String> args; | ||
|
||
State(BufStep step, String exeAbsPath) { | ||
this.version = step.version; | ||
this.args = Arrays.asList(exeAbsPath, "format"); | ||
} | ||
|
||
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()] = file.getAbsolutePath(); | ||
return runner.exec(input.getBytes(StandardCharsets.UTF_8), processArgs).assertExitZero(StandardCharsets.UTF_8); | ||
} | ||
|
||
FormatterFunc.Closeable toFunc() { | ||
ProcessRunner runner = new ProcessRunner(); | ||
return FormatterFunc.Closeable.of(runner, this::format); | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
lib/src/main/java/com/diffplug/spotless/protobuf/ProtobufConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* 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.protobuf; | ||
|
||
public class ProtobufConstants { | ||
public static final String LICENSE_HEADER_DELIMITER = "syntax"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
plugin-gradle/src/main/java/com/diffplug/gradle/spotless/ProtobufExtension.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* 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.gradle.spotless; | ||
|
||
import static com.diffplug.spotless.protobuf.ProtobufConstants.LICENSE_HEADER_DELIMITER; | ||
|
||
import java.util.Objects; | ||
|
||
import javax.inject.Inject; | ||
|
||
import com.diffplug.spotless.FormatterStep; | ||
import com.diffplug.spotless.protobuf.BufStep; | ||
|
||
public class ProtobufExtension extends FormatExtension implements HasBuiltinDelimiterForLicense { | ||
static final String NAME = "protobuf"; | ||
|
||
@Inject | ||
public ProtobufExtension(SpotlessExtension spotless) { | ||
super(spotless); | ||
} | ||
|
||
@Override | ||
public LicenseHeaderConfig licenseHeader(String licenseHeader) { | ||
return licenseHeader(licenseHeader, LICENSE_HEADER_DELIMITER); | ||
} | ||
|
||
@Override | ||
public LicenseHeaderConfig licenseHeaderFile(Object licenseHeaderFile) { | ||
return licenseHeaderFile(licenseHeaderFile, LICENSE_HEADER_DELIMITER); | ||
} | ||
|
||
/** If the user hasn't specified files, assume all protobuf files should be checked. */ | ||
@Override | ||
protected void setupTask(SpotlessTask task) { | ||
if (target == null) { | ||
target = parseTarget("**/*.proto"); | ||
} | ||
super.setupTask(task); | ||
} | ||
|
||
/** Adds the specified version of <a href="https://buf.build/">buf</a>. */ | ||
public BufFormatExtension buf(String version) { | ||
Objects.requireNonNull(version); | ||
return new BufFormatExtension(version); | ||
} | ||
|
||
public BufFormatExtension buf() { | ||
return buf(BufStep.defaultVersion()); | ||
} | ||
|
||
public class BufFormatExtension { | ||
BufStep step; | ||
|
||
BufFormatExtension(String version) { | ||
this.step = BufStep.withVersion(version); | ||
if (!steps.isEmpty()) { | ||
throw new IllegalArgumentException("buf() must be the first step, move other steps after it. Thumbs up [this issue](https://github.com/bufbuild/buf/issues/1035) for a resolution, see [here](https://github.com/diffplug/spotless/pull/1208#discussion_r1264439669) for more details on the problem."); | ||
} | ||
addStep(createStep()); | ||
} | ||
|
||
/** | ||
* When used in conjunction with the <a href=https://github.com/bufbuild/buf-gradle-plugin>{@code buf-gradle-plugin}</a>, | ||
* the {@code buf} executable can be resolved from its {@code bufTool} configuration: | ||
* | ||
* <pre> | ||
* {@code | ||
* spotless { | ||
* protobuf { | ||
* buf().pathToExe(configurations.getByName(BUF_BINARY_CONFIGURATION_NAME).getSingleFile().getAbsolutePath()) | ||
* } | ||
* } | ||
* } | ||
* </pre> | ||
* | ||
* Be sure to disable the {@code buf-gradle-plugin}'s execution of {@code buf format}: | ||
* | ||
* <pre> | ||
* {@code | ||
* buf { | ||
* enforceFormat = false | ||
* } | ||
* } | ||
* </pre> | ||
*/ | ||
public BufFormatExtension pathToExe(String pathToExe) { | ||
step = step.withPathToExe(pathToExe); | ||
replaceStep(createStep()); | ||
return this; | ||
} | ||
|
||
private FormatterStep createStep() { | ||
return step.create(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
plugin-gradle/src/test/java/com/diffplug/gradle/spotless/BufIntegrationTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* 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.gradle.spotless; | ||
|
||
import java.io.IOException; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import com.diffplug.spotless.tag.BufTest; | ||
|
||
@BufTest | ||
class BufIntegrationTest extends GradleIntegrationHarness { | ||
@Test | ||
void buf() throws IOException { | ||
setFile("build.gradle").toLines( | ||
"plugins {", | ||
" id 'com.diffplug.spotless'", | ||
"}", | ||
"spotless {", | ||
" protobuf {", | ||
" buf()", | ||
" }", | ||
"}"); | ||
setFile("buf.proto").toResource("protobuf/buf/buf.proto"); | ||
gradleRunner().withArguments("spotlessApply").build(); | ||
assertFile("buf.proto").sameAsResource("protobuf/buf/buf.proto.clean"); | ||
} | ||
|
||
@Test | ||
void bufWithLicense() throws IOException { | ||
setFile("build.gradle").toLines( | ||
"plugins {", | ||
" id 'com.diffplug.spotless'", | ||
"}", | ||
"spotless {", | ||
" protobuf {", | ||
" buf()", | ||
" licenseHeader '/* (C) 2022 */'", | ||
" }", | ||
"}"); | ||
setFile("license.proto").toResource("protobuf/buf/license.proto"); | ||
gradleRunner().withArguments("spotlessApply").build(); | ||
assertFile("license.proto").sameAsResource("protobuf/buf/license.proto.clean"); | ||
} | ||
} |
Oops, something went wrong.