-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(assert): added fileNotExists (#60)
- Loading branch information
Showing
7 changed files
with
233 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
src/main/java/me/itzg/helpers/assertcmd/EvalExistence.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package me.itzg.helpers.assertcmd; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.FileSystems; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.PathMatcher; | ||
import java.nio.file.Paths; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
import lombok.AllArgsConstructor; | ||
|
||
class EvalExistence { | ||
|
||
private static final Pattern globSymbols = Pattern.compile("[*?]|\\{.+?}"); | ||
// matches everything up to the last path separator either / or \ | ||
private static final Pattern pathSeparators = Pattern.compile(".*[/\\\\]"); | ||
|
||
static boolean exists(String pathSpec) throws IOException { | ||
return !matchingPaths(pathSpec).paths.isEmpty(); | ||
} | ||
|
||
@AllArgsConstructor | ||
static class MatchingPaths { | ||
|
||
final boolean globbing; | ||
final List<Path> paths; | ||
} | ||
|
||
static MatchingPaths matchingPaths(String pathSpec) throws IOException { | ||
final Matcher globMatcher = globSymbols.matcher(pathSpec); | ||
// find the first globbing symbol | ||
final boolean hasGlob = globMatcher.find(); | ||
if (!hasGlob) { | ||
// no globbing, just a specific path | ||
final Path path = Paths.get(pathSpec); | ||
return new MatchingPaths(false, | ||
Files.exists(path) ? Collections.singletonList(path) : Collections.emptyList() | ||
); | ||
} | ||
|
||
// find last path separator in the text before the glob | ||
final Matcher sepMatcher = pathSeparators.matcher(pathSpec.substring(0, globMatcher.start())); | ||
final Path walkStart; | ||
// ...by looking from the start of the string | ||
if (sepMatcher.lookingAt()) { | ||
// ...and grabbing the end of the matched text | ||
walkStart = Paths.get(pathSpec.substring(0, sepMatcher.end())); | ||
} | ||
else { | ||
// no separator, so process relative paths | ||
walkStart = Paths.get(""); | ||
} | ||
|
||
final PathMatcher pathMatcher = FileSystems.getDefault().getPathMatcher( | ||
"glob:" + | ||
// escape any Windows backslashes | ||
pathSpec.replace("\\", "\\\\") | ||
); | ||
try (Stream<Path> pathStream = Files.walk(walkStart)) { | ||
return new MatchingPaths(true, | ||
pathStream | ||
.filter(Files::isRegularFile) | ||
.filter(pathMatcher::matches) | ||
.collect(Collectors.toList()) | ||
); | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
src/main/java/me/itzg/helpers/assertcmd/FileNotExists.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package me.itzg.helpers.assertcmd; | ||
|
||
import java.util.List; | ||
import java.util.concurrent.Callable; | ||
import me.itzg.helpers.assertcmd.EvalExistence.MatchingPaths; | ||
import picocli.CommandLine.Command; | ||
import picocli.CommandLine.ExitCode; | ||
import picocli.CommandLine.Parameters; | ||
|
||
@Command(name = "fileNotExists") | ||
class FileNotExists implements Callable<Integer> { | ||
|
||
@Parameters | ||
List<String> paths; | ||
|
||
@Override | ||
public Integer call() throws Exception { | ||
boolean failed = false; | ||
|
||
if (paths != null) { | ||
for (String path : paths) { | ||
final MatchingPaths matchingPaths = EvalExistence.matchingPaths(path); | ||
if (!matchingPaths.paths.isEmpty()) { | ||
if (matchingPaths.globbing) { | ||
System.err.printf("The files %s exist looking at %s%n", matchingPaths.paths, path); | ||
} | ||
else { | ||
System.err.printf("%s exists%n", path); | ||
} | ||
failed = true; | ||
} | ||
} | ||
} | ||
|
||
return failed ? ExitCode.SOFTWARE : ExitCode.OK; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package me.itzg.helpers; | ||
|
||
import java.util.Arrays; | ||
import org.assertj.core.api.ListAssert; | ||
|
||
public class MoreAssertions { | ||
|
||
public static ListAssert<String> assertThatLines(String content) { | ||
final String[] lines = content.split("\n|\r\n|\r"); | ||
return new ListAssert<>(Arrays.stream(lines, 0, | ||
lines[lines.length - 1].isEmpty() ? lines.length - 1 : lines.length | ||
)); | ||
} | ||
} |
87 changes: 87 additions & 0 deletions
87
src/test/java/me/itzg/helpers/assertcmd/FileNotExistsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package me.itzg.helpers.assertcmd; | ||
|
||
import static com.github.stefanbirkner.systemlambda.SystemLambda.tapSystemErr; | ||
import static me.itzg.helpers.MoreAssertions.assertThatLines; | ||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.io.TempDir; | ||
import picocli.CommandLine; | ||
import picocli.CommandLine.ExitCode; | ||
|
||
class FileNotExistsTest { | ||
|
||
@Test | ||
void failsWhenAnyExist(@TempDir Path tempDir) throws Exception { | ||
final Path file1 = Files.createFile(tempDir.resolve("file1")); | ||
final Path file2 = tempDir.resolve("file2"); | ||
|
||
final String errOut = tapSystemErr(() -> { | ||
int exitCode = new CommandLine(new FileNotExists()) | ||
.execute( | ||
file1.toString(), | ||
file2.toString() | ||
); | ||
|
||
assertThat(exitCode).isEqualTo(ExitCode.SOFTWARE); | ||
}); | ||
|
||
assertThatLines(errOut) | ||
.contains(file1 +" exists"); | ||
} | ||
|
||
@Test | ||
void passesWhenAllMissing(@TempDir Path tempDir) throws Exception { | ||
final Path pathA = tempDir.resolve("fileA"); | ||
final Path fileB = tempDir.resolve("fileB"); | ||
|
||
final String errOut = tapSystemErr(() -> { | ||
int exitCode = new CommandLine(new FileNotExists()) | ||
.execute( | ||
pathA.toString(), | ||
fileB.toString() | ||
); | ||
|
||
assertThat(exitCode).isEqualTo(ExitCode.OK); | ||
}); | ||
|
||
assertThat(errOut).isBlank(); | ||
} | ||
|
||
@Test | ||
void failsWhenGlobFindsAnyFiles(@TempDir Path tempDir) throws Exception { | ||
final Path file1 = Files.createFile(tempDir.resolve("file1")); | ||
|
||
final String errOut = tapSystemErr(() -> { | ||
int exitCode = new CommandLine(new FileNotExists()) | ||
.execute( | ||
String.format("%s/file*", tempDir) | ||
); | ||
|
||
assertThat(exitCode).isEqualTo(ExitCode.SOFTWARE); | ||
}); | ||
|
||
assertThatLines(errOut) | ||
.hasSize(1) | ||
.element(0) | ||
.asString() | ||
.contains(file1.toString()); | ||
} | ||
|
||
@Test | ||
void passesWhenGlobFindsNothing(@TempDir Path tempDir) throws Exception { | ||
final String errOut = tapSystemErr(() -> { | ||
int exitCode = new CommandLine(new FileNotExists()) | ||
.execute( | ||
// working directory is top of project | ||
tempDir+"/*.md" | ||
); | ||
|
||
assertThat(exitCode).isEqualTo(0); | ||
}); | ||
|
||
assertThat(errOut).isBlank(); | ||
} | ||
} |
Oops, something went wrong.