babashka

https://github.com/babashka/babashka. Also see #sci, #nbb and #babashka-circleci-builds .
jumar 2020-12-07T07:27:45.117300Z

Cool! Btw. there's no built-in alias for babashka.process?

borkdude 2020-12-07T07:45:16.117600Z

There isn’t

borkdude 2020-12-07T13:11:47.118600Z

If anyone here is using babashka on the cloud / serverless, you might want to reply here: https://www.reddit.com/r/Clojure/comments/k8fc5s/askreddit_have_you_tried_to_run_babashka_on_a/

mozinator2 2020-12-07T13:21:49.119700Z

It definitely would be more easy to do than to convert your clojure web app to be graalvm compatible

alidlorenzo 2020-12-07T16:49:32.122100Z

with latest Babashka, using babashka.process/process , setting any :env options map is causing command to fail

warnings can be silenced by the --no-warnings (-n) option
Assertion failed: (str1!= NULL), function add3strings, file string_utils.c, line 103.
not sure if I’m doing anything wrong, but only way script is working is by commenting out the env options. even an empty map causes that error

borkdude 2020-12-07T17:12:12.122400Z

that doesn't sound good, let me check

borkdude 2020-12-07T17:13:53.123Z

@alidcastano I can't repro that on my machine:

user=> (slurp (:out @(babashka.process/process ["ls"] {:env {"FOO" "BAR"}})))
what is your repro and which OS? latest = 0.2.4?

borkdude 2020-12-07T17:20:00.123300Z

Also please specify which binary you have downloaded

alidlorenzo 2020-12-07T17:32:50.123700Z

hm this works for me, so may be a mix of options I’m passing. testing that out now

borkdude 2020-12-07T17:33:21.123900Z

a standalone minimal repro would be most helpful.

alidlorenzo 2020-12-07T18:33:19.124100Z

https://github.com/alidlorenzo/bb-env-bug-repro

alidlorenzo 2020-12-07T18:33:32.124400Z

sorry it took a bit, was out for lunch

alidlorenzo 2020-12-07T18:33:58.124600Z

i’m on macos btw, bb version 0.2.4

borkdude 2020-12-07T18:44:55.124800Z

I can repro now, thanks

borkdude 2020-12-07T18:51:58.125Z

I think it's related to rlwrap perhaps.

borkdude 2020-12-07T18:52:04.125200Z

This works:

@(proc/process
 ["clj"]
 {:inherit true
  :env (merge (into {} (System/getenv)) {"FOO" "BAR"})
  :shutdown proc/destroy})

borkdude 2020-12-07T18:57:59.125400Z

I can reproduce the problem with this code:

(let [pb
      (java.lang.ProcessBuilder.
       ["clj"])]
  (.clear (.environment pb))
  (.inheritIO pb)
  (let [p (.start pb)]
    (.waitFor p)))
It doesn't matter if you run this with bb or clojure, you get the same error, which I think is coming from rlwrap

borkdude 2020-12-07T18:59:02.125600Z

Not sure why though.

borkdude 2020-12-07T19:04:45.125800Z

@alidcastano I found out by experimentation that rlwrap apparently expects TERM, HOME and PATH to be set correctly

borkdude 2020-12-07T19:08:23.126Z

https://github.com/borkdude/babashka/issues/671

alidlorenzo 2020-12-07T19:11:28.126400Z

hm should those properties be auto-included in env by babashka.process? or you think it’s better for user to explicitly set them?

alidlorenzo 2020-12-07T19:11:45.126600Z

thanks for finding source of error, btw.

borkdude 2020-12-07T19:11:59.126800Z

This isn't a bb or process specific problem. rlwrap could maybe give better errors when these env vars aren't set

1✔️
borkdude 2020-12-07T19:12:25.127Z

Why are you invoking clj and not clojure btw?

borkdude 2020-12-07T19:14:57.127400Z

Seems like this should have been fixed with this: https://github.com/hanslub42/rlwrap/pull/80

alidlorenzo 2020-12-07T19:15:51.127800Z

> Why are you invoking `clj` and not `clojure` btw? bad habit, i tend to forget difference and end up using shorter version. but error does seem to happen for both commands

borkdude 2020-12-07T19:19:16.128100Z

hmyeah, that needs at least PATH and HOME it seems. clojure is a bash script which needs that

