1
2
3
4
5
6
7 package com.varmateo.yawg.cli;
8
9 import java.io.OutputStream;
10 import java.io.OutputStreamWriter;
11 import java.io.PrintWriter;
12 import java.io.Writer;
13 import java.nio.charset.StandardCharsets;
14 import java.nio.file.Path;
15
16 import io.vavr.control.Try;
17
18 import com.varmateo.yawg.api.BakeOptions;
19 import com.varmateo.yawg.api.Result;
20 import com.varmateo.yawg.api.SiteBaker;
21 import com.varmateo.yawg.api.YawgInfo;
22 import com.varmateo.yawg.core.DefaultSiteBaker;
23 import com.varmateo.yawg.logging.Log;
24 import com.varmateo.yawg.logging.LogFactory;
25 import com.varmateo.yawg.util.Results;
26
27
28
29
30
31 public final class BakerCli {
32
33
34 private static final int EXIT_STATUS_OK = 0;
35 private static final int EXIT_STATUS_FAILURE = 1;
36
37
38 private final Log _log = LogFactory.createFor(BakerCli.class);
39
40
41 private BakerCli() {
42
43 }
44
45
46
47
48
49 public static BakerCli create() {
50
51 return new BakerCli();
52 }
53
54
55
56
57
58
59
60
61 public int run(final BakerCliRunOptions options) {
62
63 final InfoPrinter infoPrinter = buildInfoPrinter(options.argv0, options.output);
64 final Try<Void> bakeResult = tryRun(infoPrinter, options.args)
65 .onFailure(cause -> infoPrinter.printError(cause));
66
67 final int exitStatus = bakeResult
68 .map(x -> EXIT_STATUS_OK)
69 .recover(x -> EXIT_STATUS_FAILURE)
70 .get();
71
72 return exitStatus;
73 }
74
75
76
77
78
79 private static InfoPrinter buildInfoPrinter(
80 final String argv0,
81 final OutputStream output) {
82
83 final boolean autoFlush = true;
84 final Writer stdoutWriter = new OutputStreamWriter(output, StandardCharsets.UTF_8);
85 final PrintWriter stdout = new PrintWriter(stdoutWriter, autoFlush);
86
87 return InfoPrinter.builder()
88 .argv0(argv0)
89 .output(stdout)
90 .build();
91 }
92
93
94
95
96
97 private Try<Void> tryRun(
98 final InfoPrinter infoPrinter,
99 final String[] args) {
100
101 return BakerCliAction.parse(args)
102 .flatMap(action -> performAction(infoPrinter, action));
103 }
104
105
106 private Try<Void> performAction(
107 final InfoPrinter infoPrinter,
108 final BakerCliAction action) {
109
110 return action.match(
111 () -> Try.run(infoPrinter::printHelp),
112 () -> Try.run(infoPrinter::printVersion),
113 bake -> doBake(bake.options()));
114 }
115
116
117 private Try<Void> doBake(final BakerCliBakeOptions options) {
118
119 logOptions(options);
120
121 final SiteBaker siteBaker = options.templatesDir()
122 .map(path -> DefaultSiteBaker.create(path))
123 .getOrElse(() -> DefaultSiteBaker.create());
124
125 final BakeOptions bakeOptions = BakeOptions.builder()
126 .sourceDir(options.sourceDir())
127 .targetDir(options.targetDir())
128 .putAllExternalPageVars(options.externalPageVars().toJavaMap())
129 .build();
130
131 final Result<Void> result = siteBaker.bake(bakeOptions);
132
133 return Results.toTry(result)
134 .recoverWith(cause -> Try.failure(CliException.bakeFailure(cause)));
135 }
136
137
138 private void logOptions(final BakerCliBakeOptions options) {
139
140 final Path sourceDir = options.sourceDir();
141 final Path targetDir = options.targetDir();
142 final String templatesDir = options.templatesDir().map(Path::toString).getOrElse("NONE");
143
144 _log.info("{0} {1}", YawgInfo.PRODUCT_NAME, YawgInfo.VERSION);
145 _log.info(" Source : {0}", sourceDir);
146 _log.info(" Target : {0}", targetDir);
147 _log.info(" Templates : {0}", templatesDir);
148 }
149
150 }