From 9d5b2aa05b35cf20c5d133367ecfe1553ea5e2fd Mon Sep 17 00:00:00 2001 From: Michiel Borkent Date: Tue, 1 Nov 2022 15:54:14 +0100 Subject: [PATCH] Fix #270: respect nbb.edn when starting nbb from JS API --- src/nbb/api.cljs | 58 +++++++++++++++++++++----- src/nbb/impl/deps.cljs | 1 - src/nbb/impl/main.cljs | 33 +++------------ src/nbb/impl/nrepl_server.cljs | 74 +++++++++++++++++---------------- test-scripts/api-test/test.cljs | 4 +- 5 files changed, 93 insertions(+), 77 deletions(-) diff --git a/src/nbb/api.cljs b/src/nbb/api.cljs index 07b393c5..b3c85ad6 100644 --- a/src/nbb/api.cljs +++ b/src/nbb/api.cljs @@ -1,11 +1,14 @@ (ns nbb.api (:require + ["fs" :as fs] ["import-meta-resolve" :as imr] ["module" :refer [createRequire]] ["path" :as path] ["url" :as url] + [clojure.edn :as edn] [nbb.classpath :as cp] - [nbb.core :as nbb])) + [nbb.core :as nbb] + [shadow.esm :as esm])) (def create-require (or createRequire @@ -13,21 +16,54 @@ (fn [_] (throw (js/Error. "createRequire is not defined, this is a no-op")))))) -(defn init-require [path] - (let [require (create-require path) - path-url (str (url/pathToFileURL path))] - (set! (.-require goog/global) require) - (swap! nbb/ctx assoc :require require) - (swap! nbb/ctx assoc :resolve #(imr/resolve % path-url)))) +(def initialized? (atom false)) + +(defn local-nbb-edn + "Finds a local nbb.edn file and reads it. Returns nil if none found." + [] + (when (fs/existsSync "nbb.edn") + (edn/read-string (fs/readFileSync "nbb.edn" "utf8")))) + +(defn initialize [path opts] + (js/Promise.resolve + (when-not @initialized? + ;; (prn :path path) + (let [path (path/resolve (or path "script.cljs")) + opts (if (:config opts) + (assoc opts :config + (edn/read-string + (fs/readFileSync + (:config opts) + "utf8"))) + (if-let [config (local-nbb-edn)] + (assoc opts :config config) + opts)) + require (create-require path) + path-url (str (url/pathToFileURL path))] + (set! (.-require goog/global) require) + (swap! nbb/ctx assoc :require require) + (swap! nbb/ctx assoc :resolve #(imr/resolve % path-url)) + (reset! nbb/opts opts) + (-> + (js/Promise.resolve + (when-let [config (:config opts)] + (if-let [paths (:paths config)] + (doseq [path paths] + (cp/add-classpath path)) + (cp/add-classpath (js/process.cwd))) + (esm/dynamic-import "./nbb_deps.js"))) + (.then (fn [_] + (reset! initialized? true)))))))) (defn loadFile [script] (let [script-path (path/resolve script)] - (init-require script-path) - (nbb/load-file script-path))) + (-> (initialize script-path nil) + (.then #(nbb/load-file script-path))))) (defn loadString [expr] - (init-require (path/resolve "script.cljs")) - (nbb/load-string expr)) + (-> (initialize nil nil) + (.then + #(nbb/load-string expr)))) (defn addClassPath [cp] (cp/add-classpath cp)) diff --git a/src/nbb/impl/deps.cljs b/src/nbb/impl/deps.cljs index bece9a41..ebf0bea5 100644 --- a/src/nbb/impl/deps.cljs +++ b/src/nbb/impl/deps.cljs @@ -6,7 +6,6 @@ [nbb.classpath :as cp] [nbb.core :as nbb :refer [opts]])) - (def default-nbb-cache-path ".nbb/.cache") diff --git a/src/nbb/impl/main.cljs b/src/nbb/impl/main.cljs index 87fa53ed..eec3f846 100644 --- a/src/nbb/impl/main.cljs +++ b/src/nbb/impl/main.cljs @@ -104,37 +104,15 @@ Tooling: bundle: produce single JS file for usage with bundlers. ")) - -(defn local-nbb-edn - "Finds a local nbb.edn file and reads it. Returns nil if none found." - [] - (when (fs/existsSync "nbb.edn") - (edn/read-string (fs/readFileSync "nbb.edn" "utf8")))) - - (defn main [] (let [[_ _ & args] js/process.argv opts (parse-args args) - opts (if (:config opts) - (assoc opts :config - (edn/read-string - (fs/readFileSync - (:config opts) - "utf8"))) - (if-let [config (local-nbb-edn)] - (assoc opts :config config) - opts)) _ (reset! common/opts opts) script-file (:script opts) expr (:expr opts) classpath (:classpath opts) - cwd (js/process.cwd) - _ (do (when classpath - (cp/add-classpath classpath)) - (if-let [paths (get-in opts [:config :paths])] - (doseq [path paths] - (cp/add-classpath path)) - (cp/add-classpath cwd))) + _ (when classpath + (cp/add-classpath classpath)) nrepl-server (:nrepl-server opts) repl? (or (:repl opts) (:socket-repl opts) @@ -147,14 +125,13 @@ Tooling: (when (:version opts) (println (str (nbb/cli-name) " v" (nbb/version))) (js/process.exit 0)) - (reset! nbb/opts opts) - (when repl? (api/init-require (path/resolve "script.cljs"))) (if (or script-file expr nrepl-server repl? bundle-opts) (do (sci/alter-var-root nbb/command-line-args (constantly (:args opts))) (-> (js/Promise.resolve - (when (:config opts) - (esm/dynamic-import "./nbb_deps.js"))) + (api/initialize (if repl? (path/resolve "script.cljs") + script-file) + opts)) (.then (fn [] (-> (cond script-file diff --git a/src/nbb/impl/nrepl_server.cljs b/src/nbb/impl/nrepl_server.cljs index 6f3386e2..113faf36 100644 --- a/src/nbb/impl/nrepl_server.cljs +++ b/src/nbb/impl/nrepl_server.cljs @@ -210,21 +210,21 @@ (ifn? (:val m)) "function" :else "variable") "status" ["done"]} - doc (assoc "docstring" doc)) + doc (assoc "docstring" doc)) (:info :lookup) (cond-> {"ns" (:ns m) "name" (:name m) "arglists-str" (forms-join (:arglists m)) "status" ["done"]} - doc (assoc "doc" doc) - file (assoc "file" file) - line (assoc "line" line)))] + doc (assoc "doc" doc) + file (assoc "file" file) + line (assoc "line" line)))] (send-fn request reply)))) (catch js/Error e (let [status (cond-> #{"done"} - (= mapping-type :eldoc) - (conj "no-eldoc"))] + (= mapping-type :eldoc) + (conj "no-eldoc"))] (send-fn request {"status" status "ex" (str e)})))))) @@ -307,36 +307,38 @@ (defn start-server "Start nRepl server. Accepts options either as JS object or Clojure map." [opts] - (api/init-require (path/resolve "script.cljs")) - (let [port (or (:port opts) - 0) - host (or (:host opts) - "127.0.0.1" ;; default - ) - _log_level (or (if (object? opts) - (.-log_level ^Object opts) - (:log_level opts)) - "info") - server (node-net/createServer - (partial on-connect {}))] - ;; Expose "app" key under js/app in the repl - (.listen server - port - host - (fn [] - (let [addr (-> server (.address)) - port (-> addr .-port) - host (-> addr .-address)] - (println (str "nREPL server started on port " port " on host " host " - nrepl://" host ":" port)) - (try - (.writeFileSync fs ".nrepl-port" (str port)) - (catch :default e - (warn "Could not write .nrepl-port" e)))))) - server) - #_(let [onExit (js/require "signal-exit")] - (onExit (fn [_code _signal] - (debug "Process exit, removing .nrepl-port") - (fs/unlinkSync ".nrepl-port"))))) + (-> (js/Promise.resolve (api/initialize (path/resolve "script.cljs") nil)) + (.then + (fn [] + (let [port (or (:port opts) + 0) + host (or (:host opts) + "127.0.0.1" ;; default + ) + _log_level (or (if (object? opts) + (.-log_level ^Object opts) + (:log_level opts)) + "info") + server (node-net/createServer + (partial on-connect {}))] + ;; Expose "app" key under js/app in the repl + (.listen server + port + host + (fn [] + (let [addr (-> server (.address)) + port (-> addr .-port) + host (-> addr .-address)] + (println (str "nREPL server started on port " port " on host " host " - nrepl://" host ":" port)) + (try + (.writeFileSync fs ".nrepl-port" (str port)) + (catch :default e + (warn "Could not write .nrepl-port" e)))))) + server))) + #_(let [onExit (js/require "signal-exit")] + (onExit (fn [_code _signal] + (debug "Process exit, removing .nrepl-port") + (fs/unlinkSync ".nrepl-port")))))) (defn stop-server [server] (.close server diff --git a/test-scripts/api-test/test.cljs b/test-scripts/api-test/test.cljs index 73936d5d..3bb1e08d 100644 --- a/test-scripts/api-test/test.cljs +++ b/test-scripts/api-test/test.cljs @@ -1,2 +1,4 @@ -(+ 1 2 3) +(require '[medley.core]) + +(first (keys (medley.core/index-by :id [{:id 1} {:id 2}])))