From e1fcd0d078f6f913830059f40a99ac329fcbcdf1 Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Thu, 24 Oct 2024 07:48:19 +0200 Subject: [PATCH 1/7] Initial setup for gitignore exclusion --- .../openrewrite/ExcludeFileFromGitignore.java | 168 ++++++++++++ .../ExcludeFileFromGitignoreTest.java | 259 ++++++++++++++++++ 2 files changed, 427 insertions(+) create mode 100644 rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java diff --git a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java new file mode 100644 index 00000000000..947f5f15543 --- /dev/null +++ b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java @@ -0,0 +1,168 @@ +package org.openrewrite; + + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Value; +import org.openrewrite.internal.StringUtils; +import org.openrewrite.jgit.ignore.FastIgnoreRule; +import org.openrewrite.jgit.ignore.IgnoreNode; +import org.openrewrite.text.PlainText; +import org.openrewrite.text.PlainTextVisitor; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +import static org.openrewrite.ExcludeFileFromGitignore.Repository; +import static org.openrewrite.jgit.ignore.IgnoreNode.MatchResult.CHECK_PARENT; +import static org.openrewrite.jgit.ignore.IgnoreNode.MatchResult.IGNORED; + +@Value +@EqualsAndHashCode(callSuper = false) +public class ExcludeFileFromGitignore extends ScanningRecipe { + + @Override + public String getDisplayName() { + return "Remove ignoral of files or directories in .gitignore"; + } + + @Override + public String getDescription() { + return "This recipe will remove a file or directory to the .gitignore file. " + + "If the file or directory is already in the .gitignore file, it will be removed." + + "If the file or directory is not in the .gitignore file, no action will be taken."; + } + + @Option(displayName = "Paths", + description = "The paths to find and remove from the gitignore files.", + example = "blacklist") + List paths; + + @Override + public Repository getInitialValue(ExecutionContext ctx) { + return new Repository(); + } + + @Override + public TreeVisitor getScanner(Repository acc) { + return new PlainTextVisitor(){ + @Override + public boolean isAcceptable(SourceFile sourceFile, ExecutionContext executionContext) { + return super.isAcceptable(sourceFile, executionContext) && sourceFile.getSourcePath().endsWith(".gitignore"); + } + + @Override + public PlainText visitText(PlainText text, ExecutionContext executionContext) { + try { + String gitignoreFileName = text.getSourcePath().toString(); + gitignoreFileName = gitignoreFileName.startsWith("/") ? gitignoreFileName : "/" + gitignoreFileName; + IgnoreNode ignoreNode = new IgnoreNode(); + ignoreNode.parse(gitignoreFileName, new ByteArrayInputStream(text.getText().getBytes())); + acc.getRules().put(gitignoreFileName.substring(0, gitignoreFileName.lastIndexOf("/") + 1), ignoreNode); + } catch (IOException e) { + throw new RuntimeException("Unknown error udring recipe run", e); + } + return super.visitText(text, executionContext); + } + }; + } + + @Data + public static class Repository { + private final Map rules = new HashMap<>(); + + public void exclude(String path) { + String normalizedPath = path.startsWith("/") ? path : "/" + path; + List impactingFiles = rules.keySet().stream() + .filter(k -> normalizedPath.toLowerCase().startsWith(k.toLowerCase())) + .sorted(Comparator.comparingInt(String::length).reversed()) + .collect(Collectors.toList()); + + IgnoreNode.MatchResult isIgnored; + boolean isDirectory = path.endsWith("/"); + for (String impactingFile : impactingFiles) { + IgnoreNode ignoreNode = rules.get(impactingFile); + String nestedPath = normalizedPath.substring(impactingFile.length() - 1); + isIgnored = ignoreNode.isIgnored(nestedPath, isDirectory); + if (CHECK_PARENT.equals(isIgnored)) { + continue; + } + if (IGNORED.equals(isIgnored)) { + List remainingRules = new ArrayList<>(); + for (FastIgnoreRule rule : ignoreNode.getRules()) { + if (!rule.isMatch(nestedPath, isDirectory, true) || !rule.getResult()) { + remainingRules.add(rule); + continue; + } else if (rule.toString().equals(nestedPath)) { + continue; + } else if (rule.getNameOnly() || rule.dirOnly()) { + remainingRules.add(rule); + remainingRules.add(new FastIgnoreRule("!" + nestedPath)); + continue; + } + remainingRules.add(rule); + } + IgnoreNode replacedNode = new IgnoreNode(remainingRules); + rules.put(impactingFile, replacedNode); + if (CHECK_PARENT.equals(replacedNode.isIgnored(nestedPath, isDirectory))) { + continue; + } + } + break; + } + } + } + + @Override + public TreeVisitor getVisitor(Repository acc) { + + for (String path : paths) { + acc.exclude(path); + } + + return new PlainTextVisitor() { + @Override + public boolean isAcceptable(SourceFile sourceFile, ExecutionContext executionContext) { + return super.isAcceptable(sourceFile, executionContext) && sourceFile.getSourcePath().endsWith(".gitignore"); + } + + @Override + public PlainText visitText(PlainText text, ExecutionContext executionContext) { + String gitignoreFileName = text.getSourcePath().toString(); + gitignoreFileName = gitignoreFileName.startsWith("/") ? gitignoreFileName : "/" + gitignoreFileName; + IgnoreNode ignoreNode = acc.getRules().get(gitignoreFileName.substring(0, gitignoreFileName.lastIndexOf("/") + 1)); + if (ignoreNode != null) { + String separator = text.getText().contains("\r\n") ? "\r\n" : "\n"; + List rules = ignoreNode.getRules(); + List newRules = Arrays.stream(text.getText().split(separator)).filter(line -> { + if (line.startsWith("#") || StringUtils.isBlank(line)) { + return true; + } + if (rules.stream().anyMatch(rule -> line.equalsIgnoreCase(rule.toString()))) { + return true; + } + return false; + }).collect(Collectors.toList()); + for (int i = 0; i < rules.size(); i++) { + FastIgnoreRule ignoreRule = rules.get(i); + if (newRules.stream().noneMatch(rule -> rule.equalsIgnoreCase(ignoreRule.toString()))) { + //TODO find the position to insert the rule using surrounding rules as best as possible + newRules.add(ignoreRule.toString()); + } + } + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < newRules.size(); i++) { + if (i > 0) { + sb.append(separator); + } + sb.append(newRules.get(i)); + } + return text.withText(sb.toString()); + } + return super.visitText(text, executionContext); + } + }; + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java b/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java new file mode 100644 index 00000000000..640d23dbc8e --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java @@ -0,0 +1,259 @@ +package org.openrewrite; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; + +import java.util.List; + +import static org.openrewrite.test.SourceSpecs.text; + +class ExcludeFileFromGitignoreTest implements RewriteTest { + + @Test + void removesEntryIfExactPathMatch() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("test.yml"))), + text( + """ + /test.yml + """, + """ + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void addNegationIfFileNameMatch() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("test.yml"))), + text( + """ + test.yml + """, + """ + test.yml + !/test.yml + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void addNegationIfNestedFileNameMatch() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml"))), + text( + """ + test.yml + """, + """ + test.yml + !/directory/test.yml + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void commentsAndEmptyLinesUntouched() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml"))), + text( + """ + # comment + + test.yml + """, + """ + # comment + + test.yml + !/directory/test.yml + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void looksInNestedGitignoreFiles() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml"))), + text( + """ + test.yml + """, + spec -> spec.path(".gitignore") + ), + text( + """ + test.yml + """, + """ + test.yml + !/test.yml + """, + spec -> spec.path("directory/.gitignore") + ) + ); + } + + @Test + void removesInNestedGitignoreFiles() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml"))), + text( + """ + """, + spec -> spec.path(".gitignore") + ), + text( + """ + /test.yml + """, + """ + """, + spec -> spec.path("directory/.gitignore") + ) + ); + } + + @Test + void recursivelyLooksInNestedGitignoreFiles() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml"))), + text( + """ + test.yml + """, + """ + test.yml + !/directory/test.yml + """, + spec -> spec.path(".gitignore") + ), + text( + """ + /test.yml + """, + """ + """, + spec -> spec.path("directory/.gitignore") + ) + ); + } + + @Test + void nothingToRemoveIfPathNotInGitignore() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml"))), + text( + """ + otherfile.yml + otherdirectory/test.yml + """, + spec -> spec.path(".gitignore") + ), + text( + """ + otherfile.yml + """, + spec -> spec.path("directory/.gitignore") + ) + ); + } + + @Test + void multiplePaths() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml", "otherdirectory/otherfile.yml", "directory/nested/not-ignored.yml"))), + text( + """ + test.yml + /otherdirectory/otherfile.yml + """, + """ + test.yml + !/directory/test.yml + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void negateFileFromIgnoredDirectory() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml"))), + text( + """ + /directory/ + """, + """ + /directory/ + !/directory/test.yml + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void ignoredDirectories() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/"))), + text( + """ + /directory/ + """, + """ + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void ignoreNestedDirectory() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/nested/"))), + text( + """ + /directory/ + """, + """ + /directory/ + !/directory/nested/ + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void ignoreNestedDirectoryWithMultipleGitignoreFiles() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/nested/yet-another-nested/test.yml"))), + text( + """ + otherfile.yml + """, + spec -> spec.path(".gitignore") + ), + text( + """ + /yet-another-nested/ + """, + """ + /yet-another-nested/ + !/yet-another-nested/test.yml + """, + spec -> spec.path("directory/nested/.gitignore") + ) + ); + } +} \ No newline at end of file From b759b4aa02288bdef1eaa78b9c18947a9c610ec6 Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Thu, 24 Oct 2024 22:17:55 +0200 Subject: [PATCH 2/7] Added a test after identifying a potential bug in the jgit fork --- .../ExcludeFileFromGitignoreTest.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java b/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java index 640d23dbc8e..cf983981e75 100644 --- a/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java +++ b/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java @@ -203,7 +203,7 @@ void negateFileFromIgnoredDirectory() { } @Test - void ignoredDirectories() { + void ignoredExactDirectories() { rewriteRun( spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/"))), text( @@ -217,6 +217,23 @@ void ignoredDirectories() { ); } + @Test + void ignoredDirectories() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/"))), + text( + """ + directory/ + """, + """ + directory/ + !/directory/ + """, + spec -> spec.path(".gitignore") + ) + ); + } + @Test void ignoreNestedDirectory() { rewriteRun( @@ -256,4 +273,4 @@ void ignoreNestedDirectoryWithMultipleGitignoreFiles() { ) ); } -} \ No newline at end of file +} From 919b9424cf0745f4e3e0e2729b510eb81fe10de8 Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Fri, 25 Oct 2024 02:13:42 +0200 Subject: [PATCH 3/7] Workaround for issue 3 of jgit --- .../openrewrite/ExcludeFileFromGitignore.java | 108 +++++++++++++++--- 1 file changed, 94 insertions(+), 14 deletions(-) diff --git a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java index 947f5f15543..b422720d55c 100644 --- a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java +++ b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java @@ -1,6 +1,5 @@ package org.openrewrite; - import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Value; @@ -10,14 +9,21 @@ import org.openrewrite.text.PlainText; import org.openrewrite.text.PlainTextVisitor; +import javax.annotation.Nullable; import java.io.ByteArrayInputStream; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import static org.openrewrite.ExcludeFileFromGitignore.Repository; import static org.openrewrite.jgit.ignore.IgnoreNode.MatchResult.CHECK_PARENT; import static org.openrewrite.jgit.ignore.IgnoreNode.MatchResult.IGNORED; +import static org.openrewrite.jgit.ignore.IgnoreNode.MatchResult.NOT_IGNORED; @Value @EqualsAndHashCode(callSuper = false) @@ -30,14 +36,10 @@ public String getDisplayName() { @Override public String getDescription() { - return "This recipe will remove a file or directory to the .gitignore file. " + - "If the file or directory is already in the .gitignore file, it will be removed." + - "If the file or directory is not in the .gitignore file, no action will be taken."; + return "This recipe will remove a file or directory to the .gitignore file. " + "If the file or directory is already in the .gitignore file, it will be removed." + "If the file or directory is not in the .gitignore file, no action will be taken."; } - @Option(displayName = "Paths", - description = "The paths to find and remove from the gitignore files.", - example = "blacklist") + @Option(displayName = "Paths", description = "The paths to find and remove from the gitignore files.", example = "blacklist") List paths; @Override @@ -47,7 +49,7 @@ public Repository getInitialValue(ExecutionContext ctx) { @Override public TreeVisitor getScanner(Repository acc) { - return new PlainTextVisitor(){ + return new PlainTextVisitor() { @Override public boolean isAcceptable(SourceFile sourceFile, ExecutionContext executionContext) { return super.isAcceptable(sourceFile, executionContext) && sourceFile.getSourcePath().endsWith(".gitignore"); @@ -61,6 +63,7 @@ public PlainText visitText(PlainText text, ExecutionContext executionContext) { IgnoreNode ignoreNode = new IgnoreNode(); ignoreNode.parse(gitignoreFileName, new ByteArrayInputStream(text.getText().getBytes())); acc.getRules().put(gitignoreFileName.substring(0, gitignoreFileName.lastIndexOf("/") + 1), ignoreNode); + acc.issue3Directories(gitignoreFileName.substring(0, gitignoreFileName.lastIndexOf("/") + 1), text.getText()); } catch (IOException e) { throw new RuntimeException("Unknown error udring recipe run", e); } @@ -72,13 +75,16 @@ public PlainText visitText(PlainText text, ExecutionContext executionContext) { @Data public static class Repository { private final Map rules = new HashMap<>(); + private final Map> issue3IgnoredDirectories = new HashMap<>(); + private final Map> issue3NegatedDirectories = new HashMap<>(); public void exclude(String path) { String normalizedPath = path.startsWith("/") ? path : "/" + path; - List impactingFiles = rules.keySet().stream() - .filter(k -> normalizedPath.toLowerCase().startsWith(k.toLowerCase())) - .sorted(Comparator.comparingInt(String::length).reversed()) - .collect(Collectors.toList()); + List impactingFiles = rules.keySet() + .stream() + .filter(k -> normalizedPath.toLowerCase().startsWith(k.toLowerCase())) + .sorted(Comparator.comparingInt(String::length).reversed()) + .collect(Collectors.toList()); IgnoreNode.MatchResult isIgnored; boolean isDirectory = path.endsWith("/"); @@ -86,13 +92,46 @@ public void exclude(String path) { IgnoreNode ignoreNode = rules.get(impactingFile); String nestedPath = normalizedPath.substring(impactingFile.length() - 1); isIgnored = ignoreNode.isIgnored(nestedPath, isDirectory); + // Overcoming issue3 in jgit repo for the pathMatch being false + if (CHECK_PARENT.equals(isIgnored) && isDirectory) { + List rules = ignoreNode.getRules(); + for (int i = rules.size() - 1; i > -1; i--) { + FastIgnoreRule rule = rules.get(i); + if (rule.isMatch(nestedPath, true, false)) { + if (rule.getResult()) { + isIgnored = IGNORED; + } else { + isIgnored = NOT_IGNORED; + } + break; + } + } + } + // Overcoming issue3 in jgit repo for the single directory rules + if (CHECK_PARENT.equals(isIgnored)) { + Boolean ignored = isIgnoredByDirectoryIssue3Bypass(impactingFile, nestedPath); + if (ignored != null) { + if (ignored) { + isIgnored = IGNORED; + } else { + isIgnored = NOT_IGNORED; + } + } + } if (CHECK_PARENT.equals(isIgnored)) { continue; } if (IGNORED.equals(isIgnored)) { List remainingRules = new ArrayList<>(); for (FastIgnoreRule rule : ignoreNode.getRules()) { - if (!rule.isMatch(nestedPath, isDirectory, true) || !rule.getResult()) { + // First 2 if clauses are for the jgit issue (#3) opened at openrewrite/jgit + if (issue3IgnoredDirectories.getOrDefault(impactingFile, new ArrayList<>()).stream().anyMatch(nestedPath::equalsIgnoreCase)) { + continue; + } else if (issue3IgnoredDirectories.getOrDefault(impactingFile, new ArrayList<>()).stream().anyMatch(nestedPath::startsWith)) { + remainingRules.add(rule); + remainingRules.add(new FastIgnoreRule("!" + nestedPath)); + continue; + } else if (!rule.isMatch(nestedPath, isDirectory, true) || !rule.getResult()) { remainingRules.add(rule); continue; } else if (rule.toString().equals(nestedPath)) { @@ -113,6 +152,47 @@ public void exclude(String path) { break; } } + + public void issue3Directories(final String gitignoreFileName, final String ignoreFile) { + Arrays.stream(ignoreFile.split("\\r?\\n")).forEach(line -> { + if (line.startsWith("#") || StringUtils.isBlank(line)) { + return; + } + Map> directories = issue3IgnoredDirectories; + if (line.startsWith("!")) { + line = line.substring(1); + directories = issue3NegatedDirectories; + } + if (!line.startsWith("/")) { + // lines not starting with / are not exact directory matches but equivalent to **/line/ + return; + } + if (line.endsWith("/")) { + directories.computeIfAbsent(gitignoreFileName, k -> new ArrayList<>()).add(line); + } + }); + } + + @Nullable + private Boolean isIgnoredByDirectoryIssue3Bypass(String gitignoreFileName, String path) { + List ignoredDirectories = issue3IgnoredDirectories.get(gitignoreFileName); + List negatedDirectories = issue3NegatedDirectories.get(gitignoreFileName); + if (negatedDirectories != null) { + for (String negatedDirectory : negatedDirectories) { + if (path.startsWith(negatedDirectory)) { + return false; + } + } + } + if (ignoredDirectories != null) { + for (String ignoredDirectory : ignoredDirectories) { + if (path.startsWith(ignoredDirectory)) { + return true; + } + } + } + return null; + } } @Override From e7c8de30f72381323142ca9ed00a8080353a6cdc Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Fri, 25 Oct 2024 02:19:37 +0200 Subject: [PATCH 4/7] Added some wildcard tests --- .../ExcludeFileFromGitignoreTest.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java b/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java index cf983981e75..cf78eba0a07 100644 --- a/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java +++ b/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java @@ -273,4 +273,41 @@ void ignoreNestedDirectoryWithMultipleGitignoreFiles() { ) ); } + + @Test + void ignoreWildcardedDirectory() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/nested/"))), + text( + """ + /**/nested/ + """, + """ + /**/nested/ + !/directory/nested/ + """, + spec -> spec.path(".gitignore") + ) + ); + } + + @Test + void ignoreWildcardedFile() { + rewriteRun( + spec -> spec.recipe(new ExcludeFileFromGitignore(List.of("directory/test.yml", "directory/other.txt"))), + text( + """ + /test.* + /*.txt + """, + """ + /test.* + /*.txt + !/test.yml + !/other.txt + """, + spec -> spec.path("directory/.gitignore") + ) + ); + } } From 737e8e6cc623c65d7e70407deae99458977540fe Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Fri, 25 Oct 2024 02:21:31 +0200 Subject: [PATCH 5/7] added a comment --- .../src/main/java/org/openrewrite/ExcludeFileFromGitignore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java index b422720d55c..7f30585d164 100644 --- a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java +++ b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java @@ -228,7 +228,7 @@ public PlainText visitText(PlainText text, ExecutionContext executionContext) { for (int i = 0; i < rules.size(); i++) { FastIgnoreRule ignoreRule = rules.get(i); if (newRules.stream().noneMatch(rule -> rule.equalsIgnoreCase(ignoreRule.toString()))) { - //TODO find the position to insert the rule using surrounding rules as best as possible + //Can we not find the position to insert the rule using surrounding rules as best as possible? newRules.add(ignoreRule.toString()); } } From 9b82f037b1bbf69c3eb5091d4665e01eaf6ce939 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 25 Oct 2024 13:46:04 +0200 Subject: [PATCH 6/7] Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../openrewrite/ExcludeFileFromGitignore.java | 30 ++++++++++++++----- .../ExcludeFileFromGitignoreTest.java | 15 ++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java index 7f30585d164..fff7539a5af 100644 --- a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java +++ b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java @@ -1,3 +1,18 @@ +/* + * Copyright 2024 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. + * You may obtain a copy of the License at + *

+ * https://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 org.openrewrite; import lombok.Data; @@ -51,8 +66,8 @@ public Repository getInitialValue(ExecutionContext ctx) { public TreeVisitor getScanner(Repository acc) { return new PlainTextVisitor() { @Override - public boolean isAcceptable(SourceFile sourceFile, ExecutionContext executionContext) { - return super.isAcceptable(sourceFile, executionContext) && sourceFile.getSourcePath().endsWith(".gitignore"); + public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) { + return super.isAcceptable(sourceFile, ctx) && sourceFile.getSourcePath().endsWith(".gitignore"); } @Override @@ -67,7 +82,7 @@ public PlainText visitText(PlainText text, ExecutionContext executionContext) { } catch (IOException e) { throw new RuntimeException("Unknown error udring recipe run", e); } - return super.visitText(text, executionContext); + return super.visitText(text, ctx); } }; } @@ -173,8 +188,7 @@ public void issue3Directories(final String gitignoreFileName, final String ignor }); } - @Nullable - private Boolean isIgnoredByDirectoryIssue3Bypass(String gitignoreFileName, String path) { + private @Nullable Boolean isIgnoredByDirectoryIssue3Bypass(String gitignoreFileName, String path) { List ignoredDirectories = issue3IgnoredDirectories.get(gitignoreFileName); List negatedDirectories = issue3NegatedDirectories.get(gitignoreFileName); if (negatedDirectories != null) { @@ -204,8 +218,8 @@ public TreeVisitor getVisitor(Repository acc) { return new PlainTextVisitor() { @Override - public boolean isAcceptable(SourceFile sourceFile, ExecutionContext executionContext) { - return super.isAcceptable(sourceFile, executionContext) && sourceFile.getSourcePath().endsWith(".gitignore"); + public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) { + return super.isAcceptable(sourceFile, ctx) && sourceFile.getSourcePath().endsWith(".gitignore"); } @Override @@ -241,7 +255,7 @@ public PlainText visitText(PlainText text, ExecutionContext executionContext) { } return text.withText(sb.toString()); } - return super.visitText(text, executionContext); + return super.visitText(text, ctx); } }; } diff --git a/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java b/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java index cf78eba0a07..23b17840bb6 100644 --- a/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java +++ b/rewrite-core/src/test/java/org/openrewrite/ExcludeFileFromGitignoreTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2024 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. + * You may obtain a copy of the License at + *

+ * https://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 org.openrewrite; import org.junit.jupiter.api.Test; From 2c527924dfe2a17d2c2aa05f42014154daa1d446 Mon Sep 17 00:00:00 2001 From: Jente Sondervorst Date: Fri, 25 Oct 2024 14:09:02 +0200 Subject: [PATCH 7/7] fix compilation --- .../main/java/org/openrewrite/ExcludeFileFromGitignore.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java index fff7539a5af..fdb014ca73c 100644 --- a/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java +++ b/rewrite-core/src/main/java/org/openrewrite/ExcludeFileFromGitignore.java @@ -71,7 +71,7 @@ public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) { } @Override - public PlainText visitText(PlainText text, ExecutionContext executionContext) { + public PlainText visitText(PlainText text, ExecutionContext ctx) { try { String gitignoreFileName = text.getSourcePath().toString(); gitignoreFileName = gitignoreFileName.startsWith("/") ? gitignoreFileName : "/" + gitignoreFileName; @@ -223,7 +223,7 @@ public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) { } @Override - public PlainText visitText(PlainText text, ExecutionContext executionContext) { + public PlainText visitText(PlainText text, ExecutionContext ctx) { String gitignoreFileName = text.getSourcePath().toString(); gitignoreFileName = gitignoreFileName.startsWith("/") ? gitignoreFileName : "/" + gitignoreFileName; IgnoreNode ignoreNode = acc.getRules().get(gitignoreFileName.substring(0, gitignoreFileName.lastIndexOf("/") + 1));