Fork me on GitHub
#babashka
<
2021-09-09
>
alexdavis11:09:44

I want to have a global bb script, say its in /src/project1/bin/bbscript , and I want to call it from anywhere (project1/bin is in my path) and give it a file as an argument like:

$ cd src/mynewproject
$ ls 
file.edn
$ bbscript -f file.edn
My problem is that I have a bb.edn file in /src/project1 so I need babashka to pick that up somehow. I tried this
#_( ;; Allow this script to be executed directly
   "cd" "$(readlink -f $(dirname $0)/..)"
   "exec" "bb" "$0" "$(readlink -f $(dirname $0)/..)" "$@" "$PWD"
   )
which picks up the bb.edn but now it doesn’t get the right file passed in (because its looking in the wrong directory)

borkdude11:09:17

@alex395 this is an interesting problem. I think we could make bb pick up on the bb.edn relative to the script but this requires some thinking, e.g. local paths in bb.edn like src, should they be resolved also relative to the script or not. this is what makes this a difficult issue

borkdude11:09:21

perhaps the local paths should always be resolved relative to the bb.edn, but I'm afraid I'll break something if I introduce this behavior

borkdude11:09:04

I've done something similar with nbb though: nbb /tmp/project/foobar.cljs picks up on /tmp/project/node_modules

alexdavis11:09:36

Yeah.. my quick fix was just to copy the bb.edn file into each directory I want to execute it, which works but isn’t great for obvious reasons

alexdavis11:09:43

couldn’t really think of a better way

borkdude11:09:29

so my suggestion just now is basically in this comment as well: https://github.com/babashka/babashka/discussions/869#discussioncomment-1115234

Adam Stokes11:09:11

You can also set BABASHKA_EDN

Adam Stokes11:09:45

but when you have deps that you want to utilize I ran into problems with this approach and just cd'ed into the top level directory where bb.end resides

borkdude11:09:38

BABASHKA_EDN is not a public/documented thing, only internally used right now for testing, it might disappear

borkdude11:09:08

@alex395 I guess you could make a bash wrapper like this:

export old_dir=$pwd
cd script_dir
bb "$@"
and then use old_dir to resolve any relative file arguments

borkdude11:09:11

I guess that's what you kind of did

borkdude11:09:26

Feedback welcome in the issue

borkdude11:09:47

I think my latest comment would work well for global scripts backed by a bb.edn

borkdude11:09:04

note that you can also use babashka.deps to add deps in a standalone script

Adam Stokes11:09:29

That was my only question, will that still work even though you aren't executing the script from where it resides?

borkdude11:09:53

we could also make an API to define tasks in a standalone script

Adam Stokes11:09:02

I would love to have that

borkdude11:09:20

(babashka.tasks/deftasks '{a ... b ...})

💯 2
borkdude11:09:01

I wonder how you would use that if you did this in global_scripts/script.clj

borkdude11:09:35

script.clj a and then (babashka.tasks/run (symbol (first *command-line-args*))) to run a?

Adam Stokes12:09:11

Not sure if this helps but I use this pattern for the subcommand stuff:

(defn -main
  [& args]
  (let [opts (parse-opts args cli-opts :in-order true)
        config (:config (:options opts))
        subcmd (first (:arguments opts))
        subcmd-args (rest (:arguments opts))]
    (cond
      (:help (:options opts)) (println usage)
      (= "help" subcmd) (println usage)
      (= "cluster" subcmd) (apply cluster/parse subcmd-args)
      (= "vm" subcmd) (apply vm/parse subcmd-args)
      :else (println usage))
    (config/save config/config)
    (shutdown-agents)))

Adam Stokes12:09:22

couldn't we do something like that?

borkdude12:09:59

The command parsing isn't what I'm interested in right now, just interested if deftasks would solve the global script + bb.edn problem(s)

borkdude12:09:23

I think (currently) you would still have the PWD + relative paths problem

borkdude12:09:47

so we might as well go with the "use bb.edn relative to script" solution

borkdude12:09:05

This would allow you to make a global bb.edn with multiple global scripts that can use it

borkdude12:09:18

and then put that dir on the path

Adam Stokes12:09:56

That would be super cool

borkdude12:09:08

I agree. This solution only occurred to me after working on #nbb so there is a nice cross-pollination there

borkdude12:09:22

node itself behaves like this

borkdude12:09:23

e.g.:

/foo/node_modules
/foo/script.js
/bar # no node_modules

/bar $ node ../foo/script.js # will use /foo/node_modules

Adam Stokes12:09:11

They also have this helper npx too that does some magic to find the right node_modules for whatever you are executing

borkdude12:09:06

yeah it finds binaries within your deps, but I don't think we will need that

borkdude12:09:20

unless we want to support executing scripts from your deps, but we already do this using bb -m foo.bar/some-fn

Adam Stokes12:09:00

Could probably just post that as a question to get feedback. I'm guessing most people are used to passing it in like youve described in the clj world

borkdude13:09:36

I think we should solve the other issue first before introducing more

👍 2
aaelony15:09:46

hi - I'm just learning babashka and I'm finding there are times when I'd like to "shell out" a command within bb. Do I need to require the sh library somehow or use babashka/process? A small example of how to just call ls -hlah from bb would be ideal. Thanks in advance

aaelony15:09:58

also - is babashka designed to replace things that might go into a .profile or .bashrc file (e.g. common aliases?)

aaelony15:09:35

Hi Dorab - I've seen the link you show which shows a clojure process. Looking for a bb example

dorab15:09:40

Ah. I misinterpreted your question then.

aaelony15:09:42

or maybe I need to study it more carefully. Is process not a "batteries included" part of babashka?

aaelony16:09:14

e.g. how does one do something like: bb -e '(require \'[babashka.process :as p]) '

aaelony16:09:35

getting closer with bb -e "(require '[babashka.process :as p]) (p/process \"ls\" ) " . I'll fiddle with it a bit more. Thanks

borkdude16:09:53

@U0CDMAKD0 you can also use (babashka.tasks/shell "ls") which is more like how you do it in a shell: it prints the output

👍 2
borkdude16:09:59

this is based on babashka.process

👍 2
aaelony16:09:23

I have this: bb -e "(require '[babashka.process :as p]) (-> (p/process [\"ls\" \"-la\"] {:out :string}) p/check :out println ) " is there a better way?

borkdude16:09:50

you can use :inherit true if you want the printing to happen from the process immediately

borkdude16:09:03

instead of :out :string

aaelony16:09:55

nice. thank-you, I'll tinker a bit more. Ultimately, I'd like to replace some of my lengthly .bashrc commands and aliases with babashka so understanding this will come in handy

aaelony16:09:28

bb -e '(-> (babashka.tasks/shell "ls" "-halt") :out )' works well, yet it also prints #object[java.lang.ProcessBuilder$NullInputStream 0x4fb6cba8 "java.lang.ProcessBuilder$NullInputStream@4fb6cba8"] after the directory listing.

aaelony16:09:33

Is there a way to elide that?

aaelony16:09:45

d'oh.. this solves it`bb -e '(-> (babashka.tasks/shell "ls" "-halt") {:out :string} )'`

aaelony16:09:04

all set, thank-you 🙂

aaelony15:09:29

I could of course do it in clojure, but trying to dabble in bb

borkdude18:09:49

Wrote a project that combines tools.build and bb.edn: https://github.com/clj-easy/graal-build-time

👀 2
pizzaspin 4
🎉 2