Skip to content

Commit

Permalink
Fix calculation of baseDir in site-integration
Browse files Browse the repository at this point in the history
Calculation now takes into consideration locale and siteDirectory
correctly.
  • Loading branch information
abelsromero committed Nov 1, 2024
1 parent 72490d4 commit 8b1e904
Show file tree
Hide file tree
Showing 11 changed files with 407 additions and 199 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ For a detailed view of what has changed, refer to the {uri-repo}/commits/main[co

== Unreleased

Bug Fixes (Site Modules)::

* Fix calculation of baseDir for Doxia modules (#968)

== v3.1.0 (2024-10-30)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.asciidoctor.maven.site.SiteBaseDirResolver.resolveBaseDir;

/**
* This class is used by <a href="https://maven.apache.org/doxia/overview.html">the Doxia framework</a>
* to handle the actual parsing of the AsciiDoc input files into HTML to be consumed/wrapped
Expand Down Expand Up @@ -68,7 +70,7 @@ public void parse(Reader reader, Sink sink, String reference) throws ParseExcept

final MavenProject project = mavenProjectProvider.get();
final Xpp3Dom siteConfig = getSiteConfig(project);
final File siteDirectory = resolveSiteDirectory(project, siteConfig);
final File siteDirectory = resolveBaseDir(project.getBasedir(), siteConfig);

// Doxia handles a single instance of this class and invokes it multiple times.
// We need to ensure certain elements are initialized only once to avoid errors.
Expand Down Expand Up @@ -127,17 +129,13 @@ protected Xpp3Dom getSiteConfig(MavenProject project) {
return project.getGoalConfiguration("org.apache.maven.plugins", "maven-site-plugin", "site", "site");
}

protected File resolveSiteDirectory(MavenProject project, Xpp3Dom siteConfig) {
File siteDirectory = new File(project.getBasedir(), "src/site");
if (siteConfig != null) {
Xpp3Dom siteDirectoryNode = siteConfig.getChild("siteDirectory");
if (siteDirectoryNode != null) {
siteDirectory = new File(siteDirectoryNode.getValue());
}
}
return siteDirectory;
}

// The possible baseDir based on configuration are:
//
// with nothing : src/site + /asciidoc
// with locale : src/site + {locale} + /asciidoc
// with siteDirectory : {siteDirectory} + /asciidoc
// with siteDirectory + locale : {siteDirectory} + {locale} + /asciidoc
protected OptionsBuilder defaultOptions(File siteDirectory) {
return Options.builder()
.backend("xhtml")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

Expand All @@ -15,6 +16,7 @@
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import static org.asciidoctor.maven.site.AsciidoctorConverterDoxiaParser.ROLE_HINT;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.codehaus.plexus.util.ReflectionUtils.setVariableValueInObject;
Expand All @@ -24,43 +26,44 @@
class AsciidoctorConverterDoxiaParserTest {

private static final String TEST_DOCS_PATH = "src/test/resources/";
private static final String SAMPLE_ASCIIDOC = "sample.asciidoc";

@Test
void should_convert_html_without_any_configuration() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser();

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h1>Document Title</h1>")
.contains("<div class=\"ulist\">")
.contains("<div class=\"listingblock\">")
.contains("require 'asciidoctor'")
.contains("<div class=\"title\">Note</div>");
.contains("<h1>Document Title</h1>")
.contains("<div class=\"ulist\">")
.contains("<div class=\"listingblock\">")
.contains("require 'asciidoctor'")
.contains("<div class=\"title\">Note</div>");
}

@Test
void should_convert_html_with_an_attribute() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
Reader reader = new FileReader(srcAsciidoc);

Sink sink = createSinkMock();
AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <icons>font</icons>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <icons>font</icons>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(reader, sink);

assertThat(((TextProviderSink) sink).text)
.contains("<i class=\"fa icon-note\" title=\"Note\"></i>");
.contains("<i class=\"fa icon-note\" title=\"Note\"></i>");
}

@Test
Expand All @@ -69,18 +72,18 @@ void should_convert_html_with_baseDir_option() throws FileNotFoundException, Par
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + new File(srcAsciidoc.getParent()).getAbsolutePath() + "</baseDir>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + new File(srcAsciidoc.getParent()).getAbsolutePath() + "</baseDir>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

// 'include works'
assertThat(((TextProviderSink) sink).text)
.contains("<h1>Include test</h1>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"");
.contains("<h1>Include test</h1>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"");
}

@Test
Expand All @@ -89,39 +92,39 @@ void should_convert_html_with_relative_baseDir_option() throws FileNotFoundExcep
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + TEST_DOCS_PATH + "</baseDir>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + TEST_DOCS_PATH + "</baseDir>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

// 'include works'
assertThat(((TextProviderSink) sink).text)
.contains("<h1>Include test</h1>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"");
.contains("<h1>Include test</h1>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"");
}

@Test
void should_convert_html_with_templateDir_option() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <templateDirs>\n" +
" <dir>" + TEST_DOCS_PATH + "/templates</dir>\n" +
" </templateDirs>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <templateDirs>\n" +
" <dir>" + TEST_DOCS_PATH + "/templates</dir>\n" +
" </templateDirs>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h1>Document Title</h1>")
.contains("<p class=\"custom-template \">");
.contains("<h1>Document Title</h1>")
.contains("<p class=\"custom-template \">");
}

@Test
Expand All @@ -130,68 +133,92 @@ void should_convert_html_with_attributes_and_baseDir_option() throws FileNotFoun
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + new File(srcAsciidoc.getParent()).getAbsolutePath() + "</baseDir>\n" +
" <attributes>\n" +
" <sectnums></sectnums>\n" +
" <icons>font</icons>\n" +
" <my-label>Hello World!!</my-label>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <baseDir>" + new File(srcAsciidoc.getParent()).getAbsolutePath() + "</baseDir>\n" +
" <attributes>\n" +
" <sectnums></sectnums>\n" +
" <icons>font</icons>\n" +
" <my-label>Hello World!!</my-label>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h1>Include test</h1>")
.contains("<h2 id=\"code\">1. Code</h2>")
.contains("<h2 id=\"optional_section\">2. Optional section</h2>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"")
.contains("Hello World!!")
.contains("<i class=\"fa icon-tip\" title=\"Tip\"></i>");
.contains("<h1>Include test</h1>")
.contains("<h2 id=\"code\">1. Code</h2>")
.contains("<h2 id=\"optional_section\">2. Optional section</h2>")
.contains("println \"HelloWorld from Groovy on ${new Date()}\"")
.contains("Hello World!!")
.contains("<i class=\"fa icon-tip\" title=\"Tip\"></i>");
}

@Test
void should_convert_html_in_locale_path() throws IOException, ParseException {
final String localeSourceDir = TEST_DOCS_PATH + "with-locale/";
final File srcAsciidoc = new File(localeSourceDir + "en/" + ROLE_HINT, "sample.adoc");
Reader reader = new FileReader(srcAsciidoc);

Sink sink = createSinkMock();
AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <siteDirectory>" + localeSourceDir + "</siteDirectory>\n" +
" <locales>en</locales>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <icons>font</icons>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(reader, sink);

assertThat(((TextProviderSink) sink).text)
.contains("This has been included");
}

@Test
void should_process_empty_selfclosing_XML_attributes() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <sectnums/>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <sectnums/>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h2 id=\"id_section_a\">1. Section A</h2>")
.contains("<h3 id=\"id_section_a_subsection\">1.1. Section A Subsection</h3>");
.contains("<h2 id=\"id_section_a\">1. Section A</h2>")
.contains("<h3 id=\"id_section_a_subsection\">1.1. Section A Subsection</h3>");
}

@Test
void should_process_empty_value_XML_attributes() throws FileNotFoundException, ParseException {
final File srcAsciidoc = new File(TEST_DOCS_PATH, "sample.asciidoc");
final File srcAsciidoc = new File(TEST_DOCS_PATH, SAMPLE_ASCIIDOC);
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <sectnums></sectnums>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <attributes>\n" +
" <sectnums></sectnums>\n" +
" </attributes>\n" +
" </asciidoc>\n" +
"</configuration>");

parser.parse(new FileReader(srcAsciidoc), sink);

assertThat(((TextProviderSink) sink).text)
.contains("<h2 id=\"id_section_a\">1. Section A</h2>")
.contains("<h3 id=\"id_section_a_subsection\">1.1. Section A Subsection</h3>");
.contains("<h2 id=\"id_section_a\">1. Section A</h2>")
.contains("<h3 id=\"id_section_a_subsection\">1.1. Section A Subsection</h3>");
}

@Test
Expand All @@ -200,32 +227,32 @@ void should_fail_when_logHandler_failIf_is_WARNING() {
final Sink sink = createSinkMock();

AsciidoctorConverterDoxiaParser parser = mockAsciidoctorDoxiaParser(
"<configuration>\n" +
" <asciidoc>\n" +
" <logHandler>\n" +
" <!-- <outputToConsole>false</outputToConsole> -->\n" +
" <failIf>\n" +
" <severity>WARN</severity>\n" +
" </failIf>\n" +
" </logHandler>\n" +
" </asciidoc>\n" +
"</configuration>");
"<configuration>\n" +
" <asciidoc>\n" +
" <logHandler>\n" +
" <!-- <outputToConsole>false</outputToConsole> -->\n" +
" <failIf>\n" +
" <severity>WARN</severity>\n" +
" </failIf>\n" +
" </logHandler>\n" +
" </asciidoc>\n" +
"</configuration>");

Throwable throwable = catchThrowable(() -> parser.parse(new FileReader(srcAsciidoc), sink));

// 'issues with WARN and ERROR are returned'
assertThat(throwable)
.isInstanceOf(org.apache.maven.doxia.parser.ParseException.class)
.hasMessageContaining("Found 4 issue(s) of severity WARN or higher during conversion");
.isInstanceOf(org.apache.maven.doxia.parser.ParseException.class)
.hasMessageContaining("Found 4 issue(s) of severity WARN or higher during conversion");
}

@SneakyThrows
private javax.inject.Provider<MavenProject> createMavenProjectMock(String configuration) {
MavenProject mockProject = Mockito.mock(MavenProject.class);
when(mockProject.getBasedir())
.thenReturn(new File("."));
.thenReturn(new File("."));
when(mockProject.getGoalConfiguration(anyString(), anyString(), anyString(), anyString()))
.thenReturn(configuration != null ? Xpp3DomBuilder.build(new StringReader(configuration)) : null);
.thenReturn(configuration != null ? Xpp3DomBuilder.build(new StringReader(configuration)) : null);

return () -> mockProject;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
== Included section

This has been included.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
= Document Title

== Include

include::included.adoc[]
Loading

0 comments on commit 8b1e904

Please sign in to comment.