Repository: jhipster/jhipster-lite
Pull request #10118 (2024-06-20 16:06:52)

feat: introduce a new ElementReplacer dedicated to insert text at end of file


Patch:
diff --git a/src/main/java/tech/jhipster/lite/module/domain/replacement/EndOfFileReplacer.java b/src/main/java/tech/jhipster/lite/module/domain/replacement/EndOfFileReplacer.java
new file mode 100644
index 000000000..3adf5aff7
--- /dev/null
+++ b/src/main/java/tech/jhipster/lite/module/domain/replacement/EndOfFileReplacer.java
@@ -0,0 +1,41 @@
+package tech.jhipster.lite.module.domain.replacement;
+
+import java.util.function.BiFunction;
+import java.util.regex.Pattern;
+import tech.jhipster.lite.module.domain.JHipsterModule;
+import tech.jhipster.lite.shared.error.domain.Assert;
+import tech.jhipster.lite.shared.generation.domain.ExcludeFromGeneratedCodeCoverage;
+
+/**
+ * {@link ElementReplacer} that inserts content at end of the file if the provided condition is met
+ * @param condition
+ */
+public record EndOfFileReplacer(ReplacementCondition condition) implements ElementReplacer {
+  private static final Pattern EOF_PATTERN = Pattern.compile("\\z", Pattern.MULTILINE);
+
+  public EndOfFileReplacer {
+    Assert.notNull("condition", condition);
+    Assert.notNull("pattern", EOF_PATTERN);
+  }
+
+  @Override
+  @ExcludeFromGeneratedCodeCoverage(reason = "Pattern always matches")
+  public boolean notMatchIn(String content) {
+    return !EOF_PATTERN.matcher(content).find();
+  }
+
+  @Override
+  public BiFunction<String, String, String> replacement() {
+    return (content, replacement) ->
+      EOF_PATTERN.matcher(content).replaceAll(result -> escapeSpecialCharacters(replacement) + JHipsterModule.LINE_BREAK + result.group());
+  }
+
+  private String escapeSpecialCharacters(String replacement) {
+    return replacement.replace("$", "\\$");
+  }
+
+  @Override
+  public String searchMatcher() {
+    return EOF_PATTERN.pattern();
+  }
+}
diff --git a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemGitIgnoreHandler.java b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemGitIgnoreHandler.java
index deb1d0664..837a97295 100644
--- a/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemGitIgnoreHandler.java
+++ b/src/main/java/tech/jhipster/lite/module/infrastructure/secondary/FileSystemGitIgnoreHandler.java
@@ -1,10 +1,11 @@
 package tech.jhipster.lite.module.infrastructure.secondary;
 
+import static tech.jhipster.lite.module.domain.replacement.ReplacementCondition.notContainingReplacement;
+
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.function.Consumer;
-import java.util.regex.Pattern;
 import org.springframework.stereotype.Service;
 import tech.jhipster.lite.module.domain.JHipsterModuleContext;
 import tech.jhipster.lite.module.domain.JHipsterProjectFilePath;
@@ -19,7 +20,6 @@ import tech.jhipster.lite.shared.generation.domain.ExcludeFromGeneratedCodeCover
 @Service
 class FileSystemGitIgnoreHandler {
 
-  private static final Pattern END_OF_FILE = Pattern.compile("\\z", Pattern.MULTILINE);
   private static final String GIT_IGNORE_FILE_PATH = ".gitignore";
   private final FileSystemReplacer fileReplacer;
 
@@ -55,10 +55,7 @@ class FileSystemGitIgnoreHandler {
 
   private Consumer<GitIgnoreEntry> handleIgnorePattern(JHipsterProjectFolder projectFolder) {
     return gitIgnoreEntry -> {
-      MandatoryReplacer replacer = new MandatoryReplacer(
-        new RegexNeedleAfterReplacer((contentBeforeReplacement, newText) -> !contentBeforeReplacement.contains(newText), END_OF_FILE),
-        gitIgnoreEntry.get()
-      );
+      MandatoryReplacer replacer = new MandatoryReplacer(new EndOfFileReplacer(notContainingReplacement()), gitIgnoreEntry.get());
       fileReplacer.handle(
         projectFolder,
         ContentReplacers.of(new MandatoryFileReplacer(new JHipsterProjectFilePath(GIT_IGNORE_FILE_PATH), replacer)),


Test patch:
diff --git a/src/test/java/tech/jhipster/lite/module/domain/replacement/EndOfFileReplacerTest.java b/src/test/java/tech/jhipster/lite/module/domain/replacement/EndOfFileReplacerTest.java
new file mode 100644
index 000000000..55312742b
--- /dev/null
+++ b/src/test/java/tech/jhipster/lite/module/domain/replacement/EndOfFileReplacerTest.java
@@ -0,0 +1,48 @@
+package tech.jhipster.lite.module.domain.replacement;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static tech.jhipster.lite.module.domain.replacement.ReplacementCondition.always;
+
+import org.junit.jupiter.api.Test;
+import tech.jhipster.lite.UnitTest;
+
+@UnitTest
+class EndOfFileReplacerTest {
+
+  @Test
+  void shouldMatchMatchingRegex() {
+    EndOfFileReplacer replacer = new EndOfFileReplacer(always());
+
+    assertThat(replacer.notMatchIn("content")).isFalse();
+  }
+
+  @Test
+  void shouldReplaceLineEnd() {
+    EndOfFileReplacer replacer = new EndOfFileReplacer(always());
+
+    String updatedContent = replacer
+      .replacement()
+      .apply(
+        """
+        <root>
+        </root>
+        """,
+        "<element />"
+      );
+
+    assertThat(updatedContent).isEqualTo(
+      """
+      <root>
+      </root>
+      <element />
+      """
+    );
+  }
+
+  @Test
+  void shouldGetPatternAsSearchMatcher() {
+    EndOfFileReplacer replacer = new EndOfFileReplacer(always());
+
+    assertThat(replacer.searchMatcher()).isEqualTo("\\z");
+  }
+}