Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace usage of jruby DirectoryWalker with Java NIO API (#532) #535

Merged
merged 4 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Maintenance::
* Rewrite `AsciidoctorHttpMojoTest` to Java to make it more approachable (#516)
* Rewrite `AsciidoctorZipMojoTest` to Java to make it more approachable (#518)
* Rewrite `AsciidoctorDoxiaParserTest` to Java + remove Groovy & Spock configurations (#519)
* Replace usage of internal Asciidoctorj `DirectoryWalker` with Java NIO API (https://github.com/stdll[@stdll]) (#532)

== v2.1.0 (2020-09-15)

Expand Down
16 changes: 7 additions & 9 deletions src/main/java/org/asciidoctor/maven/AsciidoctorMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
import org.apache.maven.shared.filtering.MavenResourcesExecution;
import org.apache.maven.shared.filtering.MavenResourcesFiltering;
import org.asciidoctor.*;
import org.asciidoctor.jruby.AsciiDocDirectoryWalker;
import org.asciidoctor.jruby.AsciidoctorJRuby;
import org.asciidoctor.jruby.DirectoryWalker;
import org.asciidoctor.jruby.internal.JRubyRuntimeContext;
import org.asciidoctor.maven.extensions.AsciidoctorJExtensionRegistry;
import org.asciidoctor.maven.extensions.ExtensionConfiguration;
Expand All @@ -25,14 +23,15 @@
import org.asciidoctor.maven.log.LogRecordsProcessors;
import org.asciidoctor.maven.log.MemoryLogHandler;
import org.asciidoctor.maven.process.AsciidoctorHelper;
import org.asciidoctor.maven.process.CustomExtensionDirectoryWalker;
import org.asciidoctor.maven.process.ResourcesProcessor;
import org.asciidoctor.maven.process.SourceDirectoryFinder;
import org.asciidoctor.maven.process.SourceDocumentFinder;
import org.jruby.Ruby;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.*;
import java.util.logging.Logger;

Expand Down Expand Up @@ -440,13 +439,12 @@ protected List<File> calculateSourceFiles(File sourceDirectory) {
if (sourceDocumentName != null)
return Arrays.asList(new File(sourceDirectory, sourceDocumentName));

// Both DirectoryWalkers filter out internal sources and path (_ prefix)
final String sourceDirectoryAbsolutePath = sourceDirectory.getAbsolutePath();
final DirectoryWalker directoryWalker = sourceDocumentExtensions.isEmpty()
? new AsciiDocDirectoryWalker(sourceDirectoryAbsolutePath)
: new CustomExtensionDirectoryWalker(sourceDirectoryAbsolutePath, sourceDocumentExtensions);
Path sourceDirectoryPath = sourceDirectory.toPath();
SourceDocumentFinder finder = new SourceDocumentFinder();

return directoryWalker.scan();
return sourceDocumentExtensions.isEmpty() ?
finder.find(sourceDirectoryPath) :
finder.find(sourceDirectoryPath, sourceDocumentExtensions);
}

protected void convertFile(Asciidoctor asciidoctor, Map<String, Object> options, File f) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.asciidoctor.maven.process;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Finds all source documents inside a source directory.
* It traverses the source directory and all subdirectories. It can match custom file extensions.
* If none are specified, it matches <code>.asc</code>, <code>.asciidoc</code>, <code>.ad</code> and <code>.adoc</code>.
* Files and directories starting with an underscore (<code>_</code>) are ignored.
*
* @author stdll
*/
public class SourceDocumentFinder {

/** Pattern for matching standard file extensions. */
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 = "^[^_.].*\\.(";

/** Suffix for matching custom file extensions. */
private static final String CUSTOM_FILE_EXTENSIONS_PATTERN_SUFFIX = ")$";

/**
* Finds all source documents inside the source directory with standard file extensions.
*
* @param sourceDirectory source directory
* @return the list of all matching source documents.
*/
public List<File> find(Path sourceDirectory) {
return find(sourceDirectory, Pattern.compile(STANDARD_FILE_EXTENSIONS_PATTERN));
}

/**
* Finds all source documents inside the source directory with custom file extensions.
*
* @param sourceDirectory source directory
* @param sourceDocumentExtensions custom file extensions
* @return the list of all matching source documents.
*/
public List<File> find(Path sourceDirectory, List<String> sourceDocumentExtensions) {
String extensionPattern = sourceDocumentExtensions.stream().collect(Collectors
.joining("|", CUSTOM_FILE_EXTENSIONS_PATTERN_PREFIX, CUSTOM_FILE_EXTENSIONS_PATTERN_SUFFIX));
return find(sourceDirectory, Pattern.compile(extensionPattern));
}

private List<File> find(Path sourceDirectory, Pattern sourceDocumentPattern) {
try (Stream<Path> sourceDocumentCandidates = Files.walk(sourceDirectory)) {
return sourceDocumentCandidates.filter(Files::isRegularFile)
// Filter all documents that don't match the file extension pattern.
.filter(p -> sourceDocumentPattern.matcher(p.getFileName().toString()).matches())
// Filter all documents that are part of ignored directories.
.filter(p -> {
for (Path part : p) {
if (part.toString().startsWith("_")) {
return false;
}
}
return true;
}).map(Path::toFile).collect(Collectors.toList());
} catch (IOException e) {
// Can't access the source directory.
return Collections.emptyList();
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package org.asciidoctor.maven.process;

import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class SourceDocumentFinderTest {
stdll marked this conversation as resolved.
Show resolved Hide resolved

private static final String DEFAULT_SOURCE_DIRECTORY = "src/test/resources/src/asciidoctor";

@Test
public void should_init_SourceDocumentFinder() {
// when
SourceDocumentFinder walker = new SourceDocumentFinder();
// then
assertThat(walker).isNotNull();
}

@Test
public void should_match_standard_file_extensions() {
// given
final String rootDirectory = DEFAULT_SOURCE_DIRECTORY + "/file-extensions";

// when
List<File> files = new SourceDocumentFinder().find(Paths.get(rootDirectory));

// then
assertThat(files)
.isNotEmpty()
.map(File::getName)
.allMatch(name -> name.endsWith("ad") || name.endsWith("adoc") || name.endsWith("asc") ||
name.endsWith("asciidoc"));
}

@Test
public void should_match_custom_file_extension() {
// given
final String rootDirectory = DEFAULT_SOURCE_DIRECTORY + "/file-extensions";

// when
List<File> files = new SourceDocumentFinder().find(Paths.get(rootDirectory), Collections.singletonList("my-adoc"));

// then
assertThat(files)
.isNotEmpty()
.allMatch(file -> file.getName().endsWith("my-adoc"));
}

@Test
public void should_match_custom_file_extensions() {
// given
final String rootDirectory = DEFAULT_SOURCE_DIRECTORY + "/file-extensions";
List<String> customFileExtensions = new ArrayList<>();
customFileExtensions.add("my-adoc");
customFileExtensions.add("adoc");

// when
List<File> files = new SourceDocumentFinder().find(Paths.get(rootDirectory), customFileExtensions);

// then
assertThat(files)
.isNotEmpty()
.map(File::getName)
.allMatch(name -> name.endsWith("my-adoc") || name.endsWith("adoc"));
}

@Test
public void should_not_match_custom_empty_file_extensions() {
// given
final String rootDirectory = DEFAULT_SOURCE_DIRECTORY + "/file-extensions";

// when
List<File> files = new SourceDocumentFinder().find(Paths.get(rootDirectory), Collections.emptyList());

// then
assertThat(files)
.isEmpty();
}

@Test
public void should_return_empty_list_if_wrong_source_directory() {
// given
final String rootDirectory = DEFAULT_SOURCE_DIRECTORY + "/file-extensions/non-existing";

// when
List<File> files = new SourceDocumentFinder().find(Paths.get(rootDirectory));

// then
assertThat(files)
.isEmpty();
}

@Test
public void should_exclude_internal_sources() {
// given
final String rootDirectory = DEFAULT_SOURCE_DIRECTORY + "/relative-path-treatment";
final List<String> fileExtensions = Collections.singletonList("adoc");

// when
List<File> files = new SourceDocumentFinder().find(Paths.get(rootDirectory), fileExtensions);

// then
assertThat(files)
.isNotEmpty()
.allMatch(file -> !file.getName().startsWith("_"));
}

@Test
public void should_exclude_internal_directories() {
// given
final String rootDirectory = DEFAULT_SOURCE_DIRECTORY + "/relative-path-treatment";
final List<String> fileExtensions = Collections.singletonList("adoc");

// when
List<File> files = new SourceDocumentFinder().find(Paths.get(rootDirectory), fileExtensions);

// then
assertThat(files)
.isNotEmpty()
.allMatch(file -> !isContainedInInternalDirectory(file));
}

private boolean isContainedInInternalDirectory(File file) {
final String path = file.getPath();
int cursor = 0;
do {
cursor = path.indexOf(File.separator, cursor + 1);
if (path.charAt(cursor + 1) == '_')
return true;
} while (cursor != -1);
return false;
}
}
28 changes: 28 additions & 0 deletions src/test/resources/src/asciidoctor/file-extensions/sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Document Title
==============
Doc Writer <thedoc@asciidoctor.org>
:idprefix: id_

Preamble paragraph.

NOTE: This is test, only a test.

== Section A

*Section A* paragraph.

=== Section A Subsection

*Section A* 'subsection' paragraph.

== Section B

*Section B* paragraph.

.Section B list
* Item 1
* Item 2
* Item 3

[source,ruby]
require 'asciidoctor'
Loading