|
@@ -37,13 +37,16 @@ public class CronEvalTool extends LoggingAwareCommand {
|
|
|
|
|
|
private final OptionSpec<Integer> countOption;
|
|
|
private final OptionSpec<String> arguments;
|
|
|
+ private final OptionSpec<Void> detailOption;
|
|
|
|
|
|
CronEvalTool() {
|
|
|
super("Validates and evaluates a cron expression");
|
|
|
- this.countOption = parser.acceptsAll(Arrays.asList("c", "count"),
|
|
|
- "The number of future times this expression will be triggered")
|
|
|
- .withRequiredArg().ofType(Integer.class).defaultsTo(10);
|
|
|
+ this.countOption = parser.acceptsAll(Arrays.asList("c", "count"), "The number of future times this expression will be triggered")
|
|
|
+ .withRequiredArg()
|
|
|
+ .ofType(Integer.class)
|
|
|
+ .defaultsTo(10);
|
|
|
this.arguments = parser.nonOptions("expression");
|
|
|
+ this.detailOption = parser.acceptsAll(Arrays.asList("d", "detail"), "Show detail for invalid cron expression");
|
|
|
|
|
|
parser.accepts("E", "Unused. Only for compatibility with other CLI tools.").withRequiredArg();
|
|
|
}
|
|
@@ -55,46 +58,63 @@ public class CronEvalTool extends LoggingAwareCommand {
|
|
|
if (args.size() != 1) {
|
|
|
throw new UserException(ExitCodes.USAGE, "expecting a single argument that is the cron expression to evaluate");
|
|
|
}
|
|
|
- execute(terminal, args.get(0), count);
|
|
|
+ boolean printDetail = options.has(detailOption);
|
|
|
+ execute(terminal, args.get(0), count, printDetail);
|
|
|
}
|
|
|
|
|
|
- private void execute(Terminal terminal, String expression, int count) throws Exception {
|
|
|
- Cron.validate(expression);
|
|
|
- terminal.println("Valid!");
|
|
|
+ private void execute(Terminal terminal, String expression, int count, boolean printDetail) throws Exception {
|
|
|
+ try {
|
|
|
+ Cron.validate(expression);
|
|
|
+ terminal.println("Valid!");
|
|
|
|
|
|
- final ZonedDateTime date = ZonedDateTime.now(ZoneOffset.UTC);
|
|
|
- final boolean isLocalTimeUTC = UTC_FORMATTER.zone().equals(LOCAL_FORMATTER.zone());
|
|
|
- if (isLocalTimeUTC) {
|
|
|
- terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC");
|
|
|
- } else {
|
|
|
- terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC, local time is [" + LOCAL_FORMATTER.format(date) + "]");
|
|
|
+ final ZonedDateTime date = ZonedDateTime.now(ZoneOffset.UTC);
|
|
|
+ final boolean isLocalTimeUTC = UTC_FORMATTER.zone().equals(LOCAL_FORMATTER.zone());
|
|
|
+ if (isLocalTimeUTC) {
|
|
|
+ terminal.println("Now is [" + UTC_FORMATTER.format(date) + "] in UTC");
|
|
|
+ } else {
|
|
|
+ terminal.println(
|
|
|
+ "Now is [" + UTC_FORMATTER.format(date) + "] in UTC, local time is [" + LOCAL_FORMATTER.format(date) + "]"
|
|
|
+ );
|
|
|
|
|
|
- }
|
|
|
- terminal.println("Here are the next " + count + " times this cron expression will trigger:");
|
|
|
-
|
|
|
- Cron cron = new Cron(expression);
|
|
|
- long time = date.toInstant().toEpochMilli();
|
|
|
-
|
|
|
- for (int i = 0; i < count; i++) {
|
|
|
- long prevTime = time;
|
|
|
- time = cron.getNextValidTimeAfter(time);
|
|
|
- if (time < 0) {
|
|
|
- if (i == 0) {
|
|
|
- throw new UserException(ExitCodes.OK, "Could not compute future times since ["
|
|
|
- + UTC_FORMATTER.format(Instant.ofEpochMilli(prevTime)) + "] " + "(perhaps the cron expression only points to " +
|
|
|
- "times in the" +
|
|
|
- " " +
|
|
|
- "past?)");
|
|
|
- }
|
|
|
- break;
|
|
|
}
|
|
|
+ terminal.println("Here are the next " + count + " times this cron expression will trigger:");
|
|
|
+
|
|
|
+ Cron cron = new Cron(expression);
|
|
|
+ long time = date.toInstant().toEpochMilli();
|
|
|
+
|
|
|
+ for (int i = 0; i < count; i++) {
|
|
|
+ long prevTime = time;
|
|
|
+ time = cron.getNextValidTimeAfter(time);
|
|
|
+ if (time < 0) {
|
|
|
+ if (i == 0) {
|
|
|
+ throw new UserException(
|
|
|
+ ExitCodes.OK,
|
|
|
+ "Could not compute future times since ["
|
|
|
+ + UTC_FORMATTER.format(Instant.ofEpochMilli(prevTime))
|
|
|
+ + "] "
|
|
|
+ + "(perhaps the cron expression only points to "
|
|
|
+ + "times in the"
|
|
|
+ + " "
|
|
|
+ + "past?)"
|
|
|
+ );
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- if (isLocalTimeUTC) {
|
|
|
- terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
|
|
|
+ if (isLocalTimeUTC) {
|
|
|
+ terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
|
|
|
+ } else {
|
|
|
+ terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
|
|
|
+ terminal.println("\t" + LOCAL_FORMATTER.format(Instant.ofEpochMilli(time)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ if (printDetail) {
|
|
|
+ throw e;
|
|
|
} else {
|
|
|
- terminal.println((i + 1) + ".\t" + UTC_FORMATTER.format(Instant.ofEpochMilli(time)));
|
|
|
- terminal.println("\t" + LOCAL_FORMATTER.format(Instant.ofEpochMilli(time)));
|
|
|
+ throw new UserException(ExitCodes.OK, e.getMessage() + (e.getCause() == null ? "" : ": " + e.getCause().getMessage()));
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
}
|