未验证 提交 9af41498 编写于 作者: J Joffrey Bion 提交者: GitHub

Add SchemaFinder to enable directory support in maven/gradle plugins (#32)

Resolves:
https://github.com/kobylynskyi/graphql-java-codegen/issues/30Co-authored-by: NJoffrey Bion <joffrey.bion@booking.com>
上级 de08b9e2
package com.kobylynskyi.graphql.codegen.supplier;
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.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Walks a directory tree to find GraphQL schema files.
*/
public class SchemaFinder {
public static final String DEFAULT_INCLUDE_PATTERN = ".*\\.graphqls";
public static final boolean DEFAULT_RECURSIVE = true;
private final Path rootDir;
private boolean recursive = DEFAULT_RECURSIVE;
private Pattern includePattern = Pattern.compile(DEFAULT_INCLUDE_PATTERN);
private Set<Path> excludedFiles = Collections.emptySet();
/**
* Creates a new SchemaFinder with the given directory as root of the search.
*
* @param rootDir
* the starting directory of the search. Must not be null.
*/
public SchemaFinder(Path rootDir) {
if (rootDir == null) {
throw new IllegalArgumentException("rootDir is required for schema search");
}
this.rootDir = rootDir;
}
/**
* Sets whether the file search should be recursive.
*/
public void setRecursive(boolean recursive) {
this.recursive = recursive;
}
/**
* Sets the Java pattern that filenames should match to be included in the result. Matching files are only included
* if they're not part of the excluded files.
*
* @see #setExcludedFiles(Set)
*/
public void setIncludePattern(String includePattern) {
this.includePattern = Pattern.compile(includePattern);
}
/**
* Sets a set of paths to exclude from the search even if they match the include pattern. The provided paths are
* either absolute or relative to the root directory provided in the constructor.
*
* @see #setIncludePattern(String)
*/
public void setExcludedFiles(Set<String> excludedFiles) {
this.excludedFiles = excludedFiles.stream().map(rootDir::resolve).collect(Collectors.toSet());
}
/**
* Walks the directory tree starting at the root provided in the constructor to find GraphQL schemas.
*
* @return an alphabetically-sorted list of file paths matching the current configuration
*
* @throws IOException
* if any I/O error occurs while reading the file system
*/
public List<String> findSchemas() throws IOException {
int maxDepth = recursive ? Integer.MAX_VALUE : 1;
try (Stream<Path> paths = Files.find(rootDir, maxDepth, (path, attrs) -> shouldInclude(path))) {
return paths.map(Path::toString).sorted().collect(Collectors.toList());
}
}
private boolean shouldInclude(Path path) {
if (Files.isDirectory(path)) {
return false;
}
if (excludedFiles.contains(path)) {
return false;
}
String filename = path.getFileName().toString();
return includePattern.matcher(filename).matches();
}
}
package com.kobylynskyi.graphql.codegen.supplier;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class SchemaFinderTest {
private Path root;
@BeforeEach
public void setup() throws IOException {
root = Files.createTempDirectory("test-schema");
root.toFile().deleteOnExit();
}
@Test
public void nullRootDir_fails() {
assertThrows(IllegalArgumentException.class, () -> new SchemaFinder(null));
}
@Test
public void absentRootDir_fails() {
SchemaFinder finder = new SchemaFinder(Paths.get("does-not-exist"));
assertThrows(NoSuchFileException.class, finder::findSchemas);
}
@Test
public void emptyRootDir() throws IOException {
SchemaFinder finder = new SchemaFinder(root);
assertEquals(Collections.emptyList(), finder.findSchemas());
}
@Test
public void emptyRootDir_nonRecursive() throws IOException {
SchemaFinder finder = new SchemaFinder(root);
finder.setRecursive(false);
assertEquals(Collections.emptyList(), finder.findSchemas());
}
@Test
public void singleFile_matchesDefaultRegex() throws IOException {
Path singleFile = Files.createFile(root.resolve("single.graphqls"));
SchemaFinder finder = new SchemaFinder(root);
List<String> expected = Collections.singletonList(singleFile.toString());
assertEquals(expected, finder.findSchemas());
}
@Test
public void singleFile_matchesCustomRegex() throws IOException {
Path singleFile = Files.createFile(root.resolve("my-file.txt"));
SchemaFinder finder = new SchemaFinder(root);
finder.setIncludePattern("my-.*\\.txt");
List<String> expected = Collections.singletonList(singleFile.toString());
assertEquals(expected, finder.findSchemas());
}
@Test
public void singleFile_filteredOutByRegex() throws IOException {
Files.createFile(root.resolve("not-a-match.txt"));
SchemaFinder finder = new SchemaFinder(root);
finder.setIncludePattern("very-specific-regex");
assertEquals(Collections.emptyList(), finder.findSchemas());
}
@Test
public void singleFile_filteredOutByRelativeExclude() throws IOException {
String excludedFilename = "excluded.txt";
Files.createFile(root.resolve(excludedFilename));
SchemaFinder finder = new SchemaFinder(root);
finder.setExcludedFiles(Collections.singleton(excludedFilename));
assertEquals(Collections.emptyList(), finder.findSchemas());
}
@Test
public void singleFile_filteredOutByAbsoluteExclude() throws IOException {
Path excludedFilePath = root.resolve("excluded.txt").toAbsolutePath();
Files.createFile(excludedFilePath);
SchemaFinder finder = new SchemaFinder(root);
finder.setExcludedFiles(Collections.singleton(excludedFilePath.toString()));
assertEquals(Collections.emptyList(), finder.findSchemas());
}
@Test
public void multipleFiles_shouldBeInAlphabeticalOrder() throws IOException {
Path file1 = Files.createFile(root.resolve("file1.good"));
Path file3 = Files.createFile(root.resolve("file3.good"));
Path file2 = Files.createFile(root.resolve("file2.good"));
List<String> expected = Arrays.asList(file1.toString(), file2.toString(), file3.toString());
SchemaFinder finder = new SchemaFinder(root);
finder.setIncludePattern("file\\d\\.good");
assertEquals(expected, finder.findSchemas());
}
@Test
public void multipleFiles_withRegexFilter() throws IOException {
Path singleFile = Files.createFile(root.resolve("abc.good"));
Files.createFile(root.resolve("abc.bad"));
List<String> expected = Collections.singletonList(singleFile.toString());
SchemaFinder finder = new SchemaFinder(root);
finder.setIncludePattern(".*\\.good");
assertEquals(expected, finder.findSchemas());
}
@Test
public void multipleFiles_withExclude() throws IOException {
Path singleFile = Files.createFile(root.resolve("abc.good"));
String excludedFilename = "excluded.good";
Files.createFile(root.resolve(excludedFilename));
List<String> expected = Collections.singletonList(singleFile.toString());
SchemaFinder finder = new SchemaFinder(root);
finder.setIncludePattern(".*\\.good");
finder.setExcludedFiles(Collections.singleton(excludedFilename));
assertEquals(expected, finder.findSchemas());
}
@Test
public void nestedDir_recursive() throws IOException {
Path rootFile = Files.createFile(root.resolve("abc.good"));
Path dir1 = Files.createDirectory(root.resolve("dir1"));
Path dir1File = Files.createFile(dir1.resolve("file1.good"));
SchemaFinder finder = new SchemaFinder(root);
finder.setIncludePattern(".*\\.good");
finder.setRecursive(true);
List<String> expectedRec = Arrays.asList(rootFile.toString(), dir1File.toString());
assertEquals(expectedRec, finder.findSchemas());
}
@Test
public void nestedDir_nonRecursive() throws IOException {
Path rootFile = Files.createFile(root.resolve("abc.good"));
Path dir1 = Files.createDirectory(root.resolve("dir1"));
Files.createFile(dir1.resolve("file1.good"));
SchemaFinder finder = new SchemaFinder(root);
finder.setIncludePattern(".*\\.good");
finder.setRecursive(false);
List<String> expected = Collections.singletonList(rootFile.toString());
assertEquals(expected, finder.findSchemas());
}
@Test
public void nestedDir_mixedCases() throws IOException {
Path rootFile = Files.createFile(root.resolve("abc.good"));
Path dir1 = Files.createDirectory(root.resolve("dir1"));
Path dir2 = Files.createDirectory(root.resolve("dir2"));
Files.createFile(root.resolve("abc.bad"));
Files.createFile(root.resolve("excluded1.good"));
// inside dir1 (mix subdirs, good files, bad files)
Path dir1File = Files.createFile(dir1.resolve("file1.good"));
Path subdir = Files.createDirectory(dir1.resolve("subdir"));
Files.createDirectory(dir1.resolve("empty")); // empty subdir
Files.createFile(dir1.resolve("abc.bad"));
// inside dir1/subdir (only good files)
Path subdirFile = Files.createFile(subdir.resolve("subdirFile.good"));
// inside dir2 (only bad files)
Files.createFile(dir2.resolve("abc.bad"));
Files.createFile(dir2.resolve("excluded2.good"));
List<String> expected = Collections.singletonList(rootFile.toString());
SchemaFinder finder = new SchemaFinder(root);
finder.setIncludePattern(".*\\.good");
finder.setExcludedFiles(new HashSet<>(Arrays.asList("excluded1.good", "dir2/excluded2.good")));
finder.setRecursive(false);
assertEquals(expected, finder.findSchemas());
List<String> expectedRec = Arrays.asList(rootFile.toString(), dir1File.toString(), subdirFile.toString());
finder.setRecursive(true);
assertEquals(expectedRec, finder.findSchemas());
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册