Skip to content

Commit

Permalink
Merge pull request #340 from ParkerM
Browse files Browse the repository at this point in the history
* pr/340:
  Polish 'Detect and preserve line separators'
  Detect and preserve line separators

Closes gh-340
  • Loading branch information
philwebb committed Feb 16, 2023
2 parents b543266 + f50024a commit 097bb33
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ void applyToProjectWithFileMergesToDotSettings() throws Exception {
}).given(projectFile).setContents((InputStream) any(), anyInt(), any());
files.applyToProject(project, monitor);
verify(projectFile).setContents((InputStream) any(), eq(1), eq(monitor));
assertThat(out.toString(StandardCharsets.UTF_8)).isEqualTo("a=b\ny=z\n");
assertThat(out.toString(StandardCharsets.UTF_8))
.isEqualToNormalizingNewlines("a=b\ny=z\n");
}

private ProjectSettingsFile createPrefsFile() throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Stream;

import org.gradle.testkit.runner.BuildResult;
Expand Down Expand Up @@ -68,12 +67,12 @@ void whenFirstInvocationSucceedsThenSecondInvocationIsUpToDate() throws IOExcept

@Test
void whenFirstInvocationSucceedsAndSourceIsModifiedThenSecondInvocationSucceeds() throws IOException {
copyFolder(new File("src/test/resources/check-ok").toPath(), this.temp.toPath());
copyNormalizedFolder(new File("src/test/resources/check-ok").toPath(), this.temp.toPath());
GradleBuild gradleBuild = this.gradleBuild.source(this.temp);
BuildResult result = gradleBuild.build("check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
Files.write(new File(this.temp, "src/main/java/simple/Simple.java").toPath(),
Collections.singletonList("// A change to the file"), StandardOpenOption.APPEND);
"// A change to the file\n".getBytes(StandardCharsets.UTF_8), StandardOpenOption.APPEND);
result = gradleBuild.build("--debug", "check");
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
Expand Down Expand Up @@ -129,14 +128,17 @@ void whenFirstInvocationFailsThenSecondInvocationFails() throws IOException {
assertThat(result.task(":checkFormatMain").getOutcome()).isEqualTo(TaskOutcome.FAILED);
}

private void copyFolder(Path source, Path target) throws IOException {
private void copyNormalizedFolder(Path source, Path target) throws IOException {
try (Stream<Path> stream = Files.walk(source)) {
stream.forEach((child) -> {
try {
Path relative = source.relativize(child);
Path destination = target.resolve(relative);
if (!destination.toFile().isDirectory()) {
Files.copy(child, destination, StandardCopyOption.REPLACE_EXISTING);
if (!Files.isDirectory(child)) {
String content = new String(Files.readAllBytes(child), StandardCharsets.UTF_8);
String normalized = content.replace("\n\r", "\n").replace('\r', '\n');
Files.createDirectories(destination.getParent());
Files.write(destination, normalized.getBytes(StandardCharsets.UTF_8));
}
}
catch (Exception ex) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 the original author or authors.
* Copyright 2017-2023 the original author or authors.
*
* 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,16 +30,14 @@
*/
public class VerifyApply {

private static final String LF = System.lineSeparator();

private static final String JAVA_FILE = "src/main/java/simple/Simple.java";

public void verify(File base) throws IOException {
verify(base, LF);
verify(base, null);
}

public void verify(File base, boolean spaces) throws IOException {
verify(base, LF, spaces);
verify(base, null, spaces);
}

public void verify(File base, String lineSeparator) throws IOException {
Expand All @@ -48,16 +46,14 @@ public void verify(File base, String lineSeparator) throws IOException {

public void verify(File base, String lineSeparator, boolean spaces) throws IOException {
String formated = new String(Files.readAllBytes(base.toPath().resolve(JAVA_FILE)), StandardCharsets.UTF_8);
if (lineSeparator == null) {
formated = formated.replace("\r\n", "\n").replace('\r', '\n');
lineSeparator = "\n";
}
String indent = (!spaces) ? " " : " ";
assertThat(formated).contains("Simple." + lineSeparator + " *" + lineSeparator + " * @author")
.contains("public class Simple {")
.contains(indent + "public static void main");
}

public static void main(String[] args) throws IOException {
new VerifyApply().verify(new File(
"/Users/pwebb/projects/spring-javaformat/code/spring-javaformat-maven/spring-javaformat-maven-plugin/target/it/apply-line-separator"),
"\r");
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 the original author or authors.
* Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,10 +17,11 @@
package io.spring.javaformat.formatter;

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import io.spring.javaformat.config.JavaBaseline;
import io.spring.javaformat.config.JavaFormatConfig;
Expand All @@ -47,7 +48,7 @@ protected final String read(File file) throws Exception {
}

protected static Item[] items(String expectedOverride) {
Collection<Item> items = new ArrayList<>();
List<Item> items = new ArrayList<>();
File sourceDir = new File("src/test/resources/source");
File expectedDir = new File("src/test/resources/expected");
File configDir = new File("src/test/resources/config");
Expand All @@ -59,12 +60,52 @@ protected static Item[] items(String expectedOverride) {
}
File config = new File(configDir, source.getName());
for (JavaBaseline javaBaseline : JavaBaseline.values()) {
items.add(new Item(javaBaseline, source, expected, config));
addItem(items, javaBaseline, source, expected, config);
}
}
return items.toArray(new Item[0]);
}

private static void addItem(List<Item> items, JavaBaseline javaBaseline, File source, File expected, File config) {
if (source.getName().contains("lineendings")) {
items.add(new Item(javaBaseline, copy(source, LineEnding.CR), copy(expected, LineEnding.CR), config));
items.add(new Item(javaBaseline, copy(source, LineEnding.LF), copy(expected, LineEnding.LF), config));
items.add(new Item(javaBaseline, copy(source, LineEnding.CRLF), copy(expected, LineEnding.CRLF), config));
}
else {
items.add(new Item(javaBaseline, source, expected, config));
}
}

private static File copy(File file, LineEnding lineEnding) {
try {
String[] name = file.getName().split("\\.");
File result = File.createTempFile(name[0] + "_" + lineEnding + "_", "." + name[1]);
String content = Files.readString(file.toPath());
content = content.replace("\r\n", "\n").replace('\r', '\n').replace("\n", lineEnding.ending());
Files.writeString(result.toPath(), content);
return result;
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}

enum LineEnding {

CR("\r"), LF("\n"), CRLF("\r\n");

private final String ending;

LineEnding(String ending) {
this.ending = ending;
}

String ending() {
return this.ending;
}
};

static class Item {

private final JavaBaseline javaBaseline;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package correct;

public class CorrectLf {

public static void main(String[] args) throws Exception {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package correct;

public class CorrectLf {

public static void main(String[] args) throws Exception { }

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2021 the original author or authors.
* Copyright 2017-2023 the original author or authors.
*
* 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 @@ -123,6 +123,7 @@ public TextEdit format(String source, int offset, int length, String lineSeparat

public TextEdit format(int kind, String source, int offset, int length, int indentationLevel,
String lineSeparator) {
lineSeparator = (lineSeparator != null) ? lineSeparator : detectLineSeparator(source);
return this.delegate.format(kind, source, offset, length, indentationLevel, lineSeparator);
}

Expand All @@ -148,6 +149,7 @@ public TextEdit format(String source, IRegion[] regions, String lineSeparator) {
}

public TextEdit format(int kind, String source, IRegion[] regions, int indentationLevel, String lineSeparator) {
lineSeparator = (lineSeparator != null) ? lineSeparator : detectLineSeparator(source);
return this.delegate.format(kind, source, regions, indentationLevel, lineSeparator);
}

Expand All @@ -159,4 +161,18 @@ public void setOptions(Map<String, String> options) {
this.delegate.setOptions(options);
}

private String detectLineSeparator(String contents) {
int length = contents.length();
for (int i = 0; i < length; i++) {
char ch = contents.charAt(i);
boolean isLastChar = (i + 1) == length;
if (ch == '\r') {
return (isLastChar || contents.charAt(i + 1) != '\n') ? "\r" : "\r\n";
}
if (ch == '\n') {
return "\n";
}
}
return null;
}
}

0 comments on commit 097bb33

Please sign in to comment.