Skip to content

Commit

Permalink
Ensure final newline in violation store files
Browse files Browse the repository at this point in the history
For a file to be considered a text file, it needs to end with
a newline character. Previously, ArchUnit did not add the final newline,
which broke Git diff and other tools.

Additionally, remove unnecessary list allocation: 1 when reading
and 1 when writing a violation store file.

Resolves TNG#1057

Signed-off-by: Piotr Kubowicz <piotr.kubowicz@gmail.com>
  • Loading branch information
pkubowicz authored and codecholeric committed Apr 15, 2023
1 parent f0c3ad5 commit 94f31ed
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.util.UUID;
import java.util.regex.Pattern;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.tngtech.archunit.PublicAPI;
import com.tngtech.archunit.lang.ArchRule;
Expand Down Expand Up @@ -151,24 +150,23 @@ public void save(ArchRule rule, List<String> violations) {
}

private void write(List<String> violations, File ruleDetails) {
String updatedViolations = Joiner.on("\n").join(escape(violations));
StringBuilder builder = new StringBuilder();
for (String violation : violations) {
builder.append(escape(violation)).append("\n");
}
try {
Files.write(ruleDetails.toPath(), updatedViolations.getBytes(UTF_8));
Files.write(ruleDetails.toPath(), builder.toString().getBytes(UTF_8));
} catch (IOException e) {
throw new StoreUpdateFailedException(e);
}
}

private List<String> escape(List<String> violations) {
return replaceCharacter(violations, "\n", "\\\n");
}

private List<String> unescape(List<String> violations) {
return replaceCharacter(violations, "\\\n", "\n");
private String escape(String violation) {
return violation.replace("\n", "\\\n");
}

private List<String> replaceCharacter(List<String> violations, String characterToReplace, String replacement) {
return violations.stream().map(violation -> violation.replace(characterToReplace, replacement)).collect(toList());
private String unescape(String violation) {
return violation.replace("\\\n", "\n");
}

private String ensureRuleFileName(ArchRule rule) {
Expand Down Expand Up @@ -197,8 +195,9 @@ public List<String> getViolations(ArchRule rule) {

private List<String> readLines(String ruleDetailsFileName) {
String violationsText = readStoreFile(ruleDetailsFileName);
List<String> lines = Splitter.on(UNESCAPED_LINE_BREAK_PATTERN).omitEmptyStrings().splitToList(violationsText);
return unescape(lines);
return Splitter.on(UNESCAPED_LINE_BREAK_PATTERN).omitEmptyStrings().splitToStream(violationsText)
.map(this::unescape)
.collect(toList());
}

private String readStoreFile(String fileName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ public void stores_violations_of_single_rule_in_configured_folder() throws IOExc
String ruleViolationsFile = properties.getProperty(defaultRule().getDescription());
assertThat(ruleViolationsFile).isNotBlank();

List<String> violationLines = Files.readLines(new File(configuredFolder, ruleViolationsFile), UTF_8);
assertThat(violationLines).containsOnly("first violation", "second violation");
String contents = Files.asCharSource(new File(configuredFolder, ruleViolationsFile), UTF_8).read();
assertThat(contents).isEqualTo("first violation\nsecond violation\n");
}

@Test
Expand Down

0 comments on commit 94f31ed

Please sign in to comment.