Fork me on GitHub
#tools-deps
<
2022-02-15
>
cjsauer16:02:34

How would I pass a JSON string as an arg to a clojure -X:bench execution when that JSON is generated by a sub-command? Example:

clojure -X:bench :json "$(my_cmd --blah)"
I keep getting errors like:
Unreadable arg: "{\"blah\": 1}"
Which suggest to me that the quoting is wrong

cjsauer16:02:45

I can't seem to find the magic incantation that gets the quoting right

Alex Miller (Clojure team)17:02:17

you need the outer double quotes for the inner to be evaluated

cjsauer17:02:19

I can pass the JSON in manually like this:

clojure -X:bench :json-plan '"{\"blah\": 1}"' 
And it works, but the single quotes seem to preclude the sub-command

Alex Miller (Clojure team)17:02:24

but you also need explicit double quotes

borkdude17:02:40

maybe "\"$(...)\""?

Alex Miller (Clojure team)17:02:49

so yeah, something like that

borkdude17:02:59

or just use -M -m :)

Alex Miller (Clojure team)17:02:13

or pipe into stdin and read that :)

borkdude17:02:14

or god forbid, a REPL

cjsauer17:02:48

"\"$(...)\"" results in clojure seeing only the opening { character...

cjsauer17:02:54

Yea, I may have to switch my approach here 😉

dpsutton17:02:59

or put it in a file and pass the file as the arg. would be helpful when keeping interesting test cases around

borkdude17:02:04

^ what he said

cjsauer17:02:12

Yep, I'll just do that

cjsauer17:02:15

thanks all

cjsauer17:02:34

Was breaking my fingers in the name of concision haha

cjsauer17:02:46

it must fit on one line

cjsauer17:02:17

Can -X functions read from stdin?

dpsutton17:02:01

we have an interesting test runner that can take a namespace, a list of namespaces, or a directory and run all tests contained in those. You could do similar logic so you can pass a file, a list of files, or a directory. clj -X:bench -json examples/weird/funky.json or clj -X:bench -json examples/stress or what have you. Or you can put different keys for the different types

cjsauer17:02:30

Nice. Actually it looks like I can just use (read-line) to grab the JSON from stdin!

borkdude17:02:49

in case it's multi-line: (slurp *in*)

🍻 1
cjsauer17:02:40

Thanks, that's probably safer

seancorfield17:02:46

@cjsauer Try '"'$(my_cmd --blah)'"' -- although that may still not work with the internal quoting.

seancorfield17:02:17

(but, yeah, reading JSON from stdin is likely to be easier than wrangling shell quoting)

borkdude18:02:31

@seancorfield The outer single quotes will prevent the $() from being "eval-ed"

seancorfield18:02:52

(! 678)-> echo '"'$(clojure -Spath)'"'
"src:/Users/sean/.m2/repository/org/clojure/clojure/1.11.0-beta1/clojure-1.11.0-beta1.jar:/Users/sean/.m2/repository/org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar:/Users/sean/.m2/repository/org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar"

seancorfield18:02:01

(but it does not handle quotes in the content unfortunately)

seancorfield18:02:38

(! 754)-> echo '"'$(cat deps.edn)'"'
"{:aliases { :hiccup {:extra-deps {hiccup/hiccup {:mvn/version "RELEASE"}}} :exec {:exec-fn [a b] :ns-default exec} :build {:extra-deps {io.github.seancorfield/build-clj {:local/root "/Developer/workspace/build-clj"}}} :build-slim {:extra-deps {io.github.seancorfield/build-clj {:local/root "/Developer/workspace/build-clj/slim"}}} :dev {:jvm-opts ["-Dclojure.compile.warn-on-reflection=true"]}}}"
so you'd need to pipe it through some sed escaping or some such...

seancorfield18:02:12

(! 755)-> echo '"'$(cat deps.edn|sed 's;";\\";g')'"'
"{:aliases { :hiccup {:extra-deps {hiccup/hiccup {:mvn/version \"RELEASE\"}}} :exec {:exec-fn [a b] :ns-default exec} :build {:extra-deps {io.github.seancorfield/build-clj {:local/root \"/Developer/workspace/build-clj\"}}} :build-slim {:extra-deps {io.github.seancorfield/build-clj {:local/root \"/Developer/workspace/build-clj/slim\"}}} :dev {:jvm-opts [\"-Dclojure.compile.warn-on-reflection=true\"]}}}"