This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-05-24
Channels
- # aleph (1)
- # beginners (43)
- # calva (22)
- # cider (51)
- # clerk (1)
- # clj-kondo (20)
- # clojure (29)
- # clojure-denmark (1)
- # clojure-europe (73)
- # clojure-finland (28)
- # clojure-nl (1)
- # clojure-norway (7)
- # clojure-spec (7)
- # clojure-uk (4)
- # clojurescript (12)
- # data-science (2)
- # datomic (51)
- # events (1)
- # fulcro (20)
- # hyperfiddle (28)
- # integrant (6)
- # malli (20)
- # matrix (2)
- # music (1)
- # off-topic (66)
- # reitit (17)
- # releases (5)
- # ring (1)
- # shadow-cljs (31)
- # xtdb (6)
If I have a project at ~/somepath/deps.edn and I want to execute the '-main' in namespace 'hello', how do I do that from an arbitrary directory - other than writing a 3 line shell script;
#!/bin/bash
cd ~/somepath/
clojure -X hello/-main $*
I want something like,
$ clojure ??? ~/somepath/deps.edn -X hello/-main ...You can’t, but you can include it as a local dep somewhat cumbersomely
clojure -Sdeps ‘{:deps {a/b {:local/root “/some/path”}}}’ -X hello/-main
Depending on what you're really trying to do, I'd probably do:
(cd ~/somepath; clojure -X hello/-main ...)
which leaves you back in the directory you started in.(I often run (cd <somewhere>; <do something>)
style commands when I want to stay where I am but run a command somewhere else)
True... well since you asked... I'm trying to write a todo cli app which uses datomic. So I want to do a "list", "add", "delete", "all" and have it invoke 4 functions (or main with an extra argument.) Sort of a datomic hello world of sorts. My thought was to use three aliases. $ alias tlist = 'bla bla; clojure bla bla main bla tlist' <-- lists todo items not yet done $ alias tadd= 'bla bla; clojure bla bla main bla tadd' <-- adds a new todo item $ alias tdone = 'bla bla; clojure bla bla main bla tdone xx' <-- marks a todo item done $ alias tall = 'bla bla; clojure bla bla main bla tall xx' <- shows all todos current and marked done
Seems a tad clunky, but my goal is to be able to invoke these from any directory in the filesystem...
so I could do the alias xx='pushd; cd ....; clojure ....; popd' or use a shellscript for dispatch... its fine.
I have a ~/bin
directory on my PATH
and tend to drop stuff in there rather than use aliases much -- then you don't have to worry about how to process command-line arguments in an alias...
> I often run (cd <somewhere>; <do something>) style commands when I want to stay where I am but run a command somewhere else > Great tip! This feels like something I should have already been doing regularly for a long time. Yet I have never used it before.
A common one:
for d in oss/*; do (cd $d && git pull); done
Updates all of my open source projects.babashka supports this pattern now: when you invoke a script in a "remote" directory, it respects the bb.edn in that remote directory. This turned out to be pretty handy for system-wide scripts, so you don't have to change the current working directory or write a bash wrapper
Babashka also supports the --config argument, which allows you to specify the location of its config file. Relative paths are resolved based on that file's location.
This would be a very useful addition to clojure cli, as it avoids messing with the current working directory or wrangling edn on the command line
Would this be appropriate as an Ask Clojure @U064X3EF3?
except that it won't compensate for relative paths, local/roots, etc unlike bb's --config
(Just to be clear, because I was confused initially – deps.clj is a faithful but unofficial port of the tools.deps bash script)
So the original question is about being able to invoke an arbitrary clojure application from any directory. The trouble with cd-ing into the directory is it changes your working directory, which means you no longer have access to the files at the shell's pwd. I would recommend in this case that you use a clojure tool installation with a local dep coordinate.
clj -Ttools install com.myself.local/my-tool '{:local/root "/some/absolute/path"}' :as local-tool
This can then be invoked from anywhere as
clj -Tlocal-tool fun-name :some '"args"'
Although if you intend to distribute this to anyone besides yourself, I might recommend that instead of using the clojure tools cli in order to provide arguments, you might look into using jlink
and jpackage
to produce a standalone version of your application which you can then distribute via a package manager, and invoke like a normal command line tool.
Yeah, both are also good options.
For my own part I think that graalvm native binaries are good but losing classloader stuff is a pretty big cost for some applications and with AOT and jpackage you can still get pretty good startup time.