Skip to content

Instantly share code, notes, and snippets.

@metametadata
Last active July 14, 2017 18:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save metametadata/0ddcf40d698a27851d29592011e89f06 to your computer and use it in GitHub Desktop.
Save metametadata/0ddcf40d698a27851d29592011e89f06 to your computer and use it in GitHub Desktop.
Example of using NodeJS spawn in Lumo
(def child-process (js/require "child_process"))
(def on-exit (js/require "signal-exit"))
(defn -spawn
"Thin wrapper around NodeJS function.
Spawns the process in the background. Returns the created ChildProcess instance."
[command args options]
(let [name (str command " " (str/join " " args))]
(println "ᐅ" name)
(-> (.spawn child-process
command
(clj->js (sequence args))
(clj->js (merge {:stdio "inherit" :shell true} options)))
(.on "error" (fn [err] (throw (ex-info (str "Error executing a process: " err) {}))))
(.on "exit"
(fn [code signal]
(when (not (= code 0))
(throw (ex-info (str "Process " (pr-str name) " exited unsuccessfully. "
"Code = " (pr-str code)
", signal = " (pr-str signal) ".") {}))))))))
(defn spawn
"Spawns the process in the background.
Will not make app wait for process to exit.
Will kill the process if parent application exits.
Returns the created ChildProcess instance."
[command args options]
(let [process (-spawn command args options)]
; Do not wait for process to exit
(.unref process)
; Kill app process on exiting the parent script (otherwise, Ctrl+D will exit the parent but not the child process)
(on-exit (fn [_code _signal] (.kill process)))
process))
(defn spawn-sync
"Spawns the process synchronously."
[command args options]
(let [name (str command " " (str/join " " args))]
(println "ᐅ" name)
(let [result (.spawnSync child-process
command
(clj->js (sequence args))
(clj->js (merge {:stdio "inherit" :shell true} options)))]
(when (some? (.-error result))
(throw (ex-info (str "Error executing a process: " (.-error result)) {})))
(when (not (= (.-status result) 0))
(throw (ex-info (str "Process " (pr-str name) " exited with error code. Code = " (.-status result) ".") {}))))))
(comment
; Start app in background
(spawn "lein" ["trampoline" "with-profile" "-dev" "run"] {:cwd "../backend"})
; Run tests
(defn argv
"Returns passed CLI args. Example:
./run.cljs 1 2 3
js/process.argv = #js [/usr/local/Cellar/lumo/1.5.0/bin/lumo nexe.js ./run.cljs 1 2 3]
(argv) = [1 2 3]"
[]
(subvec (js->clj (.-argv js/process)) 3))
(spawn-sync "lein" (into ["test-refresh"] (argv)) {}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment