From 6d44447dbb5bf9da670d58c9ea6653d85eff22d5 Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Thu, 7 Nov 2024 20:09:13 +0000 Subject: [PATCH] Add --env-file default for env (bash parsed). In addition to bash, the wrapper script requires sort and comm commands to be installed and on the PATH. If the --env-file option is used then a bash wrapper is invoked to source the file that tracks the before and after of variables and this is used to construct the resulting environment map. This is done by making all variable settings implicitly exports (`set -a`) and then printing the before and after variables using `declare -x`, and finally getting added ones using `comm -13`. --- src/dctest/core.cljs | 9 +++++++-- src/dctest/util.cljs | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/dctest/core.cljs b/src/dctest/core.cljs index e864924..90ad478 100644 --- a/src/dctest/core.cljs +++ b/src/dctest/core.cljs @@ -37,6 +37,9 @@ Options: --results-file RESULTS-FILE Write JSON results to RESULTS-FILE --schema-file SCHEMA Path to input schema file [env: DCTEST_SCHEMA] [default: ./schemas/input.yaml] + --env-file FILE Load an FILE an default env settings. + WARNING: FILE is sourced/run by bash. + DO NOT WITH UNSANITIZED FILES. ") (set! *warn-on-infer* false) @@ -538,12 +541,14 @@ Options: (defn -main [& argv] (P/let [opts (parse-opts usage (or argv #js [])) {:keys [continue-on-error project test-suite test-filter - quiet verbose-commands]} opts + quiet verbose-commands env-file]} opts _ (when (empty? test-suite) (Eprintln (str "WARNING: no test-suite was specified"))) + default-env (when env-file (util/load-env env-file)) context {:docker (Docker.) - :env {"COMPOSE_PROJECT_NAME" project} + :env (merge {"COMPOSE_PROJECT_NAME" project} + default-env) :process (js-process) :start (js/Date.now) :opts {:project project diff --git a/src/dctest/util.cljs b/src/dctest/util.cljs index 4ff8e1d..74369ca 100644 --- a/src/dctest/util.cljs +++ b/src/dctest/util.cljs @@ -8,7 +8,7 @@ [clojure.pprint :refer [pprint print-table]] [dctest.expressions :as expr] [promesa.core :as P] - [viasat.util :refer [Eprintln fatal read-file]] + [viasat.util :refer [Eprintln fatal read-file exec-promise]] ["js-yaml" :as yaml] #_["ajv$default" :as Ajv] )) @@ -61,6 +61,20 @@ (Eprintln "Failure to load file:" path) (fatal 2 (.-message err)))))) +(defn load-env [path] + "Source path (using bash) and return a map of modified env variables. + Requires bash, sort, and comm on the PATH." + [path] + (let [bash-cmd (str "bash -c '_AAAAA=$(declare -x | sort);" + "set -a; source \"" path "\";" + "_ZZZZZ=$(declare -x | sort);" + "comm -13 <(echo \"${_AAAAA}\") <(echo \"${_ZZZZZ}\")" + " | sed \"s/^declare -x //\"'")] + (P/let [result (exec-promise bash-cmd)] + (->> (S/split-lines (.-stdout result)) + (map #(first (re-seq #"([^=]*)=\"(.*)\"" %))) + (reduce (fn [m [_ k v]] (assoc m k v)) {}))))) + (defn ajv-error-to-str [error] (let [path (:instancePath error) params (dissoc (:params error) :type :pattern :missingProperty)]