From 139fcdef306a07688261aeed0a5e42150f63fe33 Mon Sep 17 00:00:00 2001 From: Abel Salgado Romero Date: Sun, 18 Jul 2021 20:33:50 +0200 Subject: [PATCH] Allow setting included sources to run full refresh on change (#542) --- CHANGELOG.adoc | 4 ++ .../auto-refresh-mojo-parameters.adoc | 4 ++ .../maven/AsciidoctorRefreshMojo.java | 24 +++++-- .../maven/process/SourceDocumentFinder.java | 4 +- ...alSourceFileAlterationListenerAdaptor.java | 35 +++++++++ .../maven/AsciidoctorRefreshMojoTest.java | 72 ++++++++++++++++--- 6 files changed, 124 insertions(+), 19 deletions(-) create mode 100644 src/main/java/org/asciidoctor/maven/refresh/AdditionalSourceFileAlterationListenerAdaptor.java diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index a5178b49..7bdc87cd 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -13,6 +13,10 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/main[co == Unreleased +Improvements:: + + * Allow running a refresh build on included sources (for `auto-refresh` & `http` mojos) (#542) + Documentation:: * Migrate docs (README) to Antora site and publish them in gh-pages (#498) diff --git a/docs/modules/plugin/partials/auto-refresh-mojo-parameters.adoc b/docs/modules/plugin/partials/auto-refresh-mojo-parameters.adoc index 27bade10..93f7dd5e 100644 --- a/docs/modules/plugin/partials/auto-refresh-mojo-parameters.adoc +++ b/docs/modules/plugin/partials/auto-refresh-mojo-parameters.adoc @@ -1,2 +1,6 @@ interval:: time in milliseconds between checks of the filesystem. Defaults to `2000` + +refreshOn:: regular expression describing additional sources that force a full refresh. +Useful when working with included/partial sources that aren't converted individually. +Defaults to `empty` diff --git a/src/main/java/org/asciidoctor/maven/AsciidoctorRefreshMojo.java b/src/main/java/org/asciidoctor/maven/AsciidoctorRefreshMojo.java index 6b4bbbf4..5bc52a30 100644 --- a/src/main/java/org/asciidoctor/maven/AsciidoctorRefreshMojo.java +++ b/src/main/java/org/asciidoctor/maven/AsciidoctorRefreshMojo.java @@ -11,10 +11,7 @@ import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.asciidoctor.maven.refresh.AsciidoctorConverterFileAlterationListenerAdaptor; -import org.asciidoctor.maven.refresh.ResourceCopyFileAlterationListenerAdaptor; -import org.asciidoctor.maven.refresh.ResourcesPatternBuilder; -import org.asciidoctor.maven.refresh.TimeCounter; +import org.asciidoctor.maven.refresh.*; import java.io.File; import java.io.FileFilter; @@ -22,6 +19,8 @@ import static org.apache.commons.lang3.StringUtils.isBlank; import static org.asciidoctor.maven.io.AsciidoctorFileScanner.ASCIIDOC_NON_INTERNAL_REG_EXP; +import static org.asciidoctor.maven.process.SourceDocumentFinder.CUSTOM_FILE_EXTENSIONS_PATTERN_PREFIX; +import static org.asciidoctor.maven.process.SourceDocumentFinder.CUSTOM_FILE_EXTENSIONS_PATTERN_SUFFIX; @Mojo(name = "auto-refresh") public class AsciidoctorRefreshMojo extends AsciidoctorMojo { @@ -31,6 +30,9 @@ public class AsciidoctorRefreshMojo extends AsciidoctorMojo { @Parameter(property = PREFIX + "interval") protected int interval = 2000; // 2s + @Parameter(property = PREFIX + "refreshOn") + protected String refreshOn; + private Collection monitors = null; @@ -100,7 +102,7 @@ protected void startPolling() throws MojoExecutionException { final FileAlterationMonitor fileAlterationMonitor = new FileAlterationMonitor(interval); - { // content monitor + { // sources monitor final FileAlterationObserver observer = new FileAlterationObserver(sourceDirectory, buildSourcesFileFilter()); final FileAlterationListener listener = new AsciidoctorConverterFileAlterationListenerAdaptor(this, () -> showWaitMessage(), getLog()); @@ -108,6 +110,16 @@ protected void startPolling() throws MojoExecutionException { fileAlterationMonitor.addObserver(observer); } + { // included-sources monitor + if (!isBlank(refreshOn)) { + final FileAlterationObserver observer = new FileAlterationObserver(sourceDirectory, new RegexFileFilter(refreshOn)); + final FileAlterationListener listener = new AdditionalSourceFileAlterationListenerAdaptor(this, () -> showWaitMessage(), getLog()); + + observer.addListener(listener); + fileAlterationMonitor.addObserver(observer); + } + } + { // resources monitor final FileAlterationObserver observer = new FileAlterationObserver(sourceDirectory, buildResourcesFileFilter()); final FileAlterationListener listener = new ResourceCopyFileAlterationListenerAdaptor(this, () -> showWaitMessage(), getLog()); @@ -137,7 +149,7 @@ private IOFileFilter buildSourcesFileFilter() { return new NameFileFilter(sourceDocumentName); if (!sourceDocumentExtensions.isEmpty()) { - final StringJoiner stringJoiner = new StringJoiner("|", "^[^_.].*\\.(", ")$"); + final StringJoiner stringJoiner = new StringJoiner("|", CUSTOM_FILE_EXTENSIONS_PATTERN_PREFIX, CUSTOM_FILE_EXTENSIONS_PATTERN_SUFFIX); for (String extension : sourceDocumentExtensions) { stringJoiner.add(extension); } diff --git a/src/main/java/org/asciidoctor/maven/process/SourceDocumentFinder.java b/src/main/java/org/asciidoctor/maven/process/SourceDocumentFinder.java index 4b2d7a84..2287385f 100644 --- a/src/main/java/org/asciidoctor/maven/process/SourceDocumentFinder.java +++ b/src/main/java/org/asciidoctor/maven/process/SourceDocumentFinder.java @@ -24,10 +24,10 @@ public class SourceDocumentFinder { private static final String STANDARD_FILE_EXTENSIONS_PATTERN = "^[^_.].*\\.a((sc(iidoc)?)|d(oc)?)$"; /** Prefix for matching custom file extensions. */ - private static final String CUSTOM_FILE_EXTENSIONS_PATTERN_PREFIX = "^[^_.].*\\.("; + public static final String CUSTOM_FILE_EXTENSIONS_PATTERN_PREFIX = "^[^_.].*\\.("; /** Suffix for matching custom file extensions. */ - private static final String CUSTOM_FILE_EXTENSIONS_PATTERN_SUFFIX = ")$"; + public static final String CUSTOM_FILE_EXTENSIONS_PATTERN_SUFFIX = ")$"; /** * Finds all source documents inside the source directory with standard file extensions. diff --git a/src/main/java/org/asciidoctor/maven/refresh/AdditionalSourceFileAlterationListenerAdaptor.java b/src/main/java/org/asciidoctor/maven/refresh/AdditionalSourceFileAlterationListenerAdaptor.java new file mode 100644 index 00000000..44759f9d --- /dev/null +++ b/src/main/java/org/asciidoctor/maven/refresh/AdditionalSourceFileAlterationListenerAdaptor.java @@ -0,0 +1,35 @@ +package org.asciidoctor.maven.refresh; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.asciidoctor.maven.AsciidoctorRefreshMojo; +import org.asciidoctor.maven.process.ResourcesProcessor; + +import java.io.File; +import java.util.Collections; + +public class AdditionalSourceFileAlterationListenerAdaptor extends AbstractFileAlterationListenerAdaptor { + + private static final ResourcesProcessor EMPTY_RESOURCES_PROCESSOR = (sourcesDir, outputDir, encoding, configuration) -> { + }; + + + public AdditionalSourceFileAlterationListenerAdaptor(AsciidoctorRefreshMojo mojo, Runnable postAction, Log log) { + super(mojo, postAction, log); + } + + @Override + synchronized void processFile(File file, String actionName) { + getLog().info(String.format("Additional source file %s %s", file.getAbsolutePath(), actionName)); + getLog().info("Full refresh"); + long timeInMillis = TimeCounter.timed(() -> { + try { + getMojo().processAllSources(EMPTY_RESOURCES_PROCESSOR); + } catch (MojoExecutionException e) { + getLog().error(e); + } + }); + getLog().info("Converted document(s) in " + timeInMillis + "ms"); + } + +} diff --git a/src/test/java/org/asciidoctor/maven/AsciidoctorRefreshMojoTest.java b/src/test/java/org/asciidoctor/maven/AsciidoctorRefreshMojoTest.java index bfb4a89e..d6a68f69 100644 --- a/src/test/java/org/asciidoctor/maven/AsciidoctorRefreshMojoTest.java +++ b/src/test/java/org/asciidoctor/maven/AsciidoctorRefreshMojoTest.java @@ -5,17 +5,9 @@ import org.apache.maven.model.Resource; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugin.logging.SystemStreamLog; -import org.apache.maven.project.MavenProject; -import org.apache.maven.shared.filtering.DefaultMavenFileFilter; -import org.apache.maven.shared.filtering.DefaultMavenResourcesFiltering; import org.asciidoctor.maven.TestUtils.ResourceBuilder; import org.asciidoctor.maven.io.ConsoleHolder; -import org.codehaus.plexus.logging.console.ConsoleLogger; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.sonatype.plexus.build.incremental.BuildContext; -import org.sonatype.plexus.build.incremental.DefaultBuildContext; import java.io.File; import java.io.IOException; @@ -27,12 +19,11 @@ import java.util.stream.Collectors; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Collections.singletonList; import static org.asciidoctor.maven.TestUtils.newFakeRefreshMojo; import static org.asciidoctor.maven.io.TestFilesHelper.createFileWithContent; import static org.asciidoctor.maven.io.TestFilesHelper.newOutputTestDirectory; import static org.assertj.core.api.Assertions.assertThat; -import static org.codehaus.plexus.util.ReflectionUtils.setVariableValueInObject; -import static org.mockito.Mockito.when; public class AsciidoctorRefreshMojoTest { @@ -335,6 +326,65 @@ public void should_copy_resources_when_updated_but_not_on_start_when_there_are_n awaitTermination(mojoThread); } + @Test + public void should_convert_additional_sources_when_set_in_refreshOn() throws IOException { + // given + final ConsoleHolder consoleHolder = ConsoleHolder.start(); + + final File srcDir = newOutputTestDirectory(TEST_DIR); + final File outputDir = newOutputTestDirectory(TEST_DIR); + + // when + final File sourceFile = new File(srcDir, "sourceFile.adoc"); + String sourceContent = new StringBuilder() + .append("= Document Title\n\n") + .append("This is test, only a test.\n\n") + .append("== Included\n\n") + .append("include::included.txt[]") + .toString(); + FileUtils.write(sourceFile, sourceContent, UTF_8); + + final File includedFile = new File(srcDir, "included.txt"); + String includedContent = new StringBuilder() + .append("Original included content") + .toString(); + FileUtils.write(includedFile, includedContent, UTF_8); + + // when + Thread mojoThread = runMojoAsynchronously(mojo -> { + mojo.headerFooter = false; + mojo.backend = "html5"; + mojo.sourceDirectory = srcDir; + mojo.outputDirectory = outputDir; + mojo.refreshOn = ".*\\.txt"; + // THIS DOES NOT AFFECT + mojo.resources = ResourceBuilder.excludeAll(); + }); + + // then: source is converted and included is copies (treated as resource) + final File target = new File(outputDir, "sourceFile.html"); + consoleHolder.awaitProcessingAllSources(); + assertThat(FileUtils.readFileToString(target, UTF_8)) + .contains("Original included content"); + assertThat(includedContent) + .isNotEmpty(); + + // and when + FileUtils.write(includedFile, "Included content UPDATED!", UTF_8); + + // then + consoleHolder.awaitProcessingResource(); + assertThat(FileUtils.readFileToString(target, UTF_8)) + .contains("Included content UPDATED!"); + assertThat(includedContent) + .isNotEmpty(); + + // cleanup + consoleHolder.input("exit"); + consoleHolder.release(); + awaitTermination(mojoThread); + } + @Test public void should_copy_resource_in_root_when_resource_is_updated() throws IOException { // given @@ -730,7 +780,7 @@ private Thread runMojoAsynchronously(File srcDir, File outputDir) { @SneakyThrows private void awaitTermination(Thread thread) { int pollTime = 250; - int ticks = (10 * 1000 / pollTime); + int ticks = (30 * 1000 / pollTime); while (thread.isAlive()) { ticks--; if (ticks == 0)