Skip to content

Commit 1899f9c

Browse files
iamdanfoxbulldozer-bot[bot]
authored andcommitted
FormatDiffCli improvements (#41)
<!-- User-facing outcomes this PR delivers -->
1 parent 35f7cb8 commit 1899f9c

File tree

7 files changed

+132
-64
lines changed

7 files changed

+132
-64
lines changed

build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,14 @@ subprojects {
4848
tasks.withType(Checkstyle) {
4949
enabled = false
5050
}
51+
52+
tasks.withType(JavaCompile) {
53+
options.errorprone.errorproneArgs += [
54+
'-Xep:PreconditionsConstantMessage:OFF',
55+
'-Xep:PreferSafeLoggableExceptions:OFF',
56+
'-Xep:PreferAssertj:OFF',
57+
'-Xep:PreferSafeLoggingPreconditions:OFF',
58+
'-Xep:SwitchStatementDefaultCase:OFF'
59+
]
60+
}
5161
}

palantir-java-format/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dependencies {
1313
testCompile 'com.google.guava:guava-testlib'
1414
testCompile 'com.google.truth:truth'
1515
testCompile 'com.google.testing.compile:compile-testing'
16+
testImplementation 'org.assertj:assertj-core'
1617
testImplementation 'org.junit.jupiter:junit-jupiter-migrationsupport'
1718
testImplementation 'org.junit.jupiter:junit-jupiter'
1819

palantir-java-format/src/main/java/com/palantir/javaformat/java/FormatDiffCli.java renamed to palantir-java-format/src/main/java/com/palantir/javaformat/java/FormatDiff.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import java.util.regex.Pattern;
3838
import java.util.stream.Stream;
3939

40-
public final class FormatDiffCli {
40+
public final class FormatDiff {
4141
// each section in the git diff output starts like this
4242
private static final Pattern SEPARATOR = Pattern.compile("diff --git");
4343

@@ -48,15 +48,16 @@ public final class FormatDiffCli {
4848
private static final Pattern HUNK =
4949
Pattern.compile("^@@.*\\+(?<startLineOneIndexed>\\d+)(,(?<numLines>\\d+))?", Pattern.MULTILINE);
5050

51-
public static void main(String[] _args) throws IOException, InterruptedException {
51+
public static void formatDiff(Path dirToFormat) throws IOException, InterruptedException {
5252
Formatter formatter = Formatter.createFormatter(
5353
JavaFormatterOptions.builder().style(JavaFormatterOptions.Style.PALANTIR).build());
54-
Path cwd = Paths.get(".");
5554

56-
String gitOutput = gitDiff(cwd);
55+
String gitOutput = gitDiff(dirToFormat);
56+
Path gitTopLevelDir = gitTopLevelDir(dirToFormat);
57+
5758
parseGitDiffOutput(gitOutput)
5859
.filter(diff -> diff.path.toString().endsWith(".java"))
59-
.map(diff -> new SingleFileDiff(cwd.resolve(diff.path), diff.lineRanges))
60+
.map(diff -> new SingleFileDiff(gitTopLevelDir.resolve(diff.path), diff.lineRanges))
6061
.filter(diff -> Files.exists(diff.path))
6162
.forEach(diff -> format(formatter, diff));
6263
}
@@ -107,14 +108,24 @@ private static void format(Formatter formatter, SingleFileDiff diff) {
107108
}
108109
}
109110

110-
private static String gitDiff(Path cwd) throws IOException, InterruptedException {
111+
private static String gitDiff(Path dir) throws IOException, InterruptedException {
111112
// TODO(dfox): this does nothing if working dir is clean - maybe use HEAD^ to format prev commit?
112-
Process process = new ProcessBuilder().command("git", "diff", "-U0", "HEAD").directory(cwd.toFile()).start();
113+
return gitCommand(dir, "git", "diff", "-U0", "HEAD", dir.toAbsolutePath().toString());
114+
}
115+
116+
private static Path gitTopLevelDir(Path dir) throws IOException, InterruptedException {
117+
return Paths.get(gitCommand(dir, "git", "rev-parse", "--show-toplevel"));
118+
}
119+
120+
private static String gitCommand(Path dir, String... args) throws IOException, InterruptedException {
121+
Process process = new ProcessBuilder().command(args).directory(dir.toFile()).start();
122+
113123
Preconditions.checkState(process.waitFor(10, TimeUnit.SECONDS), "git diff took too long to terminate");
124+
Preconditions.checkState(process.exitValue() == 0, "Expected return code of 0");
114125

115126
ByteArrayOutputStream baos = new ByteArrayOutputStream();
116127
ByteStreams.copy(process.getInputStream(), baos);
117-
return new String(baos.toByteArray(), UTF_8);
128+
return new String(baos.toByteArray(), UTF_8).trim();
118129
}
119130

120131
// TODO(dfox): replace this with immutables

palantir-java-format/src/test/java/com/palantir/javaformat/java/FormatDiffCliTest.java

Lines changed: 0 additions & 49 deletions
This file was deleted.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* (c) Copyright 2019 Palantir Technologies Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.palantir.javaformat.java;
18+
19+
import static java.nio.charset.StandardCharsets.UTF_8;
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
23+
import com.google.common.base.Preconditions;
24+
import com.google.common.collect.ImmutableList;
25+
import com.google.common.io.ByteStreams;
26+
import java.io.ByteArrayOutputStream;
27+
import java.io.IOException;
28+
import java.nio.charset.StandardCharsets;
29+
import java.nio.file.Files;
30+
import java.nio.file.Path;
31+
import java.nio.file.Paths;
32+
import java.util.List;
33+
import java.util.concurrent.TimeUnit;
34+
import java.util.stream.Collectors;
35+
import org.junit.jupiter.api.Test;
36+
import org.junit.jupiter.api.io.TempDir;
37+
38+
class FormatDiffTest {
39+
@TempDir Path repo;
40+
41+
@Test
42+
void parsing_git_diff_output_works() throws IOException {
43+
String example1 = new String(
44+
Files.readAllBytes(
45+
Paths.get("src/test/resources/com/palantir/javaformat/java/FormatDiffCliTest/example1.patch")),
46+
StandardCharsets.UTF_8);
47+
48+
List<String> strings = FormatDiff.parseGitDiffOutput(example1).map(FormatDiff.SingleFileDiff::toString).collect(
49+
Collectors.toList());
50+
assertEquals(
51+
ImmutableList.of(
52+
"SingleFileDiff{path=build.gradle, lineRanges=[[24..25), [29..30)]}",
53+
"SingleFileDiff{path=tracing/src/test/java/com/palantir/tracing/TracersTest.java, "
54+
+ "lineRanges=[[659..660), [675..676)]}"),
55+
strings);
56+
}
57+
58+
@Test
59+
void reformat_a_subpath_of_a_git_directory_for_only_changed_lines() throws IOException, InterruptedException {
60+
runCommandInRepo("git", "init");
61+
runCommandInRepo("git", "config", "user.name", "Test User");
62+
runCommandInRepo("git", "config", "user.email", "[email protected]");
63+
runCommandInRepo("git", "commit", "--allow-empty", "-m", "Init");
64+
65+
Path subdir = repo.resolve("subdir");
66+
Files.createDirectories(subdir);
67+
68+
Path reformatMe = subdir.resolve("ReformatMe.java");
69+
Files.write(reformatMe, ImmutableList.of(" class ReformatMe {}"), UTF_8);
70+
71+
Path dontTouchMe = repo.resolve("DontTouchMe.java");
72+
Files.write(dontTouchMe, ImmutableList.of(" class DontTouchMe {}"), UTF_8);
73+
74+
runCommandInRepo("git", "add", "-N", ".");
75+
76+
FormatDiff.formatDiff(subdir);
77+
78+
assertThat(reformatMe).hasContent("class ReformatMe {}");
79+
assertThat(dontTouchMe).hasContent(" class DontTouchMe {}");
80+
}
81+
82+
private void runCommandInRepo(String... args) throws IOException, InterruptedException {
83+
Process process = new ProcessBuilder().command(args).directory(repo.toFile()).start();
84+
85+
Preconditions.checkState(process.waitFor(10, TimeUnit.SECONDS), "git diff took too long to terminate");
86+
87+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
88+
ByteStreams.copy(process.getErrorStream(), baos);
89+
String stderr = new String(baos.toByteArray(), UTF_8);
90+
91+
Preconditions.checkState(process.exitValue() == 0, "Expected return code of 0: " + stderr);
92+
}
93+
}

versions.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ com.netflix.nebula:nebula-test:7.4.0 (1 constraints: 0d051a36)
2929
commons-io:commons-io:2.5 (1 constraints: eb0c8d0a)
3030
junit:junit:4.12 (6 constraints: f14f0a8f)
3131
org.apiguardian:apiguardian-api:1.1.0 (6 constraints: 18697c5a)
32+
org.assertj:assertj-core:3.13.2 (1 constraints: 3b05403b)
3233
org.checkerframework:checker-compat-qual:2.5.5 (1 constraints: 640a29b9)
3334
org.hamcrest:hamcrest-core:1.3 (1 constraints: cc05fe3f)
3435
org.junit.jupiter:junit-jupiter:5.5.2 (1 constraints: 0e051536)

versions.props

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext = 0.5
21
com.github.ben-manes.caffeine:caffeine = 2.8.0
3-
com.google.guava:guava = 27.0.1-jre
4-
com.google.errorprone:javac-shaded = 9+181-r4173-1
2+
com.google.auto.service:auto-service = 1.0-rc6
53
com.google.code.findbugs:jsr305 = 3.0.2
64
com.google.errorprone:error_prone_annotations = 2.3.3
7-
junit:junit = 4.12
5+
com.google.errorprone:javac-shaded = 9+181-r4173-1
6+
com.google.guava:guava = 27.0.1-jre
87
com.google.guava:guava-testlib = 27.0.1-jre
9-
com.google.truth:truth = 1.0
108
com.google.testing.compile:compile-testing = 0.15
9+
com.google.truth:truth = 1.0
10+
com.netflix.nebula:nebula-test = 7.4.0
11+
gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext = 0.5
12+
junit:junit = 4.12
13+
org.assertj:assertj-core = 3.13.2
1114
org.derive4j:* = 1.1.1
1215
org.immutables:value = 2.8.1
1316
org.junit.jupiter:* = 5.5.2
1417
org.junit.vintage:* = 5.5.0
15-
com.google.auto.service:auto-service = 1.0-rc6
16-
com.netflix.nebula:nebula-test = 7.4.0

0 commit comments

Comments
 (0)