Skip to content

Commit 23cf113

Browse files
Work in progress
1 parent 4e8610d commit 23cf113

File tree

10 files changed

+327
-177
lines changed

10 files changed

+327
-177
lines changed

src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/cli/ConsoleOutput.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,13 @@ private void printErr(String msg, Object... args) {
3131
}
3232

3333
private void printfln(PrintStream dest, String msg, Object... args) {
34-
dest.printf(msg, args);
35-
dest.println(); // Because "printf" does not print line return
34+
dest.printf(msg + "\n", args);// Because "printf" does not print line return
3635
}
3736

3837
public void printDebug(String msg, Object... args) {
3938
// Could not (yet) make Logger level work within native image, so fallback to plain console output (for now)
4039
if (debug) {
41-
printOut(msg, args);
40+
printOut("[DEBUG] " + msg, args);
4241
}
4342
}
4443

@@ -47,7 +46,7 @@ public void print(String msg, Object... args) {
4746
}
4847

4948
public void printError(String msg, Object... args) {
50-
printErr(msg, args);
49+
printErr("[ERROR] " + msg, args);
5150
}
5251

5352
}
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
package io.github.computerdaddyguy.jfiletreeprettyprinter.cli;
22

3+
import io.github.computerdaddyguy.jfiletreeprettyprinter.cli.options.ExternalOptionsMapper;
4+
import io.github.computerdaddyguy.jfiletreeprettyprinter.cli.options.ExternalOptionsReader;
35
import picocli.CommandLine;
46

57
class FileTreePrettyPrinterCommandLine {
68

79
public static void main(String[] args) {
8-
var cmd = new CommandLine(new PrettyPrintCommand());
9-
int exitCode = cmd.execute(args);
10-
System.exit(exitCode);
10+
System.exit(executeCommand(args));
11+
}
12+
13+
static int executeCommand(String[] args) {
14+
var reader = ExternalOptionsReader.createDefault();
15+
var mapper = ExternalOptionsMapper.createDefault();
16+
17+
var cmd = new CommandLine(new PrettyPrintCommand(reader, mapper));
18+
19+
return cmd.execute(args);
1120
}
1221

1322
}

src/main/java/io/github/computerdaddyguy/jfiletreeprettyprinter/cli/PrettyPrintCommand.java

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package io.github.computerdaddyguy.jfiletreeprettyprinter.cli;
22

