Potemkin is Java-only, so here's a basic function-importing macro that works for both CLJS and CLJ. | (ns metabase.util.namespaces #_{:clj-kondo/ignore [:discouraged-namespace]} (:require [metabase.plugins.classloader :as classloader] [metabase.util.jvm :as u.jvm] [metabase.util.log :as log] [net.cgrand.macrovich :as macros] [potemkin :as p])) |
(set! *warn-on-reflection* true) | |
(defn- redef [target sym] (let [defn-name (or sym (symbol (name target)))] `(def ~defn-name "docstring" (fn [& args#] (apply ~target args#))))) | |
Imports a single defn from another namespace.
This creates a new local function that calls through to the original, so that it reloads nicely in the REPL.
| (defmacro import-fn ;; Heavily inspired by Potemkin. ([target] `(import-fn ~target nil)) ([target sym] (redef target sym))) |
Imports defns from other namespaces.
This uses [[import-fn]] to create pass-through local functions that reload nicely.
| (defmacro import-fns {:style/indent [:form]} [& spaces] (macros/case :cljs `(do ~@(for [[target-ns & fns] spaces f fns :let [target-sym (if (vector? f) (first f) f) new-sym (if (vector? f) (second f) f) target (symbol (name target-ns) (name target-sym))]] (redef target new-sym))) :clj `(p/import-vars ~@spaces))) |
Find and load all sub-namespaces of | (defn find-and-load-namespaces! [root-ns] (assert (string? root-ns) "root-ns must be a string") (doseq [ns-symb u.jvm/metabase-namespace-symbols :when (.startsWith (name ns-symb) root-ns)] (log/infof "Loading namespace: %s" ns-symb) (classloader/require ns-symb))) |