Fork me on GitHub
#babashka
<
2022-05-25
>
ordnungswidrig13:05:17

Can you handle signals in babashka like pipe-signal-received? does?

ordnungswidrig13:05:28

ah, the signal branch 😉

borkdude13:05:00

So it's theoretically possible to support, but I haven't so far since that API is officially not stable / public

ordnungswidrig13:05:20

That API never was stable, right? I'm not an expert on this

borkdude13:05:47

And last time I asked that user, it turned out he actually just wanted to use shutdown hook instead of signals directly. Perhaps you have a similar X-Y problem?

borkdude14:05:56

(if you could explain more about you're problem we could potentially support it)

ordnungswidrig14:05:38

I want to build a shell-like tool in babasha. This requires to interrupt "Ctrl-C" and to manually handle it.

ordnungswidrig14:05:45

Also SIGWINCH etc.

borkdude14:05:08

ok, let me see if I can find that branch

borkdude14:05:08

ok, I pushed the signal branch now

borkdude14:05:25

once it's built I could point you to the right binary or you can try to build yourself

borkdude14:05:47

@U054UD60U I don't keep track of which OS you are using, which one was that?

ordnungswidrig14:05:57

Cool I'll try it

ordnungswidrig15:05:54

user=> (reify sun.misc.SignalHandler (handle [_ _] (println "Got signal" )))
java.lang.IllegalArgumentException: No matching clause: sun.misc.SignalHandler [at <repl>:20:1]
Any idea?

borkdude15:05:56

This can be added. But can you try with proxy?

ordnungswidrig08:05:29

A very basic shell implemented in babashka https://gist.github.com/ordnungswidrig/6605483ac429a399a644024a6736ecf0 (Needs a current beta, 0.8.3-SNAPHOT)

borkdude08:05:32

This requires the signal branch. But given that you have success with this, should I merge it? ;)

ordnungswidrig09:05:56

I don't see how the signal branch would do harm, except allowing you to shoot yourself into the foot in more arkane ways.

ordnungswidrig09:05:08

I only tested on MacOS though.

borkdude11:05:12

I'll add support for reify and then merge

borkdude11:05:08

Now available as snapshot release

ordnungswidrig11:05:40

Followup question, does rebel-readline work with babashka?

ordnungswidrig11:05:48

(I need to resist this rabbit hole)

borkdude11:05:11