borkdude 2020-12-07T19:19:27.128300Z

Why not pass through all env vars?

alidlorenzo 2020-12-07T19:20:50.128500Z

before using babashka process I was setting env vars like this, btw, which was not causing this error

(defn- set-process-env-vars
  "Set env vars on process builder environment object."
  [pb env-map]
  (let [env-obj (.environment pb)]
   (doseq [[k v] env-map]
     (.put env-obj (-> k name str) v))
    pb))

alidlorenzo 2020-12-07T19:21:18.128700Z

> Why not pass through all env vars? did not consider it. was mainly just passing the ones i knew i needed in my program

borkdude 2020-12-07T19:23:41.128900Z

ok, we could document this better. So the preferred way when adding things to the current env, would be this:

:env (assoc (into {} (System/getenv)) "FOO" "BAR")

alidlorenzo 2020-12-07T19:25:28.129100Z

yep doing something like that now - thanks for helping to track down issue!

borkdude 2020-12-07T19:26:20.129300Z

:thumbsup:

borkdude 2020-12-07T21:09:17.129500Z

@alidcastano btw, your shutdown hook should be something like proc/destroy or proc/destroy-tree since the hook will receive a map

2020-12-07T21:56:58.133Z

Hi! To patrice, I converting this following bash script: https://gist.github.com/mg6/7321d66ac93d9550322afd8aeec2789a It's still a draft, I want to refactor a little bit. Is it doseq the best candidate for looping and print out in this case? The Babashka version: https://gist.github.com/PrestanceDesign/7d5b8b577932f17660cdaf5b902e409c

borkdude 2020-12-07T21:58:18.133400Z

Looks good to me!

2020-12-07T22:00:56.134400Z

Ok great, thank you @borkdude ! I'll create a PR to add in BB's examples dir

borkdude 2020-12-07T22:03:05.135100Z

Cool. Can you use [skip ci] in your commit message? Then CircleCI won't get triggered. This is good practice when adding docs/examples.

1👍
borkdude 2020-12-07T22:05:03.135900Z

You might also want to do some error handling because on my macOS system the script doesn't work as expected.

borkdude 2020-12-07T22:06:41.136400Z

Also a description what the script is for would be nice, since it isn't entirely clear to me who and why this is for

dominicm 2020-12-07T22:13:54.137200Z

@borkdude curious what the error is on your machine?

borkdude 2020-12-07T22:14:24.137500Z

If you look at the error message returned from clojure shell:

p\nApple specific options (to be specified before mcast-group or host like all options)\n            -b boundif           # bind the socket to the interface\n            -k traffic_class     # set traffic class socket option\n            -K net_service_type  # set traffic class socket options\n            -apple-connect       # call connect(2) in the socket\n            -apple-time          # display current time\n"
"<http://speedtest-blr1.digitalocean.com|speedtest-blr1.digitalocean.com> =&gt; ms"

dominicm 2020-12-07T22:15:39.138300Z

One minor mistake I notice is that it should be (shell/sh "ping" "-c" "5" "-w3" endpoint)

1👍
dominicm 2020-12-07T22:16:47.138400Z

Sounds like maybe -w is a gnuism?

borkdude 2020-12-07T22:16:55.138700Z

That doesn't fix it for me:

(defn ping-result [endpoint]
  (let [{:keys [out err]} (shell/sh "ping" "-c" "5" "-w3" endpoint)]
    (prn err)
    (prn (str endpoint " =&gt; " (get-average out) "ms"))))

dominicm 2020-12-07T22:17:27.138800Z

Not listed here: https://nixdoc.net/man-pages/FreeBSD/man8/ping.8.html So I guess it's a gnuism.

dominicm 2020-12-07T22:17:42.139Z

Right, that's a separate "it's wrong", but the impl of some pings may be lenient to it. (gnu's is)

dominicm 2020-12-07T22:18:13.139200Z

@borkdude BSD uses -t instead of -w. See if that works?

dominicm 2020-12-07T22:18:59.139300Z

bb ping, cross-platform ping? :P

2020-12-07T22:20:59.139900Z

Yes, of course. In two words, the script allows you to define which DigitalOcean cloud datacenter (region) had best ping latency to take a server (droplet) on. Little bit, a cli version of this page: https://cloudpingtest.com/digital_ocean

borkdude 2020-12-07T22:25:52.140500Z

#!/usr/bin/env bb

