Utilities (jolt.util)

jolt.util collects small general-purpose helpers. The main one is import-vars, for putting a public face on another namespace — the tool for wrapping a vendored library.

import-vars

(require '[jolt.util :refer [import-vars]])
(import-vars from-ns & {:keys [exclude]})

Re-export the public vars of from-ns into the current namespace as thin delegating definitions. A function becomes a fn that applies the source var; a macro becomes a macro that expands to a call of the source macro. Pass :exclude a set of symbols to leave out.

from-ns must already be required.

(ns my.fs
  (:require [babashka.fs]
            [jolt.util :refer [import-vars]]))

;; expose all of babashka.fs except the java.util.zip functions
(import-vars babashka.fs :exclude #{zip unzip gzip gunzip})

(my.fs/exists? "deps.edn")     ; => true  (delegates to babashka.fs/exists?)

Why not intern?

The obvious way to mirror a namespace is to walk ns-publics at load time and intern each var:

(doseq [[sym v] (ns-publics 'babashka.fs)]     ; DON'T — breaks in a built binary
  (intern *ns* sym @v))

That works in the REPL but cannot be reproduced by an AOT build: the interns run as a runtime side effect over reflective state, so jolt build emits nothing for them and the wrapper's vars are unbound in the binary. import-vars instead emits static def/defmacro forms that resolve the source at call time — they bake into a binary and do not depend on load order.

This is how jolt.fs wraps the vendored babashka.fs, and it is the pattern to use when you vendor a library and want to present it under your own namespace.