Fork me on GitHub
#babashka
<
2022-01-22
>
Richie02:01:19

Hey. I figured out how to call shadow-cljs on the command line but I haven't figured out how to call it from my bb.edn file with shell . npx shadow-cljs compile web --config-merge {:output-dir,\\\"target/fun\\\"} This works. How do I put this into a string so that I can call (shell "npx shadow-cljs compile web --config-merge ...output-dir...target/fun... Everything I've tried gives me some kind of runtime exception for not being able to parse the argument. I'm on windows. I think cider uses base64 encoding somehow to avoid this issue...

Richie02:01:11

Any solution is good. shell, sh, or process, whatever.

Richie03:01:46

Here: (shell "npx shadow-cljs compile web --config-merge \"{:output-dir,\\\\\\\"target/fun\\\\\\\"}\"") This works. That wasn't fun.

Drew Verlee03:01:10

Shadow has a client api you can call directly from clojure. Not sure that means it would work from bb.

Drew Verlee03:01:40

That would avoid using shell

Richie04:01:48

Thank you. If I struggle with something like this again then I'll try it out.

borkdude06:01:55

You can pass multiple separate strings

borkdude06:01:31

I've also called shadow from bb in several projects like this. I'll paste later today

borkdude06:01:12

I think removing the slashes should improve the situation, no idea why you out them there but making the map a separate arg after the first string should also work

borkdude08:01:39

Here's a snippet from one of my other projects:

build:cljs:snapshot {:doc "Builds production JS"
                       :task (shell {:extra-env {"DUCTILE_STATIC_CLERK" "true"}}
                                    "yarn shadow-cljs release ui" "--config-merge"
                                    "{:closure-defines {ductile.ui.routes/root-view \"devdocs/index\"}}")
                       :depends [yarn-install]}

Richie15:01:46

(shell "npx shadow-cljs release web" "--config-merge" (format "{:output-dir \"%s\"}" output-dir))
result
shadow-cljs - config: C:\Users\richie\project\shadow-cljs.edn

Error while parsing option "--config-merge {:output-dir": java.lang.RuntimeException: EOF while reading
and this just in case
(shell "npx shadow-cljs release web" "--config-merge" "{:output-dir \"target/fun\"}")
result
Error while parsing option "--config-merge {:output-dir": java.lang.RuntimeException: EOF while reading
This is on windows. I just tested on mac and I do not have this issue on mac. Thanks!

borkdude16:01:13

Not sure what's going on here to be honest!

borkdude16:01:23

Can you try {:escape identity} as part of your options to shell?

borkdude16:01:35

(shell {:escape identity} ...)

borkdude16:01:40

see if that helps...

Richie16:01:02

No change in the output. Identical error.

Richie16:01:59

(shell {:escape (fn [x] (println x) x)} "npx shadow-cljs release web --config-merge {:output-dir \"target/fun\"}")
gives
npx
shadow-cljs
release
web
--config-merge
{:output-dir
target/fun
}

borkdude16:01:40

hmz, it seems the map is being split into parts

borkdude16:01:07

can you wrap the map in that string within single quotes?

borkdude16:01:19

(shell {:escape (fn [x] (println x) x)} "npx shadow-cljs release web --config-merge '{:output-dir \"target/fun\"}'")

borkdude16:01:35

within the first string, things with spaces are regarded as separate args

borkdude16:01:49

but successive strings are not split

Richie16:01:57

(shell {:escape (fn [x] (println x) x)} "npx shadow-cljs release web --config-merge '{:output-dir \"target/fun\"}'")
gives
npx
shadow-cljs
release
web
--config-merge
{:output-dir "target/fun"}
shadow-cljs - config: C:\Users\richie\project\shadow-cljs.edn

Error while parsing option "--config-merge {:output-dir": java.lang.RuntimeException: EOF while reading

borkdude16:01:48

what you can do is put that map in an .edn file and then just refer to the edn file instead

borkdude16:01:53

--config-merge foo.edn

Richie16:01:37