;; explicit requires
(require '[babashka.curl :as curl]
         '[babashka.process :as p]
         '[clojure.string :as str])

(def url "<http://speedtest-ams2.digitalocean.com/>")

(def get-endpoints
  (let [{:keys [body]} (curl/get url)]
    (re-seq #"speedtest\-.+.<http://digitalocean.com|digitalocean.com>" body)))

(defn get-average [result]
  (-&gt; result
      str/split-lines
      last
      (str/split #"/")
      (get 4)))

(def mac?
  (str/starts-with? (System/getProperty "os.name") "Mac"))

;; TODO: test on Windows
(def timeout-arg (if mac? "-t3" "-w3"))

(defn ping-result [endpoint]
  (let [out (-&gt; (p/process ["ping" "-c" "5" timeout-arg endpoint]
                           {:out :string})
                p/check ;; crash on non-zero exit code with error output
                :out)
        msg (str endpoint " =&gt; " (get-average out) "ms")]
    (println msg)))

(doseq [endpoint get-endpoints]
  (ping-result endpoint))

2020-12-08T09:38:01.148500Z

Hi @borkdude! I have a question. I saw in your script version that you required explictily babashka.curl and clojure.string. I thought that alias are already present in some of last bb versions, right? Do you recommanded to always manually required?

borkdude 2020-12-08T09:38:45.148700Z

Are you using clj-kondo?

borkdude 2020-12-08T09:39:10.148900Z

Clj-kondo will give warnings if you use a namespace alias without a prior require.

borkdude 2020-12-08T09:39:39.149100Z

This is why I advice to always use explicit requires. I think it is also more readable. The built-in aliases are for command line one-liners. See https://book.babashka.org/#style

2020-12-08T09:40:58.149400Z

Yes I use clj-kindo with Flycheck in my Spacemacs conf

2020-12-08T09:41:04.149600Z

borkdude 2020-12-08T09:41:23.150Z

Right, so when adding explicit requires these warnings go away

borkdude 2020-12-08T09:41:49.150200Z

The script will work either way, it's just a style thing

2020-12-08T09:43:26.150400Z

OK, I understand, thanks! I also prefer when my linting is clean so now I go for the explicit requires 👍

2020-12-08T09:43:38.150600Z

Perfect!

borkdude 2020-12-07T22:25:58.140700Z

^ some feedback @admin055

borkdude 2020-12-07T22:26:31.140800Z

nice! you could include that in the README

borkdude 2020-12-07T22:29:10.141500Z

I can test this on Windows too, but not tonight :)

2020-12-07T22:44:01.142800Z

I just tested your updated version (with process) and I had this error

----- Error --------------------------------------------------------------------
Type:     clojure.lang.ExceptionInfo
Message:  
Location: /home/mike/Lab/Clojure/Babashka/digitalocean-ping.clj:25:13

----- Locals -------------------------------------------------------------------
endpoint: "<http://speedtest-ams2.digitalocean.com|speedtest-ams2.digitalocean.com>"

borkdude 2020-12-07T22:45:52.143300Z

I have removed :err :inherit from the above example, did you copy that?

2020-12-07T22:47:14.144Z

Yes. Same error with the modified version.

borkdude 2020-12-07T22:48:07.144600Z

What's the return code of ping when you execute ping from the command line?

borkdude 2020-12-07T22:48:54.145200Z

Feel free to change back to clojure shell, this is just a way to trigger an error when there's something suspicious

2020-12-07T22:49:42.145900Z

OK I understand. 👍 FYI, the return code is 1

2020-12-07T22:50:20.146500Z

I'm on Linux Unbuntu.

borkdude 2020-12-07T22:51:08.147Z

If ping does not receive any reply packets at all it will exit with code 1. If a packet count and deadline are both specified, and fewer than count packets are received by the time the deadline has arrived, it will also exit with code 1. ... Otherwise it exits with code 0.
Maybe that's the case?

2020-12-07T22:53:21.147400Z

Thank you for everything and your availability! I'll continue tomorrow.

borkdude 2020-12-07T22:53:38.147700Z

Same here. Goodnight.

2020-12-07T22:53:38.147800Z

🙏

2020-12-07T22:53:55.148200Z

Thx, goodnight. 🙂

alidlorenzo 2020-12-07T23:01:21.148300Z

ah ok, thanks for catching that