This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-05-20
Channels
- # adventofcode (7)
- # announcements (1)
- # aws (1)
- # babashka (127)
- # bangalore-clj (1)
- # beginners (54)
- # calva (8)
- # cider (12)
- # clj-http (2)
- # clj-kondo (8)
- # cljdoc (10)
- # cljs-dev (2)
- # clojure (48)
- # clojure-australia (14)
- # clojure-dev (6)
- # clojure-europe (105)
- # clojure-nl (6)
- # clojure-taiwan (1)
- # clojure-uk (62)
- # clojurebridge (1)
- # clojurescript (112)
- # code-reviews (4)
- # cursive (20)
- # data-science (1)
- # depstar (1)
- # events (8)
- # fulcro (6)
- # graalvm (11)
- # honeysql (2)
- # introduce-yourself (3)
- # jobs (1)
- # jobs-discuss (30)
- # malli (23)
- # nrepl (4)
- # off-topic (47)
- # pedestal (22)
- # polylith (10)
- # portal (3)
- # re-frame (16)
- # reitit (9)
- # releases (3)
- # rewrite-clj (1)
- # ring (1)
- # spacemacs (1)
- # tools-deps (12)
- # xtdb (7)
does bb handle aliases? -A:dev and such?
I guess the better questions is how do I load fuctions in to the user namespace?
@U3F5EM2TD Can you explain your use case?
bb has an :tasks {:init ...}
section where you can put startup code when you invoke a task
It also has a BABASHKA_PRELOADS
environment variable that can contain code that is always executed before anything else
I just wanted to preload some helpful functions in the user namespace for this one project.
Let me try the tasks thing that could be it. I'm assuming BABASHKA_PRELOADS runs on every evocation of bb? And I only need this helper code for this project and only during development.
babashka 0.4.2-0.4.3:
- Better error handling in parallel tasks
- Add more agent functions and fix binding conveyance in send-via
- Better transit support for pods (fixes issue with mysql pod and java.time.LocalDateTime
results)
- Misc. other improvements
Not many developers realize it, but your little "clojure interpreter" has a support of concurrency such that virtually all popular scripting languages can't compete with at all π
FWIW I tried the static 0.4.1
release and it works like a charm π
This would be really useful to have, something that I miss from Python in my Babashka scripts
BTW, could this also be turned in a JVM library (like babashka.fs
is)?
Asking because one of the nice things of Babashka is that my codebase is 100% compatible with Clojure proper too
(But if isn't, no problem too, I can probably workaround just this case. The important part is just that I can call the function to set the env, not that it actually works in Clojure)
Yes, I want to release this is a library which can be used within babashka, but the hardest part is the name. Perhaps babashka.core? ;)
I have another function that could be in it: "exec"-ing the current process into another one
Basically these three things: https://github.com/babashka/babashka/labels/native
Babashka.x
π
Exec + a var
There are probably better names indeed
Than X I mean
So it would be a library specific to native image or even a smaller subset?
yes, set-env
and exec
sould only work in a native image. but those functions could be useful to all graalvm native projects
My 2 cents; I donβt recognize the name svm
, but maybe other graal people do. aux
could be anything I guess. So graal
and native
sound most descriptive to me.
I would suggest to follow the Python naming suggestions here, so babashka.os
seems ok to me
but it would be confusing maybe to have get-env
in babashka.process
since process
is about spawning new processes and os
is about the current process perhaps?
IMO, os
for me is for calling OS specific calls, so Python's os
exposes things like os.chdir
and os.getenv
(but there are implementations for them on Windows too, even when they're no-ops)
Right now I'm testing set-env
in babashka itself. There it doesn't work, weirdly enough.
BTW, any reason this library needs to be GraalVM specific? For example, couldn't we use JNI to implement a Java version compatible :thinking_face: ?
(Not saying that you need to implement it, just asking if it wouldn't make sense to make it more "generic")
$ ./bb -e '(babashka.utils/set-env "FOO" "BAR") (prn (System/getenv "FOO"))'
:setting "FOO" "BAR"
setenv FOO BAR
null
null
nil
@UFDRD93RR Here is the built branch: https://19176-201467090-gh.circle-artifacts.com/0/release/babashka-0.4.4-SNAPSHOT-linux-amd64-static.tar.gz
> These binaries are posted to #babashka-circleci-builds I always forget about this π
Well, let me setup a GraalVM environment since I generally build those things with Docker π
I also printed the return value now. It's 0.
$ ./bb -e '(babashka.utils/set-env "FOO" "bar") (prn (System/getenv "FOO"))'
:setting "FOO" "bar"
setenv FOO bar
null
null
0
nil
Can you print the result of System/getenv
right after setting it (still inside the Java code)?
Well, it is really strange:
diff --git a/src-java/babashka/impl/Graal.java b/src-java/babashka/impl/Graal.java
index 9754185..604b5f6 100644
--- a/src-java/babashka/impl/Graal.java
+++ b/src-java/babashka/impl/Graal.java
@@ -18,23 +18,22 @@ public class Graal {
@Override
public List<String> getHeaderFiles() {
- return Collections.singletonList("<stdlib.h>");
+ return Collections.singletonList("<stdio.h>");
}
}
@CFunction
- private static native int setenv(CCharPointer name, CCharPointer value, int overwrite);
+ private static native int puts(CCharPointer name);
// API
public static int setEnv(String name, String value) {
- int ret = 0;
+ int ret = -1;
System.out.println("setenv" + " " + name + " " + value);
try (CCharPointerHolder nameHolder = CTypeConversion.toCString(name);
CCharPointerHolder valueHolder = CTypeConversion.toCString(value)) {
- ret = setenv(nameHolder.get(), valueHolder.get(), 1);
- System.out.println(System.getenv(name));
+ ret = puts(nameHolder.get());
+ System.out.println(Integer.toString(ret));
}
- System.out.println(System.getenv(name));
return ret;
}
user=> (babashka.utils/set-env "this is the text that should be printed" "")
:setting "this is the text that should be printed" ""
setenv this is the text that should be printed
this is the text that should be printed
40
40
nil
Definitively seems to be working, but the setenv
does seems to do its job but it doesn't actually set the variable :thinking_face:In the latest commit on the set-env
branch this now works:
$ ./bb -e "(require '[babashka.os :as os])" -e '(prn (os/set-env "FOO" "BAR")) (prn (os/get-env "FOO"))'
true
"BAR"
Nice! FOO
should also be set outside of bb, right? So echo $FOO
returns "BAR"
?
Ah ok so it would be useful for processes relying on env vars invoked from within the babashka process, is that right?
yeah, although I don't know if processes invoked from babashka using processbuilder will even see the effect, since Java has its own way of handling this
ah good, that seems to work:
./bb -e "(require '[babashka.os :as os])" -e '(prn (os/set-env "dude" "1337")) @(babashka.process/process ["env"] {:inherit true})'
but you can already set those env vars as an arg to babashka.process
so for that use case it doesn't really matter
Maybe for nested process calls that you dont control :thinking_face:
Well, this cache actually makes sense since there is no way to set environment variables in JDK
@U04V15CAJ Could we also have unsetenv
wrapper?
@UFDRD93RR sure, we can support it if it works with GraalVM. But why would we do so?
For my usecase, I would like to set environment variables for the current process since I use them for some things While I could use another mechanism to have this "state" (like an atom), the subprocess also needs to inherit those environment variables So to use atom+`babashka.process`, I would probably need to always inject this environment variables to every subprocess (not exactly bad, but this gets old quickly)
@UFDRD93RR we could support this, but it can be confusing when people also use System/getenv
e.g. (os/set-env "JAVA_CMD" "foo/java")
followed by (clojure "something")
would not work, since clojure
uses System/getenv
In bb tasks you could accomplish setting an env variable with (shell {:extra-env {"FOO" "BAR"}} "bb some-other-task")
@UFDRD93RR Can you explain what you mean by this?
Well, it is actually complicated
We have a binary (let's call foo
) that is symlinked multiple times including the country info
So foo-br
is "foo for Brazil", foo-mx
is "foo for Mexico"
So I have to get the current script filename, parse it and set the environment variable (`FOO_COUNTRY=br` for foo-br
)
There is some alternatives, I could create a separate file that calls the main one and just set this environment variable
But after analyzing the code, the actual code works well enough and I don't think it would have any advantage of changing this now
(BTW, the most usage of the shell in this case is actually another shell script that I use to bootstrap babashka if not installed, this script can't be written in Babashka anyway since I would have a classic chicken-egg problem)
IMO, I would like to have something like babashka.os/set-env
, but only if we could make it work with System/getenv
, otherwise I think the drawbacks are worse than the benefits
we could patch System/getenv
but this would not work with calls that don't go through the interpreter
I think we can leave as is, if I (or someone else) find some case that it can't be workaround without changing the current env we could add with all the warnings and bells
(I feel like that I may hit this issue in the future again, but I also feel that this would be a good time to rethink the way do some things)
@U04V15CAJ Sorry about all the inconvenience about this, at least we now know that this is possible (with caveats)
@UFDRD93RR Absolutely no problem, I just started investigating to see if it was possible at all. And now I learned a bunch about C interop ;)