Skip to content

Commit

Permalink
Explain a crontab when creating/shouting a scheduled executable
Browse files Browse the repository at this point in the history
  • Loading branch information
pilosus committed Sep 3, 2023
1 parent f677c8c commit c26f468
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 27 deletions.
2 changes: 1 addition & 1 deletion deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
com.github.seancorfield/honeysql {:mvn/version "2.4.1066"}

;; Cron
org.pilosus/kairos {:mvn/version "0.2.20"}
org.pilosus/kairos {:mvn/version "0.2.22"}

;; Cryptography
buddy/buddy-core {:mvn/version "1.11.423"}}
Expand Down
29 changes: 19 additions & 10 deletions src/dienstplan/commands.clj
Original file line number Diff line number Diff line change
Expand Up @@ -650,28 +650,37 @@ Caveats:
parse-command
:command
some?))
crontab-validation (helpers/cron-validation crontab)
crontab-ok? (or (contains? #{"delete" "list" "shout"} subcommand)
(helpers/cron-valid? crontab))]
(:ok? crontab-validation))]
(cond
(not executable-ok?) :executable
(not crontab-ok?) :crontab
:else :valid)))
(not executable-ok?)
{:ok? false :error "`<executable>` cannot be parsed"}
(not crontab-ok?)
{:ok? false :error (format "`<crontab>` cannot be parsed. %s"
(:error crontab-validation))}
:else
{:ok? true})))

(defn fmt-schedule-invalid-arg
[invalid-arg]
(format "Invalid <%s> argument for `schedule` command\n\n%s"
(name invalid-arg)
help-cmd-schedule))
(let [{:keys [error]} invalid-arg]
(format "`schedule` command failed: %s\n\n%s"
error
help-cmd-schedule)))

(defn schedule-shout
[query-params]
(let [{:keys [executable crontab]} query-params
text (format "Executing `%s` with schedule `%s`" executable crontab)]
(let [{:keys [executable crontab explain]} query-params
text (format "Executing `%s` with schedule `%s` (%s)"
executable
crontab
explain)]
{:result text}))

(defmethod command-exec! :schedule [command-map]
(let [args-validation (schedule-args-validation command-map)]
(if (= args-validation :valid)
(if (= (:ok? args-validation) true)
(let [crontab (get-in command-map [:args :crontab])
query-params {:channel (get-in command-map [:context :channel])
:executable (get-in command-map [:args :executable])
Expand Down
11 changes: 8 additions & 3 deletions src/dienstplan/db.clj
Original file line number Diff line number Diff line change
Expand Up @@ -378,11 +378,16 @@
(defn schedule-insert!
[params]
(jdbc/with-transaction [^java.sql.Connection conn db]
(try (let [inserted (sql/insert! conn :schedule params)]
(try (let [inserted (sql/insert! conn :schedule params)
explain (-> params
:crontab
helpers/cron-explain)]
(log/debugf "Schedule inserted: %s" inserted)
{:result (when (-> inserted :schedule/id int?)
(format "Executable `%s` successfully scheduled with `%s`"
(:executable params) (:crontab params)))})
(format "Executable `%s` successfully scheduled with `%s` (%s)"
(:executable params)
(:crontab params)
explain))})
(catch PSQLException e
(let [message (.getMessage e)
duplicate? (string/includes? (.toLowerCase message) "duplicate key")
Expand Down
14 changes: 11 additions & 3 deletions src/dienstplan/helpers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@
(defn cron-valid?
"Return true if crontab is valid"
[crontab]
(-> crontab
kairos/cron->map
some?))
(kairos/cron-valid? crontab))

Check warning on line 68 in src/dienstplan/helpers.clj

View check run for this annotation

Codecov / codecov/patch

src/dienstplan/helpers.clj#L68

Added line #L68 was not covered by tests

(defn cron-validation
"Return crontab validation result"
[crontab]
(kairos/cron-validate crontab))

(defn cron-explain
"Explain crontab in plain English"
[crontab]
(kairos/cron->text crontab))
19 changes: 9 additions & 10 deletions test/dienstplan/api_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@
(is (= 200 (:status schedule-create-rotate-response)))
(is (=
{:channel "C123"
:text "Executable `rotate my-rota` successfully scheduled with `5 0 * * Mon-Fri`"}
:text "Executable `rotate my-rota` successfully scheduled with `5 0 * * Mon-Fri` (at minute 5, past hour 0, on every day of week from Monday through Friday, in every month)"}
(-> schedule-create-rotate-response
:body
(json/parse-string true))))
Expand All @@ -724,7 +724,7 @@
(is (= 200 (:status schedule-create-who-response)))
(is (=
{:channel "C123"
:text "Executable `who my-rota` successfully scheduled with `0 9 * * Mon-Fri`"}
:text "Executable `who my-rota` successfully scheduled with `0 9 * * Mon-Fri` (at minute 0, past hour 9, on every day of week from Monday through Friday, in every month)"}
(-> schedule-create-who-response
:body
(json/parse-string true))))
Expand Down Expand Up @@ -856,14 +856,12 @@
event-after (first events-after-processing)]
(is (= event-before event-after)))))))

(def schedule-invalid-args "Invalid arguments for `schedule` command: %s")

(def params-schedule-command-invalid-args
[["<@U001> schedule create who my rota 0 9 * * Mon-Fri"
:executable
[["<@u001> schedule create who my rota 0 9 * * Mon-Fri"
{:ok? false :error "`<executable>` cannot be parsed"}
"Invalid executable, double quotes omitted"]
["<@U001> schedule create \"who my rota\" Mon-Fri"
:crontab
["<@u001> schedule create \"who my rota\" Mon-Fri"
{:ok? false :error "`<crontab>` cannot be parsed. Invalid crontab format"}
"Invalid crontab"]])

(deftest ^:integration test-schedule-command-invalid-args
Expand Down Expand Up @@ -891,6 +889,7 @@
(testing "Duplicate schedule"
(let [executable "rotate my-rota"
crontab "0 9 * * Mon-Fri"
explain "at minute 0, past hour 9, on every day of week from Monday through Friday, in every month"
command (format "<@U001> schedule create \"%s\" %s"
executable
crontab)
Expand All @@ -913,8 +912,8 @@
:body
(json/parse-string true)
:text)]
(is (= created (format "Executable `%s` successfully scheduled with `%s`"
executable crontab)))
(is (= created (format "Executable `%s` successfully scheduled with `%s` (%s)"
executable crontab explain)))
(is (= duplicate (format "Duplicate schedule for `%s` in the channel"
executable))))))

Expand Down

0 comments on commit c26f468

Please sign in to comment.