Skip to content

Commit

Permalink
Add support for gofmt (#2001)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg committed Jan 22, 2024
2 parents 13d9627 + a145ac0 commit 706f18e
Show file tree
Hide file tree
Showing 19 changed files with 463 additions and 4 deletions.
4 changes: 2 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (

## [Unreleased]
### Added
* Maven - Support for formatting shell scripts via [shfmt](https://github.com/mvdan/sh). ([#1998](https://github.com/diffplug/spotless/pull/1998))
* Maven / Gradle - Support for formatting Java Docs for the Palantir formatter ([#2009](https://github.com/diffplug/spotless/pull/2009))
* Support for `gofmt` ([#2001](https://github.com/diffplug/spotless/pull/2001))
* Support for formatting Java Docs for the Palantir formatter ([#2009](https://github.com/diffplug/spotless/pull/2009))

## [2.44.0] - 2024-01-15
### Added
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ lib('antlr4.Antlr4FormatterStep') +'{{yes}} | {{yes}}
lib('biome.BiomeStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
lib('cpp.ClangFormatStep') +'{{yes}} | {{no}} | {{no}} | {{no}} |',
extra('cpp.EclipseFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('go.GofmtFormatStep') +'{{yes}} | {{no}} | {{no}} | {{no}} |',
lib('gherkin.GherkinUtilsStep') +'{{yes}} | {{yes}} | {{no}} | {{no}} |',
extra('groovy.GrEclipseFormatterStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
lib('java.GoogleJavaFormatStep') +'{{yes}} | {{yes}} | {{yes}} | {{no}} |',
Expand Down Expand Up @@ -131,6 +132,7 @@ lib('yaml.JacksonYamlStep') +'{{yes}} | {{yes}}
| [`biome.BiomeStep`](lib/src/main/java/com/diffplug/spotless/biome/BiomeStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`cpp.ClangFormatStep`](lib/src/main/java/com/diffplug/spotless/cpp/ClangFormatStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: |
| [`cpp.EclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/cpp/EclipseFormatterStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`go.GofmtFormatStep`](lib/src/main/java/com/diffplug/spotless/go/GofmtFormatStep.java) | :+1: | :white_large_square: | :white_large_square: | :white_large_square: |
| [`gherkin.GherkinUtilsStep`](lib/src/main/java/com/diffplug/spotless/gherkin/GherkinUtilsStep.java) | :+1: | :+1: | :white_large_square: | :white_large_square: |
| [`groovy.GrEclipseFormatterStep`](lib-extra/src/main/java/com/diffplug/spotless/extra/groovy/GrEclipseFormatterStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
| [`java.GoogleJavaFormatStep`](lib/src/main/java/com/diffplug/spotless/java/GoogleJavaFormatStep.java) | :+1: | :+1: | :+1: | :white_large_square: |
Expand Down
1 change: 1 addition & 0 deletions gradle/special-tests.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ def special = [
'Black',
'Buf',
'Clang',
'gofmt',
'Npm',
'Shfmt'
]
Expand Down
111 changes: 111 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/go/GofmtFormatStep.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright 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.go;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

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;

/**
* Note: gofmt doesn't have a version flag, because it's part of standard Go distribution.
* So `go` executable can be used to determine base path and version, and path to gofmt can be built from it.
*/
public class GofmtFormatStep {
public static String name() {
return "gofmt";
}

public static String defaultVersion() {
return "go1.20.0";
}

private final String version;
private final @Nullable String pathToExe;

private GofmtFormatStep(String version, String pathToExe) {
this.version = version;
this.pathToExe = pathToExe;
}

public static GofmtFormatStep withVersion(String version) {
return new GofmtFormatStep(version, null);
}

public GofmtFormatStep withGoExecutable(String pathToExe) {
return new GofmtFormatStep(version, pathToExe);
}

public FormatterStep create() {
return FormatterStep.createLazy(name(), this::createState, GofmtFormatStep.State::toFunc);
}

private State createState() throws IOException, InterruptedException {
String howToInstall = "gofmt is a part of standard go distribution. If spotless can't discover it automatically, " +
"you can point Spotless to the go binary with {@code pathToExe('/path/to/go')}";
final ForeignExe exe = ForeignExe.nameAndVersion("go", version)
.pathToExe(pathToExe)
.versionFlag("version")
.fixCantFind(howToInstall)
.fixWrongVersion(
"You can tell Spotless to use the version you already have with {@code gofmt('{versionFound}')}" +
"or you can install the currently specified Go version, {version}.\n" + howToInstall);
return new State(this, exe);
}

@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED")
static class State implements Serializable {
private static final long serialVersionUID = -1825662355363926318L;
// used for up-to-date checks and caching
final String version;
final transient ForeignExe exe;

public State(GofmtFormatStep step, ForeignExe goExecutable) {
this.version = step.version;
this.exe = Objects.requireNonNull(goExecutable);
}

String format(ProcessRunner runner, String input, File file) throws IOException, InterruptedException {
final List<String> processArgs = new ArrayList<>();
String pathToGoBinary = exe.confirmVersionAndGetAbsolutePath();
Path goBasePath = Path.of(pathToGoBinary).getParent();
if (goBasePath == null) {
throw new IllegalStateException("Unable to resolve base path of Go installation directory");
}
String pathToGoFmt = goBasePath.resolve("gofmt").toString();
processArgs.add(pathToGoFmt);
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);
}
}
}
1 change: 1 addition & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).

## [Unreleased]
* Support for `gofmt` ([#2001](https://github.com/diffplug/spotless/pull/2001))

### 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
@@ -0,0 +1,57 @@
/*
* Copyright 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 javax.inject.Inject;

import com.diffplug.spotless.FormatterStep;
import com.diffplug.spotless.go.GofmtFormatStep;

public class GoExtension extends FormatExtension {
public static final String NAME = "go";

@Inject
public GoExtension(SpotlessExtension spotless) {
super(spotless);
}

public GofmtConfig gofmt() {
return new GofmtConfig(GofmtFormatStep.defaultVersion());
}

public GofmtConfig gofmt(String version) {
return new GofmtConfig(version);
}

public class GofmtConfig {
GofmtFormatStep stepCfg;

public GofmtConfig(String version) {
stepCfg = GofmtFormatStep.withVersion(version);
addStep(createStep());
}

public GofmtConfig withGoExecutable(String pathToGo) {
stepCfg = stepCfg.withGoExecutable(pathToGo);
replaceStep(createStep());
return this;
}

private FormatterStep createStep() {
return stepCfg.create();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ public void gherkin(Action<GherkinExtension> closure) {
format(GherkinExtension.NAME, GherkinExtension.class, closure);
}

public void go(Action<GoExtension> closure) {
requireNonNull(closure);
format(GoExtension.NAME, GoExtension.class, closure);
}

/** Configures a custom extension. */
public void format(String name, Action<FormatExtension> closure) {
requireNonNull(name, "name");
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.GofmtTest;

@GofmtTest
class GoGradleTest extends GradleIntegrationHarness {
@Test
void gofmt() throws IOException {
setFile("build.gradle").toLines(
"plugins {",
" id 'com.diffplug.spotless'",
"}",
"spotless {",
" go {",
" target 'src/**/*.go'",
" gofmt(\"go1.21.5\")",
" }",
"}");
setFile("src/test.go").toResource("go/gofmt/go.dirty");
gradleRunner().withArguments("spotlessApply").build();
assertFile("src/test.go").sameAsResource("go/gofmt/go.clean");
}
}
3 changes: 2 additions & 1 deletion plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (
## [Unreleased]
### Added
* Support for formatting shell scripts via [shfmt](https://github.com/mvdan/sh). ([#1998](https://github.com/diffplug/spotless/issues/1998))
* Maven / Gradle - Support for formatting Java Docs for the Palantir formatter ([#2009](https://github.com/diffplug/spotless/pull/2009))
* Support for `gofmt` ([#2001](https://github.com/diffplug/spotless/pull/2001))
* Support for formatting Java Docs for the Palantir formatter ([#2009](https://github.com/diffplug/spotless/pull/2009))

## [2.42.0] - 2024-01-15
### Added
Expand Down
28 changes: 28 additions & 0 deletions plugin-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ user@machine repo % mvn spotless:check
- [JSON](#json) ([simple](#simple), [gson](#gson), [jackson](#jackson), [Biome](#biome), [jsonPatch](#jsonPatch))
- [YAML](#yaml)
- [Gherkin](#gherkin)
- [Go](#go)
- Multiple languages
- [Prettier](#prettier) ([plugins](#prettier-plugins), [npm detection](#npm-detection), [`.npmrc` detection](#npmrc-detection), [caching `npm install` results](#caching-results-of-npm-install))
- [eclipse web tools platform](#eclipse-web-tools-platform)
Expand Down Expand Up @@ -1048,6 +1049,33 @@ Uses a Gherkin pretty-printer that optionally allows configuring the number of s
</gherkinUtils>
```

## Go

- `com.diffplug.spotless.maven.FormatterFactory.addStepFactory(FormatterStepFactory)` [code](https://github.com/diffplug/spotless/blob/main/plugin-maven/src/main/java/com/diffplug/spotless/maven/go/Go.java)

```xml
<configuration>
<go>
<includes> <!-- You have to set the target manually -->
<include>src/**/*.go</include>
</includes>

<gofmt /> <!-- has its own section below -->
</go>
</configuration>
```

### gofmt

Standard Go formatter, part of Go distribution.

```xml
<gofmt>
<version>go1.25.1</version>
<goExecutablePath>/opt/sdks/go1.25.1/bin/go</goExecutablePath>
</gofmt>
```

## Prettier

[homepage](https://prettier.io/). [changelog](https://github.com/prettier/prettier/blob/master/CHANGELOG.md). [official plugins](https://prettier.io/docs/en/plugins.html#official-plugins). [community plugins](https://prettier.io/docs/en/plugins.html#community-plugins). Prettier is a formatter that can format almost every anything - JavaScript, JSX, Angular, Vue, Flow, TypeScript, CSS, Less, SCSS, HTML, JSON, GraphQL, Markdown (including GFM and MDX), and YAML. It can format even more [using plugins](https://prettier.io/docs/en/plugins.html) (PHP, Ruby, Swift, XML, Apex, Elm, Java (!!), Kotlin, pgSQL, .properties, solidity, svelte, toml, shellscript, ...).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import com.diffplug.spotless.maven.generic.Format;
import com.diffplug.spotless.maven.generic.LicenseHeader;
import com.diffplug.spotless.maven.gherkin.Gherkin;
import com.diffplug.spotless.maven.go.Go;
import com.diffplug.spotless.maven.groovy.Groovy;
import com.diffplug.spotless.maven.incremental.UpToDateChecker;
import com.diffplug.spotless.maven.incremental.UpToDateChecking;
Expand Down Expand Up @@ -188,6 +189,9 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
@Parameter
private Gherkin gherkin;

@Parameter
private Go go;

@Parameter(property = "spotlessFiles")
private String filePatterns;

Expand Down Expand Up @@ -362,7 +366,7 @@ private FileLocator getFileLocator() {
}

private List<FormatterFactory> getFormatterFactories() {
return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, javascript, antlr4, pom, sql, python, markdown, json, shell, yaml, gherkin))
return Stream.concat(formats.stream(), Stream.of(groovy, java, scala, kotlin, cpp, typescript, javascript, antlr4, pom, sql, python, markdown, json, shell, yaml, gherkin, go))
.filter(Objects::nonNull)
.collect(toList());
}
Expand Down
39 changes: 39 additions & 0 deletions plugin-maven/src/main/java/com/diffplug/spotless/maven/go/Go.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 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.go;

import java.util.Collections;
import java.util.Set;

import org.apache.maven.project.MavenProject;

import com.diffplug.spotless.maven.FormatterFactory;

public class Go extends FormatterFactory {
@Override
public Set<String> defaultIncludes(MavenProject project) {
return Collections.emptySet();
}

@Override
public String licenseHeaderDelimiter() {
return null;
}

public void addGofmt(Gofmt gofmt) {
addStepFactory(gofmt);
}
}
Loading

0 comments on commit 706f18e

Please sign in to comment.