Skip to content

Commit

Permalink
Merge pull request #1055 from tisoft/custom_index_file
Browse files Browse the repository at this point in the history
Support custom index files for incremental up-to-date checking
  • Loading branch information
lutovich committed Jan 6, 2022
2 parents b3a6e36 + 0a94634 commit e98684a
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 38 deletions.
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Original file line number Diff line number Diff line change
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
* Support custom index files for incremental up-to-date checking ([#1055](https://github.com/diffplug/spotless/pull/1055)).
### Fixed
* Remove Java files from default Maven Groovy formatting ([#1051](https://github.com/diffplug/spotless/pull/1051)).
* Before this release, the default target of groovy was
Expand Down
4 changes: 3 additions & 1 deletion plugin-maven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ enable incremental up-to-date checking with the following configuration:
<configuration>
<upToDateChecking>
<enabled>true</enabled>
<indexFile>${project.basedir}/custom-index-file</indexFile> <!-- optional, default is ${project.build.directory}/spotless-index -->
</upToDateChecking>
<!-- ... define formats ... -->
</configuration>
Expand All @@ -946,7 +947,7 @@ The index file contains source file paths and corresponding last modified timest
It allows Spotless to skip already formatted files that have not changed.

**Note:** the index file is located in the `target` directory. Executing `mvn clean` will delete
the index file, and Spotless will need to check/format all the source files.
the index file, and Spotless will need to check/format all the source files. You can override the default index file location with the `indexFile` configuration parameter.

Spotless will remove the index file when up-to-date checking is explicitly turned off with the
following configuration:
Expand All @@ -955,6 +956,7 @@ following configuration:
<configuration>
<upToDateChecking>
<enabled>false</enabled>
<indexFile>${project.basedir}/custom-index-file</indexFile> <!-- optional, default is ${project.build.directory}/spotless-index -->
</upToDateChecking>
<!-- ... define formats ... -->
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2021 DiffPlug
* Copyright 2016-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 @@ -19,6 +19,7 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -71,7 +72,7 @@
import com.diffplug.spotless.maven.typescript.Typescript;

public abstract class AbstractSpotlessMojo extends AbstractMojo {

private static final String DEFAULT_INDEX_FILE_NAME = "spotless-index";
private static final String DEFAULT_ENCODING = "UTF-8";
private static final String DEFAULT_LINE_ENDINGS = "GIT_ATTRIBUTES";
static final String GOAL_CHECK = "check";
Expand Down Expand Up @@ -324,10 +325,15 @@ private List<FormatterStepFactory> getFormatterStepFactories() {
}

private UpToDateChecker createUpToDateChecker(Iterable<Formatter> formatters) {
Path indexFile = upToDateChecking == null ? null : upToDateChecking.getIndexFile();
if (indexFile == null) {
Path targetDir = project.getBasedir().toPath().resolve(project.getBuild().getDirectory());
indexFile = targetDir.resolve(DEFAULT_INDEX_FILE_NAME);
}
if (upToDateChecking != null && upToDateChecking.isEnabled()) {
getLog().info("Up-to-date checking enabled");
return UpToDateChecker.forProject(project, formatters, getLog());
return UpToDateChecker.forProject(project, indexFile, formatters, getLog());
}
return UpToDateChecker.noop(project, getLog());
return UpToDateChecker.noop(project, indexFile, getLog());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 DiffPlug
* Copyright 2021-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 @@ -20,18 +20,17 @@
import org.apache.maven.project.MavenProject;

class FileIndexConfig {

private static final String INDEX_FILE_NAME = "spotless-index";

private final MavenProject project;
private final PluginFingerprint pluginFingerprint;
private final Path indexFile;

FileIndexConfig(MavenProject project) {
this(project, PluginFingerprint.empty());
FileIndexConfig(MavenProject project, Path indexFile) {
this(project, indexFile, PluginFingerprint.empty());
}

FileIndexConfig(MavenProject project, PluginFingerprint pluginFingerprint) {
FileIndexConfig(MavenProject project, Path indexFile, PluginFingerprint pluginFingerprint) {
this.project = project;
this.indexFile = indexFile;
this.pluginFingerprint = pluginFingerprint;
}

Expand All @@ -40,8 +39,7 @@ Path getProjectDir() {
}

Path getIndexFile() {
Path targetDir = getProjectDir().resolve(project.getBuild().getDirectory());
return targetDir.resolve(INDEX_FILE_NAME);
return indexFile;
}

PluginFingerprint getPluginFingerprint() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 DiffPlug
* Copyright 2021-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 Down Expand Up @@ -39,9 +39,9 @@ class IndexBasedChecker implements UpToDateChecker {
this.log = log;
}

static IndexBasedChecker create(MavenProject project, Iterable<Formatter> formatters, Log log) {
static IndexBasedChecker create(MavenProject project, Path indexFile, Iterable<Formatter> formatters, Log log) {
PluginFingerprint pluginFingerprint = PluginFingerprint.from(project, formatters);
FileIndexConfig indexConfig = new FileIndexConfig(project, pluginFingerprint);
FileIndexConfig indexConfig = new FileIndexConfig(project, indexFile, pluginFingerprint);
FileIndex fileIndex = FileIndex.read(indexConfig, log);
return new IndexBasedChecker(fileIndex, log);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 DiffPlug
* Copyright 2021-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 @@ -24,8 +24,8 @@ class NoopChecker implements UpToDateChecker {

private NoopChecker() {}

static NoopChecker create(MavenProject project, Log log) {
FileIndexConfig indexConfig = new FileIndexConfig(project);
static NoopChecker create(MavenProject project, Path indexFile, Log log) {
FileIndexConfig indexConfig = new FileIndexConfig(project, indexFile);
FileIndex.delete(indexConfig, log);
return new NoopChecker();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 DiffPlug
* Copyright 2021-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 Down Expand Up @@ -30,11 +30,11 @@ public interface UpToDateChecker extends AutoCloseable {

void close();

static UpToDateChecker noop(MavenProject project, Log log) {
return NoopChecker.create(project, log);
static UpToDateChecker noop(MavenProject project, Path indexFile, Log log) {
return NoopChecker.create(project, indexFile, log);
}

static UpToDateChecker forProject(MavenProject project, Iterable<Formatter> formatters, Log log) {
return IndexBasedChecker.create(project, formatters, log);
static UpToDateChecker forProject(MavenProject project, Path indexFile, Iterable<Formatter> formatters, Log log) {
return IndexBasedChecker.create(project, indexFile, formatters, log);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 DiffPlug
* Copyright 2021-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 @@ -15,14 +15,27 @@
*/
package com.diffplug.spotless.maven.incremental;

import java.io.File;
import java.nio.file.Path;

import javax.annotation.Nullable;

import org.apache.maven.plugins.annotations.Parameter;

public class UpToDateChecking {

@Parameter
private boolean enabled;

@Parameter
private String indexFile;

public boolean isEnabled() {
return enabled;
}

@Nullable
public Path getIndexFile() {
return indexFile == null ? null : new File(indexFile).toPath();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 DiffPlug
* Copyright 2021-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 @@ -18,6 +18,7 @@
import static org.assertj.core.api.Assertions.assertThat;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.apache.maven.model.Build;
Expand All @@ -28,29 +29,33 @@ class FileIndexConfigTest {

@Test
void returnsCorrectProjectDir() {
FileIndexConfig config = new FileIndexConfig(mavenProject(), PluginFingerprint.from("foo"));
MavenProject project = mavenProject();
FileIndexConfig config = new FileIndexConfig(project, getIndexFile(project), PluginFingerprint.from("foo"));

assertThat(config.getProjectDir()).isEqualTo(Paths.get("projectDir"));
}

@Test
void returnsCorrectIndexFile() {
FileIndexConfig config = new FileIndexConfig(mavenProject(), PluginFingerprint.from("foo"));
MavenProject project = mavenProject();
FileIndexConfig config = new FileIndexConfig(project, getIndexFile(project), PluginFingerprint.from("foo"));

assertThat(config.getIndexFile())
.isEqualTo(Paths.get("projectDir", "target", "spotless-index"));
}

@Test
void returnsCorrectPluginFingerprint() {
FileIndexConfig config = new FileIndexConfig(mavenProject(), PluginFingerprint.from("foo"));
MavenProject project = mavenProject();
FileIndexConfig config = new FileIndexConfig(project, getIndexFile(project), PluginFingerprint.from("foo"));

assertThat(config.getPluginFingerprint()).isEqualTo(PluginFingerprint.from("foo"));
}

@Test
void returnsEmptyPluginFingerprint() {
FileIndexConfig config = new FileIndexConfig(mavenProject());
MavenProject project = mavenProject();
FileIndexConfig config = new FileIndexConfig(project, getIndexFile(project));

assertThat(config.getPluginFingerprint()).isEqualTo(PluginFingerprint.from(""));
}
Expand All @@ -63,4 +68,8 @@ private static MavenProject mavenProject() {
project.setBuild(build);
return project;
}

private static Path getIndexFile(MavenProject project) {
return project.getBasedir().toPath().resolve(project.getBuild().getDirectory()).resolve("spotless-index");
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 DiffPlug
* Copyright 2021-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 Down Expand Up @@ -52,7 +52,7 @@ class NoopCheckerTest extends ResourceHarness {
@BeforeEach
void beforeEach() throws Exception {
project = buildMavenProject();
indexFile = new FileIndexConfig(project).getIndexFile();
indexFile = project.getBasedir().toPath().resolve(project.getBuild().getDirectory()).resolve("spotless-index");
existingSourceFile = project.getBasedir().toPath().resolve("existing.txt");
Files.write(existingSourceFile, "foo".getBytes(UTF_8), CREATE_NEW);
nonExistingSourceFile = project.getBasedir().toPath().resolve("non-existing.txt");
Expand All @@ -61,12 +61,12 @@ void beforeEach() throws Exception {
@Test
void deletesExistingIndexFileWhenCreated() {
Log log = mock(Log.class);
try (UpToDateChecker realChecker = UpToDateChecker.forProject(project, singletonList(dummyFormatter()), log)) {
try (UpToDateChecker realChecker = UpToDateChecker.forProject(project, indexFile, singletonList(dummyFormatter()), log)) {
realChecker.setUpToDate(existingSourceFile);
}
assertThat(indexFile).exists();

try (UpToDateChecker noopChecker = UpToDateChecker.noop(project, log)) {
try (UpToDateChecker noopChecker = UpToDateChecker.noop(project, indexFile, log)) {
assertThat(noopChecker).isNotNull();
}
assertThat(indexFile).doesNotExist();
Expand All @@ -78,7 +78,7 @@ void doesNothingWhenIndexFileDoesNotExist() {
assertThat(indexFile).doesNotExist();

Log log = mock(Log.class);
try (UpToDateChecker noopChecker = UpToDateChecker.noop(project, log)) {
try (UpToDateChecker noopChecker = UpToDateChecker.noop(project, indexFile, log)) {
assertThat(noopChecker).isNotNull();
}
assertThat(indexFile).doesNotExist();
Expand All @@ -87,7 +87,7 @@ void doesNothingWhenIndexFileDoesNotExist() {

@Test
void neverUpToDate() {
try (UpToDateChecker noopChecker = UpToDateChecker.noop(project, mock(Log.class))) {
try (UpToDateChecker noopChecker = UpToDateChecker.noop(project, indexFile, mock(Log.class))) {
assertThat(noopChecker.isUpToDate(existingSourceFile)).isFalse();
assertThat(noopChecker.isUpToDate(nonExistingSourceFile)).isFalse();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 DiffPlug
* Copyright 2021-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 @@ -19,6 +19,8 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -65,6 +67,42 @@ void disableUpToDateChecking() throws Exception {
assertFormatted(files);
}

@Test
void enableUpToDateCheckingCustomIndexFile() throws Exception {
Path tempDirectory = newFolder("index-files").toPath();
Path indexFile = tempDirectory.resolve("com.diffplug.spotless/spotless-maven-plugin-tests.index");
assertThat(indexFile.getParent()).doesNotExist();
assertThat(indexFile).doesNotExist();
writePomWithUpToDateCheckingEnabledIndexFile(true, tempDirectory + "/${project.groupId}/${project.artifactId}.index");

List<File> files = writeUnformattedFiles(1);
String output = runSpotlessApply();

assertThat(output).contains("Up-to-date checking enabled");
assertFormatted(files);
assertThat(indexFile.getParent()).exists();
assertThat(indexFile).exists();
}

@Test
void disableUpToDateCheckingCustomIndexFile() throws Exception {
Path tempDirectory = newFolder("index-files").toPath();
Path indexFile = tempDirectory.resolve("com.diffplug.spotless/spotless-maven-plugin-tests.index");
Files.createDirectories(indexFile.getParent());
Files.createFile(indexFile);
assertThat(indexFile.getParent()).exists();
assertThat(indexFile).exists();
writePomWithUpToDateCheckingEnabledIndexFile(false, tempDirectory + "/${project.groupId}/${project.artifactId}.index");

List<File> files = writeUnformattedFiles(1);
String output = runSpotlessApply();

assertThat(output).doesNotContain("Up-to-date checking enabled");
assertFormatted(files);
assertThat(indexFile.getParent()).exists();
assertThat(indexFile).doesNotExist();
}

@Test
void spotlessApplyRecordsCorrectlyFormattedFiles() throws Exception {
writePomWithUpToDateCheckingEnabled(true);
Expand Down Expand Up @@ -141,6 +179,17 @@ private void writePomWithUpToDateCheckingEnabled(boolean enabled) throws IOExcep
"</upToDateChecking>");
}

private void writePomWithUpToDateCheckingEnabledIndexFile(boolean enabled, String indexFile) throws IOException {
writePom(
"<java>",
" <googleJavaFormat/>",
"</java>",
"<upToDateChecking>",
" <enabled>" + enabled + "</enabled>",
" <indexFile>" + indexFile + "</indexFile>",
"</upToDateChecking>");
}

private List<File> writeFormattedFiles(int count) throws IOException {
return writeFiles("java/googlejavaformat/JavaCodeFormatted18.test", "formatted", count);
}
Expand Down

0 comments on commit e98684a

Please sign in to comment.