33
import io.github.computerdaddyguy.jfiletreeprettyprinter.FileTreePrettyPrinter;
4+
import io.github.computerdaddyguy.jfiletreeprettyprinter.cli.options.ExternalOptionsException;
5+
import io.github.computerdaddyguy.jfiletreeprettyprinter.cli.options.ExternalOptionsMapper;
46
import io.github.computerdaddyguy.jfiletreeprettyprinter.cli.options.ExternalOptionsReader;
57
import io.github.computerdaddyguy.jfiletreeprettyprinter.options.PrettyPrintOptions;
8+
import jakarta.validation.ConstraintViolationException;
69
import java.io.File;
710
import java.nio.file.Path;
8-
import java.util.ArrayList;
11+
import java.util.Objects;
912
import java.util.concurrent.Callable;
1013
import org.jspecify.annotations.NullMarked;
1114
import org.jspecify.annotations.Nullable;
@@ -24,7 +27,15 @@
2427
@NullMarked
2528
class PrettyPrintCommand implements Callable<Integer> {
2629

27-
private static final String DEFAULT_OPTION_FILENAME = ".prettyprint";
30+
private final ExternalOptionsReader reader;
31+
private final ExternalOptionsMapper mapper;
32+
33+
public PrettyPrintCommand(ExternalOptionsReader reader, ExternalOptionsMapper mapper) {
34+
this.reader = Objects.requireNonNull(reader, "reader is null");
35+
this.mapper = Objects.requireNonNull(mapper, "mapper is null");
36+
}
37+
38+
// ---------- CLI args ----------
2839

2940
@Nullable
3041
@Parameters(index = "0", description = "The path to pretty print", arity = "0..1")
@@ -37,6 +48,8 @@ class PrettyPrintCommand implements Callable<Integer> {
3748
@Option(names = { "-d", "--debug" }, description = "debug mode")
3849
private boolean debug;
3950

51+
// ---------- Command ----------
52+
4053
@Override
4154
public Integer call() throws Exception {
4255

@@ -48,7 +61,18 @@ public Integer call() throws Exception {
4861
return 1;
4962
}
5063

51-
var options = detectOptions(targetPath, output);
64+
PrettyPrintOptions options;
65+
try {
66+
Path optionsPath = optionsFile == null ? null : optionsFile.toPath().toAbsolutePath().normalize();
67+
var externalOptions = reader.readExternalOptions(output, targetPath, optionsPath);
68+
options = mapper.mapToOptions(targetPath, externalOptions);
69+
} catch (ExternalOptionsException e) {
70+
output.printError(e.getMessage() + ": " + optionsFile.toString());
71+
return 1;
72+
} catch (ConstraintViolationException e) {
73+
output.printError(e.getMessage() + ": " + optionsFile.toString());
74+
return 1;
75+
}
5276

5377
try {
5478
var printer = FileTreePrettyPrinter.builder().withOptions(options).build();
@@ -74,29 +98,4 @@ private Path detectTargetPath(ConsoleOutput output) {
7498
return path;
7599
}
76100

77-
private PrettyPrintOptions detectOptions(Path targetPath, ConsoleOutput output) {
78-
79-
var reader = new ExternalOptionsReader(output);
80-
if (optionsFile != null) {
81-
var path = optionsFile.toPath().toAbsolutePath().normalize();
82-
var options = reader.readOptions(targetPath, path);
83-
if (options == null) {
84-
System.exit(1);
85-
}
86-
return options;
87-
} else {
88-
var potentialOptions = new ArrayList<Path>();
89-
potentialOptions.add(targetPath.resolve(DEFAULT_OPTION_FILENAME));
90-
potentialOptions.add(Path.of(".").resolve(DEFAULT_OPTION_FILENAME));
91-
potentialOptions.add(Path.of(System.getProperty("user.home")).resolve(DEFAULT_OPTION_FILENAME));
92-
var options = reader.readOptions(targetPath, potentialOptions);
93-
if (options != null) {
94-
return options;
95-
}
96-
output.printDebug("No options file provided/found!");
97-
return PrettyPrintOptions.createDefault();
98-
}
99-
100-
}
101-
102101
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.github.computerdaddyguy.jfiletreeprettyprinter.cli.options;
2+
3+
import io.github.computerdaddyguy.jfiletreeprettyprinter.options.ChildLimits;
4+
import io.github.computerdaddyguy.jfiletreeprettyprinter.options.PathMatchers;
5+
import io.github.computerdaddyguy.jfiletreeprettyprinter.options.PrettyPrintOptions;
6+
import java.nio.file.Path;
7+
import java.nio.file.PathMatcher;
8+
import org.jspecify.annotations.Nullable;
9+
10+
class DefaultExternalOptionsMapper implements ExternalOptionsMapper {
11+
12+
@Override
13+
public PrettyPrintOptions mapToOptions(Path targetPath, @Nullable ExternalOptions externalOptions) {
14+
var options = PrettyPrintOptions.createDefault();
15+
if (externalOptions != null) {
16+
options = mapEmojis(options, externalOptions);
17+
options = mapChildLimit(options, externalOptions, targetPath);
18+
}
19+
return options;
20+
}
21+
22+
private PrettyPrintOptions mapEmojis(PrettyPrintOptions options, ExternalOptions externalOptions) {
23+
if (Boolean.TRUE.equals(externalOptions.emojis())) {
24+
return options.withDefaultEmojis();
25+
}
26+
return options;
27+
}
28+
29+
private PrettyPrintOptions mapChildLimit(PrettyPrintOptions options, ExternalOptions externalOptions, Path targetPath) {
30+
if (externalOptions.childLimit() == null) {
31+
return options;
32+
}
33+
return switch (externalOptions.childLimit()) {
34+
case ChildLimit.StaticLimit(var limit) -> options.withChildLimit(limit);
35+
case ChildLimit.DynamicLimit(var limits) -> {
36+
var limitBuilder = ChildLimits.builder();
37+
for (var limit : limits) {
38+
limitBuilder.add(mapMatcher(limit.matcher(), targetPath), limit.limit());
39+
}
40+
options.withChildLimit(limitBuilder.build());
41+
yield options;
42+
}
43+
};
44+
}
45+
46+
private PathMatcher mapMatcher(Matcher matcher, Path targetPath) {
47+
return switch (matcher) {
48+
case Matcher.AlwaysTrue() -> (p) -> true;
49+
case Matcher.AlwaysFalse() -> (p) -> false;
50+
case Matcher.AllOf(var matchers) -> PathMatchers.allOf(matchers.stream().map(subMatcher -> mapMatcher(subMatcher, targetPath)).toList());
51+
case Matcher.AnyOf(var matchers) -> PathMatchers.anyOf(matchers.stream().map(subMatcher -> mapMatcher(subMatcher, targetPath)).toList());
52+
case Matcher.NoneOf(var matchers) -> PathMatchers.noneOf(matchers.stream().map(subMatcher -> mapMatcher(subMatcher, targetPath)).toList());
53+
case Matcher.NameGlob(var glob) -> PathMatchers.hasNameMatchingGlob(glob);
54+
case Matcher.PathGlob(var glob) -> PathMatchers.hasRelativePathMatchingGlob(targetPath, glob);
55+
};
56+
}
57+
58+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.github.computerdaddyguy.jfiletreeprettyprinter.cli.options;
2+
3+
import java.nio.file.Path;
4+
import org.jspecify.annotations.NullMarked;
5+
6+
@NullMarked
7+
public class ExternalOptionsException extends RuntimeException {
8+
9+
private final Path optionsPath;
10+
11+
public ExternalOptionsException(Path optionsPath, String message, Throwable cause) {
12+
super(message, cause);
13+
this.optionsPath = optionsPath;
14+
}
15+
16+
public ExternalOptionsException(Path optionsPath, String message) {
17+
super(message);
18+
this.optionsPath = optionsPath;
19+
}
20+
21+
public Path getOptionsPath() {
22+
return optionsPath;
23+
}
24+
25+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.github.computerdaddyguy.jfiletreeprettyprinter.cli.options;
2+
3+
import io.github.computerdaddyguy.jfiletreeprettyprinter.options.PrettyPrintOptions;
4+
import java.nio.file.Path;
5+
import org.jspecify.annotations.NullMarked;
6+
import org.jspecify.annotations.Nullable;
7+
8+
@NullMarked
9+
public interface ExternalOptionsMapper {
10+
11+
PrettyPrintOptions mapToOptions(Path targetPath, @Nullable ExternalOptions externalOptions);
12+
13+
static ExternalOptionsMapper createDefault() {
14+
return new DefaultExternalOptionsMapper();
15+
}
16+
17+
}

0 commit comments

Comments
 (0)