(shell {:escape (fn [x] (println x) x)} "npx shadow-cljs release web --config-merge '{:output-dir,\"target/fun\"}'")
gives
npx
shadow-cljs
release
web
--config-merge
{:output-dir,"target/fun"}
shadow-cljs - config: C:\Users\richie\project\shadow-cljs.edn
[:web] Compiling ...
Invalid configuration
-- Spec failed --------------------

  {:output-dir target/fun,
               ^^^^^^^^^^
   :compiler-options ...,
   :build-hooks ...,
   :modules ...,
   :devtools ...,
   :build-id ...,
   :asset-path ...,
   :target ...}

should satisfy

  non-empty-string?

Richie16:01:59

I added a comma.

Richie16:01:25

Oh neat. Thanks for that tip.

borkdude16:01:41

just use the file approach. windows can behave weird with spaces and quotes in args. it could also be something in shadow

Richie16:01:41

{:enter (do
          (def opts (parse-opts *command-line-args* [[nil "--output-dir OUTPUT-DIR"]]))
          (def conf (edn/read-string (slurp "shadow-cljs.edn"))))
 :task (let [output-dir (or (:output-dir (:options opts))
                            (get-in conf [:builds :web :output-dir]))]
         (shell {:escape (fn [x] (println x) x)} "npx shadow-cljs" "release" "web" (format "--config-merge \\\"{:output-dir \\\\\\\"%s\\\\\\\"}\\\"" output-dir)))}
This works. +1 for not needing a comma. I'm currently reading the output-dir from a cli parameter. I don't need this but it's helpful atm so I'll keep using it in the near-term.

Richie16:01:45

Thank you!

borkdude16:01:19

ok, you could also first spit out the map to a temporary file on disk and then use that file name

borkdude16:01:35

Instead of :enter you probably want to put that in :init . enter is executed before every individual task

borkdude16:01:05

oh I misread, you want to do this before this specific task

Richie16:01:36

You're right. I can definitely put (def conf in :init

Richie17:01:00

(defn escape
  [s]
  (str/join ""
            (flatten
             (replace {\\ [\\ \\]
                       \" [\\ \"]}
                      s))))
(escape (format "--config-merge %s" (pr-str (pr-str {:output-dir "target/fun"}))))
;; "--config-merge \\\"{:output-dir \\\\\\\"target/fun\\\\\\\"}\\\""

borkdude17:01:37

that looks scary....

borkdude17:01:20

a temp file sounds easier to me :)

robert-stuttaford09:01:02

forgive a noob question (can you tell i don't write much cli stuff :D) how would rewrite this so i can put it into my bb.edn? specifically, the output to carve.txt : clj -Tcarve carve! > carve.txt

borkdude09:01:34

I think this should work:

(clojure {:out "carve.txt"} "-Tcarve carve!")

borkdude09:01:00

I tested this and it worked:

{:tasks {foo (clojure {:out "/tmp/sum.txt"} "-M -e '(+ 1 2 3)'")}}

borkdude12:01:24

Survey time! Please leave your feedback on how you are using #babashka! I will publish the results as an article later. https://forms.gle/ko3NjDg2SwXeEoNQ9

5
Richie15:01:31

I'm trying to determine if my bb.edn is running on windows or not.

{:tasks
 {:requires [[babashka.main :refer [windows?]]]
  test (println windows?)}}
gives
Message:  Could not find namespace: babashka.main.
but it's here in babashka.main https://github.com/babashka/babashka/blob/master/src/babashka/main.clj#L59 Thanks again!

borkdude15:01:51

@rgkirch you can use babashka.core :refer [windows?] - it's a function. the code in the babashka repo does not reflect what's available in babashka itself.

Richie15:01:28

Perfect, thanks!

David Pham23:01:31

I answered the survey, but I forgot that I would love to have datascript inside babashka as default feature 🙂

4
teodorlu18:01:02

I just finished too -- and embedded datascript would be great. Though I don't know how hard that is to achieve.

David Pham23:01:47

I can you can have it as a feature flag though