Fork me on GitHub
#babashka
<
2023-06-14
>
leifericf09:06:03

I have written this function to find all Git repositories within a given directory:

(defn find-repos
  [search-path]
  (->> (babashka.fs/glob search-path "**.git" {:hidden true})
       (pmap #(str %))
       (pmap #(clojure.string/replace-first % #"/\.git$" ""))
       (doall)))
The regular expression removes the "filename part" of the path (`/.git`). While this works, it looks ugly, and I suspect it's not the best approach to use regular expressions to mess with the paths. Does babashka.fs have a function to get a path without the filename at the end? For context, the Bash script I'm replacing does this to execute Git commands in the found directories:
find . -name ".git" -maxdepth 2 -type d -execdir git pull \; -execdir git status \;
Notice the use of -execdir as opposed to -exec. I have written another function to execute a Git command within a directory:
(defn run-git-command
  [path command]
  (-> (process/sh {:dir path} "git" command)
      :out))
My plan is to combine find-repos with run-git-command to do the same. That's why I need the path without the filename.

leifericf09:06:22

Ahaaa, yeah! It looks like it. I missed that because I didn't think to look for the word "parent" in the docs 😅

👍 2
🙌 2
leifericf09:06:36

I'm quickly learning that one of my greatest weaknesses is not knowing what to search for and how to best navigate docs 😅

leifericf10:06:24

babashka.fs/parent was exactly what I needed 🙂

👍 2
teodorlu10:06:34

> I'm quickly learning that one of my greatest weaknesses is not knowing what to search for and how to best navigate docs 😅 > Not sure if I agree! I mostly know these things because Borkdude has been helping me out with stupid questions. Some things are hard to learn on one's own! I think asking "how would you ... ?" and "can I get feedback on this code?" questions is a great way to learn :)

👍 2
teodorlu10:06:47

I also think it's fair to just work with strings when you don't know the specific functions that could solve the task with less code. See for instance this thing I wrote: https://github.com/teodorlu/play.teod.eu/blob/42e9d3edc9dfe6958c2c87cbc2bde73d6c9f97fb/play.clj#L55 At that time, I wasn't familiar with babashka fs at all!

👀 2
lispyclouds10:06:31

Also as a side note, I’d recommend against the use of pmap pretty much everywhere, specially if you’re seeing the need to use a doall after it. pmap though is easy doesn’t really add much value and is almost always not a good choice when using with side effects.

lispyclouds10:06:56

This particular code the overhead from managing the threads and the laziness would probably defeat the gains that you’re looking for 🙂

2
lispyclouds10:06:03

Referring to the find-repos example from @U01PE7630AC

👍 4
leifericf10:06:02

Thanks for the advice, @U7ERLH6JX! When I use map it doesn't process the whole collection, so I had to use run! or doseq or pmap + doall. What would be the best approach in this scenario?

lispyclouds10:06:08

The problem with pmap is that it’s lazy and has chunking too like map. If you wanna do things in parallel and not care about laziness pmap is okay hence ruling out side effects. This thread should help: https://clojurians.slack.com/archives/C03S1KBA2/p1678968328528409

👀 2
👍 2
lispyclouds10:06:26

bb supports the nice executor framework that the JDK has and it’s a bit more involved but simpler solution. Also works nicely with the snappy virtual threads 😄

dpsutton14:06:13

I’m seeing some strange behavior with connecting over a socket repl. Details in thread:

dpsutton14:06:49

I’m starting bb with

❯ bb --socket-repl 5000
Babashka socket REPL started at 127.0.0.1:5000
Babashka v1.3.176 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.

user=>
and I can connect with netcat:
❯ netcat localhost 5000
Babashka v1.3.176 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.

user=>
Note this is over localhost

borkdude14:06:14

so far so good, right?

dpsutton14:06:51

if i connect with inf-clojure on localhost 5000, i’m never seeing any output like a repl prompt. If i send stuff over localhost i see

(+ 1 1)

RTSP/1.0 403 Forbidden
Content-Length: 0
Server: AirTunes/675.4.1

dpsutton14:06:03

but if i connect on 127.0.0.1 everything seems to work fine

dpsutton14:06:19

does this ring a bell?

borkdude14:06:20

it seems like another server is running on that port maybe?

dpsutton14:06:38

well the netcat seems to find the bb socket server

borkdude14:06:58

but it connects to 127.0.0.1, perhaps "localhost" does something slightly different, not sure

borkdude14:06:20

is something weird in your /etc/hosts maybe?

borkdude14:06:53

perhaps try a different port like 11223344

dpsutton14:06:29

huh. yeah that seems to have worked

dpsutton14:06:44

bizarre. i guess something else is on port 5000? can they be multiplexed?

borkdude14:06:17

sudo lsof -i :5000 on mac

borkdude14:06:34

COMMAND    PID     USER   FD   TYPE            DEVICE SIZE/OFF NODE NAME
ControlCe 2829 borkdude   21u  IPv4 0x7e0ffdd84f48315      0t0  TCP *:commplex-main (LISTEN)
ControlCe 2829 borkdude   22u  IPv6 0x7e0ffe24fd6c5cd      0t0  TCP *:commplex-main (LISTEN)

borkdude14:06:39

seems mac is running something on there

dpsutton14:06:00

yeah i have similar. weird that it works for netcat

borkdude14:06:39

does netcat localhost also work, instead of 127.0.0.1 then?

dpsutton14:06:22

netcat always sees bb on port 5000

dpsutton14:06:28

but emacs seems to see the airplay service

borkdude14:06:37

yeah, dunno :)

dpsutton14:06:05

well thanks for the help as always @U04V15CAJ

👍 2
respatialized15:06:06

when using babahska.process, can I stream the process output to *out*? using *out* for :out in the option map appears to only redirect the final output of the script after it completes, not while it is running.

borkdude15:06:56

This is due to buffering. But there's already a stream by default with process/process and you can just read from that manually

borkdude15:06:31

You can also use {:out :inherit} if you don't actually want to capture it, but see it as it's written

borkdude15:06:10

The shell function does this by default

respatialized15:06:51

by default, :inherit goes to stdout of where my REPL was launched (which is a terminal window). can I get the same behavior as :inherit but for my REPL connection?