Make snippet directory resolution more robust

The previous approach had (at least) two problems:

 - A Gradle build run from a directory that also contains a pom.xml
   would result in the resolver incorrectly identifing that Maven was
   being used
 - A Maven build run from a directory that did not could a pom and
   that used -f to provide the path to a pom would result in the
   resolver incorretly indentifying that Gradle was being used

With this commit, the resolver now uses the presence of the maven.home
system property to identify that Maven is being used. When Maven
is being used, rather than looking for a pom.xml in the working
directory, the resolver now locates the pom.xml by searching up the
directory hierarchy from the docdir.

Closes gh-297
This commit is contained in:
Andy Wilkinson
2016-10-22 21:58:11 +01:00
parent c13b7d03f5
commit 49596df0f3
4 changed files with 80 additions and 25 deletions

View File

@@ -16,8 +16,6 @@
package org.springframework.restdocs.asciidoctor; package org.springframework.restdocs.asciidoctor;
import java.io.File;
import org.asciidoctor.ast.Document; import org.asciidoctor.ast.Document;
import org.asciidoctor.extension.Preprocessor; import org.asciidoctor.extension.Preprocessor;
import org.asciidoctor.extension.PreprocessorReader; import org.asciidoctor.extension.PreprocessorReader;
@@ -30,8 +28,7 @@ import org.asciidoctor.extension.PreprocessorReader;
*/ */
final class DefaultAttributesPreprocessor extends Preprocessor { final class DefaultAttributesPreprocessor extends Preprocessor {
private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver( private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver();
new File("."));
@Override @Override
public PreprocessorReader process(Document document, PreprocessorReader reader) { public PreprocessorReader process(Document document, PreprocessorReader reader) {

View File

@@ -17,6 +17,7 @@
package org.springframework.restdocs.asciidoctor; package org.springframework.restdocs.asciidoctor;
import java.io.File; import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Map; import java.util.Map;
@@ -30,29 +31,42 @@ import java.util.Map;
*/ */
class SnippetsDirectoryResolver { class SnippetsDirectoryResolver {
private final File root;
SnippetsDirectoryResolver(File root) {
this.root = root;
}
File getSnippetsDirectory(Map<String, Object> attributes) { File getSnippetsDirectory(Map<String, Object> attributes) {
if (new File(this.root, "pom.xml").exists()) { if (System.getProperty("maven.home") != null) {
return getMavenSnippetsDirectory(attributes); return getMavenSnippetsDirectory(attributes);
} }
return getGradleSnippetsDirectory(attributes); return getGradleSnippetsDirectory(attributes);
} }
private File getMavenSnippetsDirectory(Map<String, Object> attributes) { private File getMavenSnippetsDirectory(Map<String, Object> attributes) {
Path rootPath = Paths.get(this.root.getAbsolutePath()); Path docdir = Paths.get(getRequiredAttribute(attributes, "docdir"));
Path docDirPath = Paths.get((String) attributes.get("docdir")); return new File(docdir.relativize(findPom(docdir).getParent()).toFile(),
Path relativePath = docDirPath.relativize(rootPath); "target/generated-snippets");
return new File(relativePath.toFile(), "target/generated-snippets"); }
private Path findPom(Path docdir) {
Path path = docdir;
while (path != null) {
Path pom = path.resolve("pom.xml");
if (Files.isRegularFile(pom)) {
return pom;
}
path = path.getParent();
}
throw new IllegalStateException("pom.xml not found in '" + docdir + "' or above");
} }
private File getGradleSnippetsDirectory(Map<String, Object> attributes) { private File getGradleSnippetsDirectory(Map<String, Object> attributes) {
return new File((String) attributes.get("projectdir"), return new File(getRequiredAttribute(attributes, "projectdir"),
"build/generated-snippets"); "build/generated-snippets");
} }
private String getRequiredAttribute(Map<String, Object> attributes, String name) {
String attribute = (String) attributes.get(name);
if (attribute == null || attribute.length() == 0) {
throw new IllegalStateException(name + " attribute not found");
}
return attribute;
}
} }

View File

@@ -35,8 +35,9 @@ public class DefaultAttributesPreprocessorTests {
@Test @Test
public void snippetsAttributeIsSet() { public void snippetsAttributeIsSet() {
String converted = Asciidoctor.Factory.create().convert("{snippets}", Options options = new Options();
new Options()); options.setAttributes(new Attributes("projectdir=../../.."));
String converted = Asciidoctor.Factory.create().convert("{snippets}", options);
assertThat(converted, assertThat(converted,
containsString("build" + File.separatorChar + "generated-snippets")); containsString("build" + File.separatorChar + "generated-snippets"));
} }
@@ -44,7 +45,7 @@ public class DefaultAttributesPreprocessorTests {
@Test @Test
public void snippetsAttributeFromConvertArgumentIsNotOverridden() { public void snippetsAttributeFromConvertArgumentIsNotOverridden() {
Options options = new Options(); Options options = new Options();
options.setAttributes(new Attributes("snippets=custom")); options.setAttributes(new Attributes("snippets=custom projectdir=../../.."));
String converted = Asciidoctor.Factory.create().convert("{snippets}", options); String converted = Asciidoctor.Factory.create().convert("{snippets}", options);
assertThat(converted, containsString("custom")); assertThat(converted, containsString("custom"));
} }
@@ -52,7 +53,7 @@ public class DefaultAttributesPreprocessorTests {
@Test @Test
public void snippetsAttributeFromDocumentPreambleIsNotOverridden() { public void snippetsAttributeFromDocumentPreambleIsNotOverridden() {
Options options = new Options(); Options options = new Options();
options.setAttributes(new Attributes("snippets=custom")); options.setAttributes(new Attributes("projectdir=../../.."));
String converted = Asciidoctor.Factory.create() String converted = Asciidoctor.Factory.create()
.convert(":snippets: custom\n{snippets}", options); .convert(":snippets: custom\n{snippets}", options);
assertThat(converted, containsString("custom")); assertThat(converted, containsString("custom"));

View File

@@ -23,6 +23,7 @@ import java.util.Map;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
@@ -39,30 +40,72 @@ public class SnippetsDirectoryResolverTests {
@Rule @Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder(); public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test @Test
public void mavenProjectsUseTargetGeneratedSnippetsRelativeToDocDir() public void mavenProjectsUseTargetGeneratedSnippetsRelativeToDocdir()
throws IOException { throws IOException {
this.temporaryFolder.newFile("pom.xml"); this.temporaryFolder.newFile("pom.xml");
Map<String, Object> attributes = new HashMap<>(); Map<String, Object> attributes = new HashMap<>();
attributes.put("docdir", attributes.put("docdir",
new File(this.temporaryFolder.getRoot(), "src/main/asciidoc") new File(this.temporaryFolder.getRoot(), "src/main/asciidoc")
.getAbsolutePath()); .getAbsolutePath());
File snippetsDirectory = new SnippetsDirectoryResolver( File snippetsDirectory = getMavenSnippetsDirectory(attributes);
this.temporaryFolder.getRoot()).getSnippetsDirectory(attributes);
assertThat(snippetsDirectory.isAbsolute(), is(false)); assertThat(snippetsDirectory.isAbsolute(), is(false));
assertThat(snippetsDirectory, assertThat(snippetsDirectory,
equalTo(new File("../../../target/generated-snippets"))); equalTo(new File("../../../target/generated-snippets")));
} }
@Test
public void illegalStateExceptionWhenMavenPomCannotBeFound() throws IOException {
Map<String, Object> attributes = new HashMap<>();
String docdir = new File(this.temporaryFolder.getRoot(), "src/main/asciidoc")
.getAbsolutePath();
attributes.put("docdir", docdir);
this.thrown.expect(IllegalStateException.class);
this.thrown
.expectMessage(equalTo("pom.xml not found in '" + docdir + "' or above"));
getMavenSnippetsDirectory(attributes);
}
@Test
public void illegalStateWhenDocdirAttributeIsNotSetInMavenProject()
throws IOException {
Map<String, Object> attributes = new HashMap<>();
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage(equalTo("docdir attribute not found"));
getMavenSnippetsDirectory(attributes);
}
@Test @Test
public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectDir() public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectDir()
throws IOException { throws IOException {
Map<String, Object> attributes = new HashMap<>(); Map<String, Object> attributes = new HashMap<>();
attributes.put("projectdir", "project/dir"); attributes.put("projectdir", "project/dir");
File snippetsDirectory = new SnippetsDirectoryResolver( File snippetsDirectory = new SnippetsDirectoryResolver()
this.temporaryFolder.getRoot()).getSnippetsDirectory(attributes); .getSnippetsDirectory(attributes);
assertThat(snippetsDirectory, assertThat(snippetsDirectory,
equalTo(new File("project/dir/build/generated-snippets"))); equalTo(new File("project/dir/build/generated-snippets")));
} }
@Test
public void illegalStateWhenProjectdirAttributeIsNotSetInGradleProject()
throws IOException {
Map<String, Object> attributes = new HashMap<>();
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage(equalTo("projectdir attribute not found"));
new SnippetsDirectoryResolver().getSnippetsDirectory(attributes);
}
private File getMavenSnippetsDirectory(Map<String, Object> attributes) {
System.setProperty("maven.home", "/maven/home");
try {
return new SnippetsDirectoryResolver().getSnippetsDirectory(attributes);
}
finally {
System.clearProperty("maven.home");
}
}
} }