diff --git a/pom.xml b/pom.xml
index db44116..5830915 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
io.whelk.asciidoc
asciidoc-template-maven-plugin
- 1.0.7-RELEASE
+ 1.0.8-SNAPSHOT
maven-plugin
Asciidoc Template Plugin
@@ -67,6 +67,17 @@
1.18.12
provided
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.7.0-RC1
+ test
+
+
+ org.assertj
+ assertj-core
+ 3.16.1
+
diff --git a/src/main/java/io/whelk/asciidoc/TemplateMojo.java b/src/main/java/io/whelk/asciidoc/TemplateMojo.java
index ab89b60..a8fdfc0 100644
--- a/src/main/java/io/whelk/asciidoc/TemplateMojo.java
+++ b/src/main/java/io/whelk/asciidoc/TemplateMojo.java
@@ -2,9 +2,16 @@
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import lombok.Value;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
@@ -14,10 +21,15 @@
import org.apache.maven.project.MavenProject;
import lombok.SneakyThrows;
+import org.assertj.core.util.VisibleForTesting;
@Mojo(name = "build", defaultPhase = LifecyclePhase.PACKAGE)
public class TemplateMojo extends AbstractMojo {
+ public static final String TAG = "tag";
+
+ public static final String TAG_END = "end";
+
@Parameter(property = "templateDirectory")
String templateDirectory;
@@ -45,10 +57,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {
@SneakyThrows
private List readLines(String first, String... more) {
- return Files
- .readAllLines(Paths.get(first, more))
- .stream()
- .collect(Collectors.toList());
+ return new ArrayList<>(Files
+ .readAllLines(Paths.get(first, more)));
}
private List updateLines(List lines) {
@@ -67,13 +77,62 @@ private List updateLine(final String line) {
}
private boolean matchesIncludeLine(final String line) {
- return line.startsWith("include::") &&
- line.endsWith(".adoc[]");
+ return line.startsWith("include::") &&
+ line.endsWith("]");
+ }
+
+ @VisibleForTesting
+ List updateIncludeLine(final String line) {
+ var pathAndOptions = extractPathAndOptions(line);
+ if (pathAndOptions.optionMap.containsKey(TAG)) {
+ return readTaggedLines(templateDirectory, pathAndOptions);
+ }
+ return this.readLines(templateDirectory, pathAndOptions.path);
+ }
+
+ @SneakyThrows
+ private List readTaggedLines(String templateDirectory, PathAndOptions path) {
+ ArrayList lines = new ArrayList<>(Files
+ .readAllLines(Paths.get(templateDirectory, path.path)));
+ String tag = path.optionMap.get(TAG);
+ AtomicReference startHasBeenReached = new AtomicReference<>(false);
+ AtomicReference endHasBeenReached = new AtomicReference<>(false);
+ List taggedLines = lines.stream().filter(x -> {
+ boolean foundStart = x.contains(TAG + "::" + tag);
+ boolean foundEnd = x.contains(TAG_END + "::" + tag);
+ if (!startHasBeenReached.get()) {
+ startHasBeenReached.set(foundStart);
+ }
+ if (startHasBeenReached.get() && !endHasBeenReached.get()) {
+ endHasBeenReached.set(foundEnd);
+ }
+ boolean thisIsATagLine = foundStart || foundEnd;
+ return !thisIsATagLine && startHasBeenReached.get() && !endHasBeenReached.get();
+ }).collect(Collectors.toList());
+ return taggedLines;
+ }
+
+ @Value
+ static
+ class PathAndOptions {
+ String path;
+ Map optionMap;
}
- private List updateIncludeLine(final String line) {
- var path = line.substring(9, line.length() - 2);
- return this.readLines(templateDirectory, path);
+ @VisibleForTesting
+ PathAndOptions extractPathAndOptions(String line) {
+ int pathStart = 9;
+ Pattern pattern = Pattern.compile("\\[.*\\]$");
+ Matcher matcher = pattern.matcher(line);
+ boolean found = matcher.find();
+ String[] allOptions = matcher.group().replaceAll("[\\[\\]]", "").split(",");
+ Map optionMap = Arrays.asList(allOptions).stream()
+ .filter(x -> x.trim().length() > 0)
+ .map(x -> x.split("="))
+ .collect(Collectors.toMap(x -> x[0], x -> x[1]));
+ int pathEnd = matcher.start();
+ String path = line.substring(pathStart, pathEnd);
+ return new PathAndOptions(path, optionMap);
}
private void setDefaultConfiguration() {
diff --git a/src/test/java/io/whelk/asciidoc/TemplateMojoTest.java b/src/test/java/io/whelk/asciidoc/TemplateMojoTest.java
new file mode 100644
index 0000000..5010194
--- /dev/null
+++ b/src/test/java/io/whelk/asciidoc/TemplateMojoTest.java
@@ -0,0 +1,37 @@
+package io.whelk.asciidoc;
+
+import io.whelk.asciidoc.TemplateMojo.PathAndOptions;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TemplateMojoTest {
+
+ // tag::exampleShort[]
+ String test = "this is a small test";
+ // end::exampleShort[]
+
+ @Test
+ void testFilePathExtraction() {
+ TemplateMojo templateMojo = new TemplateMojo();
+
+ assertThat(templateMojo.extractPathAndOptions("include::otherFile.adoc[]"))
+ .isEqualTo(new PathAndOptions("otherFile.adoc", Map.of()));
+
+ assertThat(templateMojo.extractPathAndOptions("include::src/test/java/io/whelk/asciidoc/TemplateMojoTest.java[tag=exampleShort]"))
+ .isEqualTo(new PathAndOptions("src/test/java/io/whelk/asciidoc/TemplateMojoTest.java", Map.of("tag", "exampleShort")));
+ }
+
+ @Test
+ void includeJavaCode() {
+ TemplateMojo templateMojo = new TemplateMojo();
+ templateMojo.templateDirectory = "./";
+
+ assertThat(templateMojo.updateIncludeLine("include::src/test/java/io/whelk/asciidoc/TemplateMojoTest.java[tag=exampleShort]"))
+ .containsOnly(" String test = \"this is a small test\";");
+ }
+
+}