A Java library providing glob pattern matching traversal of the file system. In addition to pattern matching, Git ignore files can be honored.
The library is available from Maven Central using the following Maven dependency:
<dependency>
<groupId>org.cthing</groupId>
<artifactId>filevisitor</artifactId>
<version>2.0.0</version>
</dependency>or the following Gradle dependency:
implementation("org.cthing:filevisitor:2.0.0")In a similar manner to Files.walkFileTree,
the MatchingTreeWalker will traverse the file system starting at the specified directory. The walker will attempt
to match files and directories against the patterns specified (see Pattern Matching Syntax).
Specify an implementation of the MatchHandler interface to process the matched files and directories. The following
example looks for all Java files:
final MatchHandler handler = new MyMatchHandler();
final MatchingTreeWalker walker = new MatchingTreeWalker(start, handler, "**/*.java");
walker.walk();To use Files.walkFileTree
directly, specify an instance of the MatchingFileVisitor. The equivalent to the above example is:
final MatchHandler handler = new MyMatchHandler();
final MatchingFileVisitor visitor = new MatchingFileVisitor(handler, "**/*.java");
Files.walkFileTree(start, visitor);To obtain a list of all matched files and directories, use the CollectingMatchHandler.
final CollectingMatchHandler handler = new CollectingMatchHandler();
new MatchingTreeWalker(start, handler, "**/*.java").walk();
final List<Path> matchedPaths = handler.getPaths();To obtain a list of only matched files:
final CollectingMatchHandler handler = new CollectingMatchHandler(false);
new MatchingTreeWalker(start, handler, "**/*.java").walk();
final List<Path> matchedPaths = handler.getPaths();Patterns to match files and directories use the Git ignore
glob syntax. Note that unlike Git ignore globs, which indicate the files and directories to exclude, in this
library, they indicate the files and directories to include. For example, specifying **/*.java includes
all Java files in any directory. To exclude files and directories, use the "!" negation prefix. Below is summary
of the glob syntax. See the Git ignore documentation for a
detailed explanation.
- Blank lines are ignored
- Lines starting with "#" are comments
- A "!" prefix negates the pattern
- A "" escapes special characters (e.g. to use a "#" character, specify "\#")
- A "/" is used as the directory separator regardless of the platform
- A "/" at the end of the pattern only matches directories
- Relative paths are resolved against the starting directory of the traversal
- A "*" matches anything except a slash
- A "?" matches any one character except a slash
- Range notation (e.g. "[a-zA-Z]") can be used to match one character in that range
- A leading "*/" (e.g. "*/foo") matches in all directories
- A trailing "/**" (e.g. "foo/**") matches everything inside
- A slash followed by two consecutive asterisks followed by a slash (e.g. "a/**/b") matches zero or more directories
By default, file tree traversal respects Git ignore files. If the start directory is anywhere within a Git work tree, any Git ignore files will be used to exclude files from matching. Global Git ignore files are also considered. Git ignore files have the same precedence as they do in Git. User specified match patterns have higher precedence than Git ignore patterns.
To disable the use of Git ignore files, call the MatchingTreeWalker.respectGitignore or
MatchingFileVisitor.respectGitignore method with false.
Hidden Files
By default, file tree traversal ignores hidden files and directories. To include hidden files and directories, call
the MatchingTreeWalker.excludeHidden or MatchingFileVisitor.excludeHidden method with false.
By default, the MatchingTreeWalker does not follow symbolic links. To follow symbolic links, call the
MatchingTreeWalker.followLinks method with true.
By default, the MatchingTreeWalker performs a depth first traversal of the entire file tree under the starting
directory. To restrict the traversal to a specific depth, call the MatchingTreeWalker.maxDepth method. Specify,
Integer.MAX_VALUE for unlimited depth.
The glob and Git ignore pattern parsing and matching in this library is based on the Rust code in the ripgrep project's globset and ignore crates covered by the Unlicense (i.e. public domain).
The Git config file parser is a heavily modified copy of the Config class from the Eclipse JGitTM project and is covered by the EDL license.
The library is compiled for Java 17. If a Java 17 toolchain is not available, one will be downloaded.
Gradle is used to build the library:
./gradlew buildThe Javadoc for the library can be generated by running:
./gradlew javadocThis project is released on the Maven Central repository. Perform the following steps to create a release.
- Commit all changes for the release
- In the
build.gradle.ktsfile, edit theProjectVersionobject- Set the version for the release. The project follows semantic versioning.
- Set the build type to
BuildType.release
- Commit the changes
- Wait until CI builds the release candidate
- Run the command
mkrelease filevisitor <version> - In a browser go to the Maven Central Repository
- Log in
- Select
Publishfrom the menubar - Press
Publish Component - Enter a name for the deployment
- Choose the file
filevisitor-bundle-<version>.zip - Press
Publish Component - Refresh the page until the deployment has been validated
- Press
Publish - Refresh the page until the status is
Published - Log out
- Delete the file
filevisitor-bundle-<version>.zip - In a browser, go to the project on GitHub
- Generate a release with the tag
<version> - In the build.gradle.kts file, edit the
ProjectVersionobject- Increment the version patch number
- Set the build type to
BuildType.snapshot
- Update the
CHANGELOG.mdwith the changes in the release and prepare for next release changes - Update the
Usagesection in theREADME.mdwith the latest artifact release version - Commit these changes
