Skip to content

Instantly share code, notes, and snippets.

Last active Jun 28, 2022
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