Closed jeroenvandijk closed 1 year ago
We used to generate Bash wrappers but we moved to Babashka wrappers for Windows support. We removed the original Bash wrappers so we only have to maintain one format for the time being.
It's possible this may change in the future once the code matures a bit more. Until then I suggest creating a Bash script manually to invoke bb -Sdeps
:
#!/usr/bin/env bash
bb -Sdeps '
{:deps {com.github.rads/watch {:git/url "https://github.com/rads/watch.git"
:git/tag "v0.0.4"
:git/sha "d5f36aa54e685f42f9592a7f3dd28badc3588c08"}}}
' -m rads.watch -- "$@"
$ chmod +x watch
$ ./watch --help
Usage: watch [utility]
Run arbitrary commands when files change.
Examples:
ls | watch
Thank you for the feedback. Removing the bash wrappers make sense.
I have found an alternative solution that I'll publish later. Basically I've played around with requiring-resolve
and being lazy about loading deps and parsing code. I now have a babashka task that compiles my project into one file. Most namespaces are put in strings and are only eval-ed when required. This saves quite some time in most cases, and by putting it in one file I can use bbin install compiled-output.clj
. I believe there are other options, e.g. with jar files, but I haven't tried this yet.
Maybe one of these strategies could be formalised as a part of the install process of bbin
, maybe not. I'll post a link to my example later.
Small update, some first tests seem to suggest that creating an uberjar (instead of inlining the code), and running from that is equivalent in boottime to the inlining option. I have the following bb.edn
for the tree options:
{:deps {deps/local {:local/root "."}}
:tasks
{install (shell "bbin" "install" ".")
generate-inline-script tasks/generate-inline-script
install-inline (do (run 'generate-inline-script)
(shell "bbin" "install" "target/inline.clj" "--as" "aws.console"))
install-jar (do
(shell "bb" "uberjar" "target/uberjar.jar")
(spit "target/uberjar-inline.clj" (clojure.string/join "\n" [
'(require '[babashka.classpath :refer [add-classpath]])
(list 'add-classpath (str (System/getenv "PWD") "/target/uberjar.jar"))
'(require '[aws.console])
'(apply aws.console/-main *command-line-args*)
]))
(shell "bbin" "install" "target/uberjar-inline.clj" "--as" "aws.console")
)
}
:bbin/bin {aws.console {:main-opts ["-f" "src/aws/console.clj"]}}
}
To me the uberjar route sounds like an interesting optimisation option for bbin. It would require to put the uberjar somewhere, but I'm guessing this would work on all operating systems.
I'm closing this issue, it's a little too broad in hindsight and after some testing I found that the uberjar has the best boottime. I had a discussion about this in Slack. The jar wrapper script would need to be patched to not use exec
, I'll create an issue for this later.
Thank you for creating this project. I did some tests and things work in a very clean way.
I'm trying to minimize the startup time of my cli tool. When I install it with
bbin
it adds around 40ms extra due to how the wrapper script works (invokingbb
one more time). By writing my own wrapper script I could keep the total around 40ms, but this would limit the distribution options (only exact url or local file). Maybe it is possible to havebbin
provide a hook that would be called during installation in order to create a custom wrapper script?You might reason 40ms is not that much, but I'm working on a command line tool that I intend to use regularly and as a part of a chain of other binaries. Sometimes the binary is even executed multiple times in one invocation. This means that every addition in latency quickly adds up.
Maybe related to #18 and #40
I'll do some experimentation with my own wrapper script and report back later.