Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

obsolete - Internal-only breaking changes #1096

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ 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`).

## [TBD lint release]
* **BREAKING** Removed all deprecated methods.
* **BREAKING** Removed `isClean`, `applyTo`, and `applyToAndReturnResultIfDirty` from `Formatter` because users should instead use new class `DirtyState.of`
* **BREAKING** Removed `FormatterStep.Strict` because it was an unnecessary and unused implementation detail
* **BREAKING** Removed `rootDir` and `exceptionPolicy` parameters from `Formatter`
* **BREAKING** Renamed `PipeStepPair` to `FenceStep` and changed its approach to be lint-friendly
* **BREAKING** Modified `StepHarness` and `StepHarnessWithFile` to stop asserting on exceptions (to prepare for Lint)

## [Unreleased]
### Changes
* Bump the dev version of Gradle from `7.5.1` to `7.6` ([#1409](https://github.com/diffplug/spotless/pull/1409))
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 @@ -56,15 +56,17 @@ interface CleanProvider {
}

private static class CleanProviderFormatter implements CleanProvider {
private final Path rootDir;
private final Formatter formatter;

CleanProviderFormatter(Formatter formatter) {
CleanProviderFormatter(Path rootDir, Formatter formatter) {
this.rootDir = Objects.requireNonNull(rootDir);
this.formatter = Objects.requireNonNull(formatter);
}

@Override
public Path getRootDir() {
return formatter.getRootDir();
return rootDir;
}

@Override
Expand Down Expand Up @@ -121,8 +123,8 @@ public Builder runToFix(String runToFix) {
return this;
}

public Builder formatter(Formatter formatter) {
this.formatter = new CleanProviderFormatter(formatter);
public Builder formatter(Path rootDir, Formatter formatter) {
this.formatter = new CleanProviderFormatter(rootDir, formatter);
return this;
}

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 All @@ -26,24 +26,19 @@
import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.jupiter.api.Test;

import com.diffplug.common.base.Errors;
import com.diffplug.common.base.StringPrinter;
import com.diffplug.spotless.LineEnding;
import com.diffplug.spotless.ResourceHarness;

class GitAttributesTest extends ResourceHarness {
private List<File> testFiles(String prefix) {
try {
List<File> result = new ArrayList<>();
for (String path : TEST_PATHS) {
String prefixedPath = prefix + path;
setFile(prefixedPath).toContent("");
result.add(newFile(prefixedPath));
}
return result;
} catch (IOException e) {
throw Errors.asRuntime(e);
List<File> result = new ArrayList<>();
for (String path : TEST_PATHS) {
String prefixedPath = prefix + path;
setFile(prefixedPath).toContent("");
result.add(newFile(prefixedPath));
}
return result;
}

private List<File> testFiles() {
Expand Down
141 changes: 141 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/DirtyState.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* 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;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.Arrays;

import javax.annotation.Nullable;

/**
* The clean/dirty state of a single file. Intended use:
* - {@link #isClean()} means that the file is is clean, and there's nothing else to say
* - {@link #didNotConverge()} means that we were unable to determine a clean state
* - once you've tested the above conditions and you know that it's a dirty file with a converged state,
* then you can call {@link #writeCanonicalTo(OutputStream)} to get the canonical form of the given file.
*/
public class DirtyState {
@Nullable
private final byte[] canonicalBytes;

DirtyState(@Nullable byte[] canonicalBytes) {
this.canonicalBytes = canonicalBytes;
}

public boolean isClean() {
return this == isClean;
}

public boolean didNotConverge() {
return this == didNotConverge;
}

private byte[] canonicalBytes() {
if (canonicalBytes == null) {
throw new IllegalStateException("First make sure that {@code !isClean()} and {@code !didNotConverge()}");
}
return canonicalBytes;
}

public void writeCanonicalTo(File file) throws IOException {
Files.write(file.toPath(), canonicalBytes());
}

public void writeCanonicalTo(OutputStream out) throws IOException {
out.write(canonicalBytes());
}

/** Returns the DirtyState which corresponds to {@code isClean()}. */
public static DirtyState clean() {
return isClean;
}

static final DirtyState didNotConverge = new DirtyState(null);
static final DirtyState isClean = new DirtyState(null);

public static Calculation of(Formatter formatter, File file) throws IOException {
return of(formatter, file, Files.readAllBytes(file.toPath()));
}

public static Calculation of(Formatter formatter, File file, byte[] rawBytes) {
return new Calculation(formatter, file, rawBytes);
}

public static class Calculation {
private final Formatter formatter;
private final File file;
private final byte[] rawBytes;
private final String raw;

private Calculation(Formatter formatter, File file, byte[] rawBytes) {
this.formatter = formatter;
this.file = file;
this.rawBytes = rawBytes;
this.raw = new String(rawBytes, formatter.getEncoding());
// check that all characters were encodable
String encodingError = EncodingErrorMsg.msg(raw, rawBytes, formatter.getEncoding());
if (encodingError != null) {
throw new IllegalArgumentException(encodingError);
}
}

/**
* Calculates whether the given file is dirty according to a PaddedCell invocation of the given formatter.
* DirtyState includes the clean state of the file, as well as a warning if we were not able to apply the formatter
* due to diverging idempotence.
*/
public DirtyState calculateDirtyState() {
String rawUnix = LineEnding.toUnix(raw);

// enforce the format
String formattedUnix = formatter.compute(rawUnix, file);
// convert the line endings if necessary
String formatted = formatter.computeLineEndings(formattedUnix, file);

// if F(input) == input, then the formatter is well-behaving and the input is clean
byte[] formattedBytes = formatted.getBytes(formatter.getEncoding());
if (Arrays.equals(rawBytes, formattedBytes)) {
return isClean;
}

// F(input) != input, so we'll do a padded check
String doubleFormattedUnix = formatter.compute(formattedUnix, file);
if (doubleFormattedUnix.equals(formattedUnix)) {
// most dirty files are idempotent-dirty, so this is a quick-short circuit for that common case
return new DirtyState(formattedBytes);
}

PaddedCell cell = PaddedCell.check(formatter, file, rawUnix);
if (!cell.isResolvable()) {
return didNotConverge;
}

// get the canonical bytes
String canonicalUnix = cell.canonical();
String canonical = formatter.computeLineEndings(canonicalUnix, file);
byte[] canonicalBytes = canonical.getBytes(formatter.getEncoding());
if (!Arrays.equals(rawBytes, canonicalBytes)) {
// and write them to disk if needed
return new DirtyState(canonicalBytes);
} else {
return isClean;
}
}
}
}
Loading