diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 2bc3420e..c44774d6 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -16,6 +16,7 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/main[co Bug Fixes:: * Remove Java 'requires open access' module warning in modern Java versions with JRuby v9.4.5.0 (#553) + * Check for both destinationDir and toDir when to avoid invalid "Duplicated destination found" messages, and improve warning message (#728) Build / Infrastructure:: diff --git a/src/main/java/org/asciidoctor/maven/AsciidoctorMojo.java b/src/main/java/org/asciidoctor/maven/AsciidoctorMojo.java index 95782c7a..1703715c 100644 --- a/src/main/java/org/asciidoctor/maven/AsciidoctorMojo.java +++ b/src/main/java/org/asciidoctor/maven/AsciidoctorMojo.java @@ -1,5 +1,6 @@ package org.asciidoctor.maven; +import org.apache.commons.io.FilenameUtils; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; @@ -243,9 +244,16 @@ public void processSources(List sourceFiles, ResourcesProcessor resourcesP final Set uniquePaths = new HashSet<>(); for (final File source : sourceFiles) { - final File destinationPath = setDestinationPaths(source, optionsBuilder, sourceDir, this); - if (!uniquePaths.add(destinationPath)) - getLog().warn("Duplicated destination found: overwriting file: " + destinationPath.getAbsolutePath()); + final Destination destination = setDestinationPaths(source, optionsBuilder, sourceDir, this); + final File destinationPath = destination.path; + if (!uniquePaths.add(destinationPath)) { + String destinationFile = destinationPath.getAbsolutePath(); + if (!destination.isOutput) { + String baseName = FilenameUtils.getBaseName(destinationPath.getName()); + destinationFile = destinationPath.getParentFile().getAbsolutePath() + File.separator + baseName + ".*"; + } + getLog().warn("Duplicated destination found: overwriting file: " + destinationFile); + } convertFile(asciidoctor, optionsBuilder.asMap(), source); @@ -357,8 +365,8 @@ private void copyResources(List resources, String encoding, File outpu * @return the final destination file path. * @throws MojoExecutionException If output is not valid */ - public File setDestinationPaths(final File sourceFile, final OptionsBuilder optionsBuilder, final File sourceDirectory, - final AsciidoctorMojo configuration) throws MojoExecutionException { + public Destination setDestinationPaths(final File sourceFile, final OptionsBuilder optionsBuilder, final File sourceDirectory, + final AsciidoctorMojo configuration) throws MojoExecutionException { try { if (configuration.getBaseDir() != null) { optionsBuilder.baseDir(configuration.getBaseDir()); @@ -379,19 +387,37 @@ public File setDestinationPaths(final File sourceFile, final OptionsBuilder opti optionsBuilder.toDir(outputDir).destinationDir(outputDir); } final File outputFile = configuration.getOutputFile(); - final String destinationDir = (String) optionsBuilder.asMap().get(Options.DESTINATION_DIR); + final String destinationDir = getDestinationDir(optionsBuilder); if (outputFile != null) { - // allow overriding the output file name optionsBuilder.toFile(outputFile); - return outputFile.isAbsolute() ? outputFile : new File(destinationDir, outputFile.getPath()); + return outputFile.isAbsolute() + ? new Destination(outputFile, true) + : new Destination(new File(destinationDir, outputFile.getPath()), true); } else { - return new File(destinationDir, sourceFile.getName()); + return new Destination(new File(destinationDir, sourceFile.getName()), false); } } catch (IOException e) { throw new MojoExecutionException("Unable to locate output directory", e); } } + class Destination { + final File path; + // Whether path is the actual output file or an approximation + final boolean isOutput; + + Destination(File destination, boolean isSource) { + this.path = destination; + this.isOutput = isSource; + } + } + + private static String getDestinationDir(OptionsBuilder optionsBuilder) { + final Map options = optionsBuilder.asMap(); + return (String) Optional.ofNullable(options.get(Options.DESTINATION_DIR)) + .orElse(options.get(Options.TO_DIR)); + } + protected Asciidoctor getAsciidoctorInstance(String gemPath) throws MojoExecutionException { Asciidoctor asciidoctor = null; if (gemPath == null) { diff --git a/src/test/java/org/asciidoctor/maven/AsciidoctorMojoTest.java b/src/test/java/org/asciidoctor/maven/AsciidoctorMojoTest.java index d6342af5..c2dab281 100644 --- a/src/test/java/org/asciidoctor/maven/AsciidoctorMojoTest.java +++ b/src/test/java/org/asciidoctor/maven/AsciidoctorMojoTest.java @@ -5,12 +5,18 @@ import org.apache.maven.model.Resource; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.asciidoctor.Options; +import org.asciidoctor.OptionsBuilder; +import org.asciidoctor.maven.AsciidoctorMojo.Destination; import org.asciidoctor.maven.extensions.ExtensionConfiguration; import org.asciidoctor.maven.io.AsciidoctorFileScanner; import org.asciidoctor.maven.io.ConsoleHolder; import org.asciidoctor.maven.test.processors.RequireCheckerTreeprocessor; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullSource; +import org.junit.jupiter.params.provider.ValueSource; import java.io.*; import java.nio.file.Files; @@ -1069,4 +1075,23 @@ public void should_not_show_message_when_overwriting_files_using_outputFile_and_ consoleHolder.release(); } + @ParameterizedTest + @NullSource + @ValueSource(strings = {"output.html"}) + public void should_return_absolute_path_when_calculating_destination(String outputFile) throws MojoExecutionException { + // given + final AsciidoctorMojo mojo = mockAsciidoctorMojo(); + mojo.setOutputDirectory(newOutputTestDirectory("overlapping-outputFile")); + if (outputFile != null) mojo.setOutputFile(outputFile); + final File source = new File("source.adoc"); + final OptionsBuilder builder = Options.builder(); + final File sourceDir = new File("."); + + // when + Destination file = mojo.setDestinationPaths(source, builder, sourceDir, mojo); + + // then + Assertions.assertThat(file.path).isAbsolute(); + Assertions.assertThat(file.isOutput).isEqualTo(outputFile != null); + } }