Skip to content

Commit

Permalink
Merge branch 'main' into feat/equo-solstice
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg committed Mar 13, 2023
2 parents f93fccc + f2558fe commit cdcfe14
Show file tree
Hide file tree
Showing 35 changed files with 344 additions and 106 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ jobs:
with:
gradle-home-cache-cleanup: true
- name: spotlessCheck
run: ./gradlew spotlessCheck --build-cache
run: ./gradlew spotlessCheck
- name: assemble testClasses
run: ./gradlew assemble testClasses --build-cache
run: ./gradlew assemble testClasses
build:
needs: sanityCheck
strategy:
Expand Down Expand Up @@ -71,13 +71,13 @@ jobs:
gradle-home-cache-cleanup: true
- name: build (maven-only)
if: matrix.kind == 'maven'
run: ./gradlew :plugin-maven:build -x spotlessCheck --build-cache
run: ./gradlew :plugin-maven:build -x spotlessCheck
- name: build (everything-but-maven)
if: matrix.kind == 'gradle'
run: ./gradlew build -x spotlessCheck --build-cache -PSPOTLESS_EXCLUDE_MAVEN=true
run: ./gradlew build -x spotlessCheck -PSPOTLESS_EXCLUDE_MAVEN=true
- name: test npm
if: matrix.kind == 'npm'
run: ./gradlew testNpm --build-cache
run: ./gradlew testNpm
- name: junit result
uses: mikepenz/action-junit-report@v3
if: always() # always run even if the previous step fails
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
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
* You can now put the filename into a license header template with `$FILE`. ([#1605](https://github.com/diffplug/spotless/pull/1605) fixes [#1147](https://github.com/diffplug/spotless/issues/1147))
### Changes
* We are now opting in to Gradle's new stable configuration cache. ([#1591](https://github.com/diffplug/spotless/pull/1591))
* Adopt [Equo Solstice OSGi and p2 shim](https://github.com/equodev/equo-ide/tree/main/solstice) to update all Eclipse-based plugins. ([#1524](https://github.com/diffplug/spotless/pull/1524))
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ VER_SLF4J=[1.6,2.0[

# Used in multiple places
VER_DURIAN=1.2.0
VER_JGIT=6.4.0.202211300538-r
VER_JGIT=6.5.0.202303070854-r
VER_JUNIT=5.9.2
VER_ASSERTJ=3.24.2
VER_MOCKITO=5.1.1
VER_MOCKITO=5.2.0
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@

/** Prefixes a license header before the package statement. */
public final class LicenseHeaderStep {
public static final String DEFAULT_JAVA_HEADER_DELIMITER = "(package|import|public|class|module) ";
private static final Logger LOGGER = LoggerFactory.getLogger(LicenseHeaderStep.class);

public enum YearMode {
Expand Down Expand Up @@ -142,7 +143,7 @@ public FormatterStep build() {
throw new IllegalStateException(yearMode.toString());
}
return new Runtime(headerLazy.get(), delimiter, yearSeparator, updateYear, skipLinesMatching);
}, step -> step::format);
}, step -> FormatterFunc.needsFile(step::format));
}

if (contentPattern == null) {
Expand Down Expand Up @@ -213,6 +214,9 @@ private static class Runtime implements Serializable {
private final @Nullable String afterYear;
private final boolean updateYearWithLatest;
private final boolean licenseHeaderWithRange;
private final boolean hasFileToken;

private static final Pattern FILENAME_PATTERN = Pattern.compile("\\$FILE");

/** The license that we'd like enforced. */
private Runtime(String licenseHeader, String delimiter, String yearSeparator, boolean updateYearWithLatest, @Nullable String skipLinesMatching) {
Expand All @@ -226,6 +230,7 @@ private Runtime(String licenseHeader, String delimiter, String yearSeparator, bo
}
this.delimiterPattern = Pattern.compile('^' + delimiter, Pattern.UNIX_LINES | Pattern.MULTILINE);
this.skipLinesMatching = skipLinesMatching == null ? null : Pattern.compile(skipLinesMatching);
this.hasFileToken = FILENAME_PATTERN.matcher(licenseHeader).find();

Optional<String> yearToken = getYearToken(licenseHeader);
if (yearToken.isPresent()) {
Expand Down Expand Up @@ -266,9 +271,9 @@ private static Optional<String> getYearToken(String licenseHeader) {
}

/** Formats the given string. */
private String format(String raw) {
private String format(String raw, File file) {
if (skipLinesMatching == null) {
return addOrUpdateLicenseHeader(raw);
return addOrUpdateLicenseHeader(raw, file);
} else {
String[] lines = raw.split("\n");
StringBuilder skippedLinesBuilder = new StringBuilder();
Expand All @@ -287,11 +292,17 @@ private String format(String raw) {
remainingLinesBuilder.append(line).append('\n');
}
}
return skippedLinesBuilder + addOrUpdateLicenseHeader(remainingLinesBuilder.toString());
return skippedLinesBuilder + addOrUpdateLicenseHeader(remainingLinesBuilder.toString(), file);
}
}

private String addOrUpdateLicenseHeader(String raw) {
private String addOrUpdateLicenseHeader(String raw, File file) {
raw = replaceYear(raw);
raw = replaceFileName(raw, file);
return raw;
}

private String replaceYear(String raw) {
Matcher contentMatcher = delimiterPattern.matcher(raw);
if (!contentMatcher.find()) {
throw new IllegalArgumentException("Unable to find delimiter regex " + delimiterPattern);
Expand Down Expand Up @@ -421,6 +432,19 @@ private String setLicenseHeaderYearsFromGitHistory(String raw, File file) throws
return beforeYear + yearRange + afterYear + raw.substring(contentMatcher.start());
}

private String replaceFileName(String raw, File file) {
if (!hasFileToken) {
return raw;
}
Matcher contentMatcher = delimiterPattern.matcher(raw);
if (!contentMatcher.find()) {
throw new IllegalArgumentException("Unable to find delimiter regex " + delimiterPattern);
}
String header = raw.substring(0, contentMatcher.start());
String content = raw.substring(contentMatcher.start());
return FILENAME_PATTERN.matcher(header).replaceAll(file.getName()) + content;
}

private static String parseYear(String cmd, File file) throws IOException {
String fullCmd = cmd + " -- " + file.getAbsolutePath();
ProcessBuilder builder = new ProcessBuilder().directory(file.getParentFile());
Expand Down
3 changes: 3 additions & 0 deletions plugin-gradle/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `3.27.0`).

## [Unreleased]
### Added
* You can now put the filename into a license header template with `$FILE`. ([#1605](https://github.com/diffplug/spotless/pull/1605) fixes [#1147](https://github.com/diffplug/spotless/issues/1147))
* `licenseHeader` default pattern for Java files is updated to `(package|import|public|class|module) `. ([#1614](https://github.com/diffplug/spotless/pull/1614))

## [6.16.0] - 2023-02-27
### Added
Expand Down
4 changes: 2 additions & 2 deletions plugin-gradle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,8 @@ spotless {
```gradle
spotless {
scala {
// version and configFile, majorScalaVersion are all optional
scalafmt('3.5.9').configFile('scalafmt.conf').majorScalaVersion('2.13')
// version and configFile, scalaMajorVersion are all optional
scalafmt('3.5.9').configFile('scalafmt.conf').scalaMajorVersion('2.13')
```
<a name="applying-to-cc-sources"></a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ public JavaExtension(SpotlessExtension spotless) {
super(spotless);
}

// If this constant changes, don't forget to change the similarly-named one in
// testlib/src/test/java/com/diffplug/spotless/generic/LicenseHeaderStepTest.java as well
static final String LICENSE_HEADER_DELIMITER = "package ";
static final String LICENSE_HEADER_DELIMITER = LicenseHeaderStep.DEFAULT_JAVA_HEADER_DELIMITER;

@Override
public LicenseHeaderConfig licenseHeader(String licenseHeader) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 DiffPlug
* Copyright 2016-2023 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -35,6 +35,7 @@
import org.gradle.work.FileChange;
import org.gradle.work.InputChanges;

import com.diffplug.common.annotations.VisibleForTesting;
import com.diffplug.common.base.StringPrinter;
import com.diffplug.spotless.Formatter;
import com.diffplug.spotless.PaddedCell;
Expand Down Expand Up @@ -92,28 +93,37 @@ public void performAction(InputChanges inputs) throws Exception {
}
}

private void processInputFile(@Nullable GitRatchet ratchet, Formatter formatter, File input) throws IOException {
@VisibleForTesting
void processInputFile(@Nullable GitRatchet ratchet, Formatter formatter, File input) throws IOException {
File output = getOutputFile(input);
getLogger().debug("Applying format to " + input + " and writing to " + output);
getLogger().debug("Applying format to {} and writing to {}", input, output);
PaddedCell.DirtyState dirtyState;
if (ratchet != null && ratchet.isClean(getProjectDir().get().getAsFile(), getRootTreeSha(), input)) {
dirtyState = PaddedCell.isClean();
} else {
dirtyState = PaddedCell.calculateDirtyState(formatter, input);
try {
dirtyState = PaddedCell.calculateDirtyState(formatter, input);
} catch (IOException e) {
throw new IOException("Issue processing file: " + input, e);
} catch (RuntimeException e) {
throw new IllegalArgumentException("Issue processing file: " + input, e);
}
}
if (dirtyState.isClean()) {
// Remove previous output if it exists
Files.deleteIfExists(output.toPath());
} else if (dirtyState.didNotConverge()) {
getLogger().warn("Skipping '" + input + "' because it does not converge. Run {@code spotlessDiagnose} to understand why");
getLogger().warn("Skipping '{}' because it does not converge. Run {@code spotlessDiagnose} to understand why", input);
} else {
Path parentDir = output.toPath().getParent();
if (parentDir == null) {
throw new IllegalStateException("Every file has a parent folder.");
throw new IllegalStateException("Every file has a parent folder. But not: " + output);
}
Files.createDirectories(parentDir);
// Need to copy the original file to the tmp location just to remember the file attributes
Files.copy(input.toPath(), output.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);

getLogger().info(String.format("Writing clean file: %s", output));
dirtyState.writeCanonicalTo(output);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ void integration() throws IOException {
" }",
"}");

setFile("test.java").toResource("java/cleanthat/MultipleMutators.dirty.java");
setFile("test.java").toResource("java/cleanthat/MultipleMutators.dirty.test");
gradleRunner().withArguments("spotlessApply").build();
assertFile("test.java").sameAsResource("java/cleanthat/MultipleMutators.clean.java");
assertFile("test.java").sameAsResource("java/cleanthat/MultipleMutators.clean.test");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 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.File;
import java.nio.file.Paths;

import org.assertj.core.api.Assertions;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.logging.Logger;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import com.diffplug.spotless.Formatter;

public class SpotlessTaskImplTest {
@Test
public void testThrowsMessageContainsFilename() throws Exception {
SpotlessTaskImpl task = Mockito.mock(SpotlessTaskImpl.class, Mockito.CALLS_REAL_METHODS);
Mockito.when(task.getLogger()).thenReturn(Mockito.mock(Logger.class));

File projectDir = Paths.get("unitTests", "projectDir").toFile();
DirectoryProperty projectDirProperty = Mockito.mock(DirectoryProperty.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(projectDirProperty.get().getAsFile()).thenReturn(projectDir);

Mockito.when(task.getProjectDir()).thenReturn(projectDirProperty);

File input = Paths.get("unitTests", "projectDir", "someInput").toFile();
Formatter formatter = Mockito.mock(Formatter.class);

Assertions.assertThatThrownBy(() -> task.processInputFile(null, formatter, input)).hasMessageContaining(input.toString());
}
}
6 changes: 6 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
We adhere to the [keepachangelog](https://keepachangelog.com/en/1.0.0/) format (starting after version `1.27.0`).

## [Unreleased]
### Added
* You can now put the filename into a license header template with `$FILE`. ([#1605](https://github.com/diffplug/spotless/pull/1605) fixes [#1147](https://github.com/diffplug/spotless/issues/1147))
### Fixed
* `licenseHeader` default pattern for Java files is updated to `(package|import|public|class|module) `. ([#1614](https://github.com/diffplug/spotless/pull/1614))
### Changes
* Enable incremental up-to-date checking by default. ([#1621](https://github.com/diffplug/spotless/pull/1621))

## [2.34.0] - 2023-02-27
### Added
Expand Down
2 changes: 1 addition & 1 deletion plugin-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1262,7 +1262,7 @@ To define what lines to skip at the beginning of such files, fill the `skipLines

## Incremental up-to-date checking and formatting

**This feature is turned off by default.**
**This feature is enabled by default starting from version 2.35.0.**

Execution of `spotless:check` and `spotless:apply` for large projects can take time.
By default, Spotless Maven plugin needs to read and format each source file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public abstract class AbstractSpotlessMojo extends AbstractMojo {
private String setLicenseHeaderYearsFromGitHistory;

@Parameter
private UpToDateChecking upToDateChecking;
private UpToDateChecking upToDateChecking = UpToDateChecking.enabled();

protected abstract void process(Iterable<File> files, Formatter formatter, UpToDateChecker upToDateChecker) throws MojoExecutionException;

Expand Down Expand Up @@ -373,9 +373,9 @@ private UpToDateChecker createUpToDateChecker(Iterable<Formatter> formatters) {
}
final UpToDateChecker checker;
if (upToDateChecking != null && upToDateChecking.isEnabled()) {
getLog().info("Up-to-date checking enabled");
checker = UpToDateChecker.forProject(project, indexFile, formatters, getLog());
} else {
getLog().info("Up-to-date checking disabled");
checker = UpToDateChecker.noop(project, indexFile, getLog());
}
return UpToDateChecker.wrapWithBuildContext(checker, buildContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected void process(Iterable<File> files, Formatter formatter, UpToDateChecke
} else {
counter.checkedButAlreadyClean();
}
} catch (IOException e) {
} catch (IOException | RuntimeException e) {
throw new MojoExecutionException("Unable to format file " + file, e);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2021 DiffPlug
* Copyright 2016-2023 DiffPlug
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,9 +38,12 @@ public class SpotlessCheckMojo extends AbstractSpotlessMojo {

@Override
protected void process(Iterable<File> files, Formatter formatter, UpToDateChecker upToDateChecker) throws MojoExecutionException {
ImpactedFilesTracker counter = new ImpactedFilesTracker();

List<File> problemFiles = new ArrayList<>();
for (File file : files) {
if (upToDateChecker.isUpToDate(file.toPath())) {
counter.skippedAsCleanCache();
if (getLog().isDebugEnabled()) {
getLog().debug("Spotless will not check an up-to-date file: " + file);
}
Expand All @@ -51,14 +54,24 @@ protected void process(Iterable<File> files, Formatter formatter, UpToDateChecke
PaddedCell.DirtyState dirtyState = PaddedCell.calculateDirtyState(formatter, file);
if (!dirtyState.isClean() && !dirtyState.didNotConverge()) {
problemFiles.add(file);
counter.cleaned();
} else {
counter.checkedButAlreadyClean();
upToDateChecker.setUpToDate(file.toPath());
}
} catch (IOException e) {
} catch (IOException | RuntimeException e) {
throw new MojoExecutionException("Unable to format file " + file, e);
}
}

// We print the number of considered files which is useful when ratchetFrom is setup
if (counter.getTotal() > 0) {
getLog().info(String.format("Spotless.%s is keeping %s files clean - %s needs changes to be clean, %s were already clean, %s were skipped because caching determined they were already clean",
formatter.getName(), counter.getTotal(), counter.getCleaned(), counter.getCheckedButAlreadyClean(), counter.getSkippedAsCleanCache()));
} else {
getLog().debug(String.format("Spotless.%s has no target files. Examine your `<includes>`: https://github.com/diffplug/spotless/tree/main/plugin-maven#quickstart", formatter.getName()));
}

if (!problemFiles.isEmpty()) {
throw new MojoExecutionException(DiffMessageFormatter.builder()
.runToFix("Run 'mvn spotless:apply' to fix these violations.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.maven.project.MavenProject;

import com.diffplug.common.collect.ImmutableSet;
import com.diffplug.spotless.generic.LicenseHeaderStep;
import com.diffplug.spotless.maven.FormatterFactory;
import com.diffplug.spotless.maven.generic.LicenseHeader;

Expand All @@ -32,7 +33,7 @@
public class Groovy extends FormatterFactory {

private static final Set<String> DEFAULT_INCLUDES = ImmutableSet.of("src/main/groovy/**/*.groovy", "src/test/groovy/**/*.groovy");
private static final String LICENSE_HEADER_DELIMITER = "package ";
private static final String LICENSE_HEADER_DELIMITER = LicenseHeaderStep.DEFAULT_JAVA_HEADER_DELIMITER;

@Override
public Set<String> defaultIncludes(MavenProject project) {
Expand Down

0 comments on commit cdcfe14

Please sign in to comment.