No, because it depends on jline which is not available :(

borkdude11:05:30

Perhaps better luck with #nbb which supports everything the npm ecosystem has to offer

borkdude11:05:53

We could see how much binary size jline adds though

ordnungswidrig11:05:37

I have no idea how bb is actually working but could jline be provided as a pod?

borkdude11:05:22

They are already at jine3 now

borkdude11:05:38

As a pod, this can potentially work yes

borkdude11:05:57

probably not trivial

ordnungswidrig11:05:56

hmmm, that would give term io but not line editing, right?

borkdude11:05:50

I mean, you could make a similar pod for jline and theoretically it would work

ordnungswidrig11:05:55

I see. That would be another friday 😉

borkdude11:05:15

A think like this could work too: xterm https://babashka.org/xterm-sci/ This works in the browser and terminal

borkdude11:05:25

but requires a JS env like Node.js

borkdude11:05:31

Should work in nbb

borkdude12:05:27

$ bbm1 ~/Downloads/babash.bb
Welcome to babash...
ℬ ~/dev/babashka > ls
----- Error --------------------------------------------------------------------
Type:     java.lang.IllegalArgumentException
Message:  Don't know how to create ISeq from: clojure.lang.Symbol

ordnungswidrig12:05:17

Hmmm having a look. Probably some copy-and-paste error when editing the gist

borkdude12:05:23

$ bbm1 ~/Downloads/babash.bb
Welcome to babash...
ℬ ~/dev/babashka > "ls"
----- Error --------------------------------------------------------------------
Type:     java.lang.NoSuchFieldException
Message:  trim

borkdude12:05:49

I think you should not rely on *input* in scripts, just use /usr/bin/env/bb and *in* or read-line directly

ordnungswidrig12:05:27

Yes, maybe that horrible quick hack fires back now :thinking_face:

borkdude12:05:44

Btw, did you also know about process/$?

(require '[babashka.process :as process])

(defmacro $ [& args]
  `@(process/$ {:inherit true} ~@args))

($ ls -la)
($ echo "hello")

(let [x "hello"]
  ($ echo ~x))

borkdude12:05:57

It allows you to type symbols (as in bash) and unquote resolves variables from the environment

borkdude12:05:08

Arguably not that useful, but it's fancy

borkdude12:05:39

So this works:

($ echo "The sum of 1 2 and 3:" ~(+ 1 2 3))

borkdude12:05:54

You could wrap in your shell, everything in an implicit ($ ...) call

borkdude12:05:16

And then you would have Clojure eval :)

borkdude13:05:41

@U054UD60U Maybe a library which exposes all kinds of shell commands as functions (which can be composed and output edn data, or so) could work, which you could then run with rebel-readline for awesome terminal editing and could use in scripts with bb too

borkdude13:05:03

But with full preservation of normal Clojure semantics

borkdude13:05:51

But maybe exposing $ would just be sufficient already

ordnungswidrig13:05:17

that sounds tempting

borkdude13:05:48

One annoying thing about the JVM is that it doesn't support cd, so you would have to patch that by keeping track of some directory and then feeding that back into whatever file stuff you're doing.

user> cd "/tmp"
user> ls
Applications		Documents

borkdude13:05:11

unlike Node.js which does support it

borkdude13:05:21

so perhaps nbb would be a better foundation to build such a thing on

ordnungswidrig13:05:42

I just use an atom to track what the "shell" considers to be the current directory.

borkdude13:05:51

ah yeah, that works

ordnungswidrig13:05:18

For a shell it's just a special variable which is passed to exec

borkdude13:05:52

I guess so, but when you then start moving things around with (fs/copy ..) it behaves unexpectedly

ordnungswidrig13:05:13

true. that would require a lot of wrapping maybe. :thinking_face:

borkdude13:05:38

Yeah, I've been thinking about that

borkdude13:05:59

A global dynamic var which holds the cwd and several libraries like fs and process would take that into consideration

borkdude13:05:41

Seems like a reasonable thing, if you document the caveats

borkdude13:05:43

Maybe there should be a library babashka.cwd which other libraries in the ecosystem could then also look at

borkdude13:05:03

if those wanted to support a similar feature without babashka

ordnungswidrig13:05:13

I wonder if the cwd is a concept of posix for a process.

ordnungswidrig13:05:34

> One excerpt from the bug database that highlights the issues with adding such a call: >> EVALUATION >> This feature can be interpreted in two ways: chdir could change the current working directory of the process containing the JVM, causing all threads to change simultaneously, or to provide a more "virtual" per-thread concept of current directory, which could conceptually be a ThreadLocal. This would be merely a convenience for building up complete path names to pass to the underlying operating system API. >> This is how the current directory works in Emacs - it's just a variable, but a magic one that can have buffer-local values. Emacs buffers are kinda sorta like Java threads in this sense. Such an implementation would offer convenience and safety. Having each thread with a ThreadLocal current directory gives a programmer experience familiar to old Unix greybeards, except that Threads replace Processes. > >

ordnungswidrig13:05:41

Ha! Emacs knew it already.

borkdude13:05:59

Yes, implementing that as a dynamic var would have thread-local behavior. https://github.com/babashka/babashka/issues/1277

ordnungswidrig13:05:51

What happens when the jvm calls chdir via jni? :thinking_face: :rolling_on_the_floor_laughing:

borkdude13:05:28

But the problem is that the environment is cached , so (System/getenv. ...) calls don't really work

ordnungswidrig16:05:46

who do other processes do that? is the env updated when chdir is called?

borkdude16:05:12

you mean, like in Node.js?

ordnungswidrig16:05:30

I have no clue how node.js behaves here.

borkdude16:05:30

I don't get the question

borkdude16:05:55

The problem is that the JVM caches things on startup and considers them immutable: env but also working dir

borkdude16:05:08

so all JVM APIs assume it won't change and use the cached value

ordnungswidrig16:05:26

When I chdir(2) in a unix process and then later all getenv(3) to get PWD from it is PWD updated in the env?

borkdude16:05:00

oh, I don't know about PWD

ordnungswidrig16:05:40

It leas that's an env var in bash which contains the current working directory. But maybe something that bash manages.

borkdude16:05:25

> process.chdir("/tmp")
undefined
> process.env.PWD
'/Users/borkdude/dev/nextjournal'
> process.cwd()
'/private/tmp'

ordnungswidrig16:05:26

So I get that the JVM caches things, but does it look up the cwd from the environment or does it (properly) call getcwd(3)

ordnungswidrig16:05:42

That's nodejs, right?

borkdude16:05:05

The JVM just uses an immutable map to cache the env and the cwd (both are separate concerns but with the same problem)

ordnungswidrig16:05:16

when you exec sh -c pwd from there, what does it print?

borkdude16:05:32

This is why chdir and setenv are both not not working like you would expect in a JVM via JNI

borkdude16:05:50

> from there, from where?

borkdude16:05:43

> process.chdir("/tmp") undefined > child_process.execSync("pwd") <Buffer 2f 70 72 69 76 61 74 65 2f 74 6d 70 0a> > child_process.execSync("pwd").toString()

'/private/tmp\n'

ordnungswidrig16:05:45

The thing is that the changed env would only be relevant for a spawned sub process. And for that you can use /usr/bin/env to set all the updated values.

ordnungswidrig16:05:22

so for nodejs, it's just a cwd value maintained in nodejs but not even passed onto a forked process.

borkdude16:05:25

Well, you can already set a changed env for a subprocess:

(process [...] {:extra-env {"FOO" "BAR"}})

borkdude16:05:47

No, it is passed on to a forked process

borkdude16:05:58

tmp was the directory I changed to

ordnungswidrig16:05:12

child_process.execSync("pwd").toString() printed the old value?!

ordnungswidrig16:05:29

/tmp == /private/tmp ?

ordnungswidrig16:05:51

Maybe they also hooked "update the pwd" into execSync?

borkdude16:05:20

yes, /private/tmp is a symlink

borkdude16:05:58

They probably just mutate the cwd via the C API and everything is consistent with that

ordnungswidrig16:05:18

Only when you want to support changing the "current directory" for all clojure / babashka code.

borkdude16:05:44

I was describing how "they" = Node.js does it

ordnungswidrig16:05:01

For the specific needs of a shell tracking the "shell current directory" in a dynvar and passing to forked processes is sufficient.

borkdude16:05:19

for a shell yes

ordnungswidrig16:05:28

I would not call chdir via JNI an a JVM because nobody knows what happens 😛

borkdude16:05:45

if you chdir and then copy files, people expect you to be in that dir

borkdude16:05:59

so forked subprocesses work, but not APIs in the same process

ordnungswidrig16:05:35

unless "copy files" is a "shell operation"

ordnungswidrig16:05:59

IOW what you described earlier as wrapping all fs commands

ordnungswidrig16:05:04

hmmm, good point.

ordnungswidrig16:05:30

So maybe worth a try. JNI to chdir and then even .File.("something") should work?!

borkdude16:05:50

As I said, they cache the cwd on startup

borkdude16:05:01

so no, it probably won't work, but it would be good to double check

ordnungswidrig16:05:17

in java.io.File? 😱

borkdude16:05:27

no, globally in the JVM

borkdude16:05:46

and java.io.File and everything else use that cached value

ordnungswidrig16:05:17

But that's in the solaris port 😆

borkdude16:05:12

And this is nio

ordnungswidrig16:05:28

This is a mess.

borkdude14:05:45

Hi babashkians! https://github.com/clj-commons/etaoin on the Github master branch is now bb compatible. This means you can write your browser tests in #babashka! An example:

(ns etaoin
  (:require [babashka.deps :as deps]))

(deps/add-deps '{:deps {etaoin/etaoin {:git/url ""
                                       :git/sha "e1b7df647740536cec7b8528fe4c84ae21f94ab7"}}})

(require '[etaoin.api :as api])

;; brew install geckodriver

(def driver (api/firefox))

(api/go driver "")

(api/quit driver)

babashka 11
1
👏 5
1
🎉 1
lispyclouds18:05:28

How about calling us The Babushkas? seems quite fitting 😛

borkdude18:05:44

I don't want to offend any young people here

😂 1
rwstauner16:05:37

i've been using the pod for long time, but this is great news!

lread23:05:30

It’s a nice luxury with Babashka that I don’t have to worry about which JDK version folks might be using.