From 49596df0f3b59cd22329f70ff0b7f07ebc3ebf07 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Sat, 22 Oct 2016 21:58:11 +0100 Subject: [PATCH] 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 --- .../DefaultAttributesPreprocessor.java | 5 +- .../SnippetsDirectoryResolver.java | 38 ++++++++----- .../DefaultAttributesPreprocessorTests.java | 9 ++-- .../SnippetsDirectoryResolverTests.java | 53 +++++++++++++++++-- 4 files changed, 80 insertions(+), 25 deletions(-) diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java index 7caa35f9..12ffd02a 100644 --- a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java +++ b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessor.java @@ -16,8 +16,6 @@ package org.springframework.restdocs.asciidoctor; -import java.io.File; - import org.asciidoctor.ast.Document; import org.asciidoctor.extension.Preprocessor; import org.asciidoctor.extension.PreprocessorReader; @@ -30,8 +28,7 @@ import org.asciidoctor.extension.PreprocessorReader; */ final class DefaultAttributesPreprocessor extends Preprocessor { - private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver( - new File(".")); + private final SnippetsDirectoryResolver snippetsDirectoryResolver = new SnippetsDirectoryResolver(); @Override public PreprocessorReader process(Document document, PreprocessorReader reader) { diff --git a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java index dd6829ad..4e9c53ea 100644 --- a/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java +++ b/spring-restdocs-asciidoctor/src/main/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolver.java @@ -17,6 +17,7 @@ package org.springframework.restdocs.asciidoctor; import java.io.File; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Map; @@ -30,29 +31,42 @@ import java.util.Map; */ class SnippetsDirectoryResolver { - private final File root; - - SnippetsDirectoryResolver(File root) { - this.root = root; - } - File getSnippetsDirectory(Map attributes) { - if (new File(this.root, "pom.xml").exists()) { + if (System.getProperty("maven.home") != null) { return getMavenSnippetsDirectory(attributes); } return getGradleSnippetsDirectory(attributes); } private File getMavenSnippetsDirectory(Map attributes) { - Path rootPath = Paths.get(this.root.getAbsolutePath()); - Path docDirPath = Paths.get((String) attributes.get("docdir")); - Path relativePath = docDirPath.relativize(rootPath); - return new File(relativePath.toFile(), "target/generated-snippets"); + Path docdir = Paths.get(getRequiredAttribute(attributes, "docdir")); + return new File(docdir.relativize(findPom(docdir).getParent()).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 attributes) { - return new File((String) attributes.get("projectdir"), + return new File(getRequiredAttribute(attributes, "projectdir"), "build/generated-snippets"); } + private String getRequiredAttribute(Map attributes, String name) { + String attribute = (String) attributes.get(name); + if (attribute == null || attribute.length() == 0) { + throw new IllegalStateException(name + " attribute not found"); + } + return attribute; + } + } diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java index 8903c99e..83ef4782 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/DefaultAttributesPreprocessorTests.java @@ -35,8 +35,9 @@ public class DefaultAttributesPreprocessorTests { @Test public void snippetsAttributeIsSet() { - String converted = Asciidoctor.Factory.create().convert("{snippets}", - new Options()); + Options options = new Options(); + options.setAttributes(new Attributes("projectdir=../../..")); + String converted = Asciidoctor.Factory.create().convert("{snippets}", options); assertThat(converted, containsString("build" + File.separatorChar + "generated-snippets")); } @@ -44,7 +45,7 @@ public class DefaultAttributesPreprocessorTests { @Test public void snippetsAttributeFromConvertArgumentIsNotOverridden() { 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); assertThat(converted, containsString("custom")); } @@ -52,7 +53,7 @@ public class DefaultAttributesPreprocessorTests { @Test public void snippetsAttributeFromDocumentPreambleIsNotOverridden() { Options options = new Options(); - options.setAttributes(new Attributes("snippets=custom")); + options.setAttributes(new Attributes("projectdir=../../..")); String converted = Asciidoctor.Factory.create() .convert(":snippets: custom\n{snippets}", options); assertThat(converted, containsString("custom")); diff --git a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java index f998caf4..74bbda7e 100644 --- a/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java +++ b/spring-restdocs-asciidoctor/src/test/java/org/springframework/restdocs/asciidoctor/SnippetsDirectoryResolverTests.java @@ -23,6 +23,7 @@ import java.util.Map; import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import static org.hamcrest.CoreMatchers.equalTo; @@ -39,30 +40,72 @@ public class SnippetsDirectoryResolverTests { @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder(); + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test - public void mavenProjectsUseTargetGeneratedSnippetsRelativeToDocDir() + public void mavenProjectsUseTargetGeneratedSnippetsRelativeToDocdir() throws IOException { this.temporaryFolder.newFile("pom.xml"); Map attributes = new HashMap<>(); attributes.put("docdir", new File(this.temporaryFolder.getRoot(), "src/main/asciidoc") .getAbsolutePath()); - File snippetsDirectory = new SnippetsDirectoryResolver( - this.temporaryFolder.getRoot()).getSnippetsDirectory(attributes); + File snippetsDirectory = getMavenSnippetsDirectory(attributes); assertThat(snippetsDirectory.isAbsolute(), is(false)); assertThat(snippetsDirectory, equalTo(new File("../../../target/generated-snippets"))); } + @Test + public void illegalStateExceptionWhenMavenPomCannotBeFound() throws IOException { + Map 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 attributes = new HashMap<>(); + this.thrown.expect(IllegalStateException.class); + this.thrown.expectMessage(equalTo("docdir attribute not found")); + getMavenSnippetsDirectory(attributes); + } + @Test public void gradleProjectsUseBuildGeneratedSnippetsBeneathProjectDir() throws IOException { Map attributes = new HashMap<>(); attributes.put("projectdir", "project/dir"); - File snippetsDirectory = new SnippetsDirectoryResolver( - this.temporaryFolder.getRoot()).getSnippetsDirectory(attributes); + File snippetsDirectory = new SnippetsDirectoryResolver() + .getSnippetsDirectory(attributes); assertThat(snippetsDirectory, equalTo(new File("project/dir/build/generated-snippets"))); } + @Test + public void illegalStateWhenProjectdirAttributeIsNotSetInGradleProject() + throws IOException { + Map attributes = new HashMap<>(); + this.thrown.expect(IllegalStateException.class); + this.thrown.expectMessage(equalTo("projectdir attribute not found")); + new SnippetsDirectoryResolver().getSnippetsDirectory(attributes); + } + + private File getMavenSnippetsDirectory(Map attributes) { + System.setProperty("maven.home", "/maven/home"); + try { + return new SnippetsDirectoryResolver().getSnippetsDirectory(attributes); + } + finally { + System.clearProperty("maven.home"); + } + } + }