Skip to content

Instantly share code, notes, and snippets.

Last active June 28, 2022 08:50
What would you like to do?
An example of "light" validation of babashka.cli arguments i.e. checking for required arguments without using Spec or Malli
(ns cli-gist
(:require [babashka.cli :as cli]
[clojure.set :as set]
[clojure.string :as str]))
(def upload-spec {:bucket-region {:ref "<aws-region>"
:desc "The AWS region where the S3 bucket was created"
:optional true
:alias :r}
:bucket {:ref "<s3-bucket-name>"
:desc "The name of the s3 bucket"
:optional false
:alias :b}
:path {:ref "<s3-path>"
:desc "The path inside the s3 bucket where the artifact will be added"
:optional false
:alias :p}})
(defn validate-optional-args
"return a string describing missing CLI arguments using the :optional key in a spec"
[{:keys [spec parsed]}]
(let [required-keys (->> spec
(keep (fn [arg-entry]
(when (false? (:optional (val arg-entry)))
(key arg-entry))))
parsed-keys (set (keys parsed))]
(when-let [missing-keys (seq (set/difference required-keys parsed-keys))]
(->> missing-keys
(map name)
(str/join ", ")
(str "Required keys missing: ")))))
(defn parse-deploy-args
"parse and validate the cli args"
(let [opts (cli/parse-opts args {:spec upload-spec})]
(when-let [validation-error (validate-optional-args {:spec upload-spec
:parsed opts})]
(println validation-error "\n")
(println "Usage:")
(println (cli/format-opts {:spec deploy-spec}))
(throw (ex-info "failed" {:message validation-error})))
; good
(parse-deploy-args ["--bucket-region" "us-west-2"
"--bucket" "cloudfront-assets"
"--path" "apps/prod"])
; bad
(parse-deploy-args ["--bucket-region" "us-west-2"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment