Skip to content

Instantly share code, notes, and snippets.

@andiogenes
Last active May 16, 2022 08:45
Show Gist options
  • Save andiogenes/681c260a395aa3cbf4f2ef915fbec41e to your computer and use it in GitHub Desktop.
Save andiogenes/681c260a395aa3cbf4f2ef915fbec41e to your computer and use it in GitHub Desktop.
Poor man's direnv
#!/usr/bin/env bb
(require '[clojure.java.shell :refer [sh]]
'[clojure.java.io :as io]
'[clojure.edn :as edn])
(def usage-line
"Usage: with-env [arg*]
\rExtends environment with variables obtained from 'env.edn' file,
\rlocated in current working directory.
\rThe content of 'env.edn' should be a map with keyword keys and
\rstring values, just as following:
\r{:FOO \"foo\" :BAR \"bar\" ...}")
(defn print-usage-and-exit []
(println usage-line)
(System/exit 1))
(defn load-edn
"Load edn from an io/reader source (filename or io/resource)."
[source]
(try
(with-open [r (io/reader source)]
(edn/read (java.io.PushbackReader. r)))
(catch java.io.IOException e nil)
(catch RuntimeException e
(printf "Error parsing edn file '%s': %s\n" source (.getMessage e))
(System/exit 2))))
(defn execute-with-env-edn [args]
(let [env-path "./env.edn"
env-tbl (load-edn env-path)
env (into ["env"] (map (fn [[k v]] (str (name k) "=" v)) env-tbl))
result (apply sh (concat env args))
out (:out result)
err (:err result)]
(when (not-empty out) (print out) (flush))
(when (not-empty err) (.print *err* err) (.flush *err*))
(System/exit (:exit result))))
(defn help-option? [option]
(let [help-aliases #{"--help" "--usage" "-h"}]
(contains? help-aliases option)))
(let [[& args] *command-line-args*]
(cond
(help-option? (first args))
(print-usage-and-exit)
:else
(execute-with-env-edn args)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment