Welcome! Please see the About page for a little more info on how this works.

+1 vote
in tools.deps by

I'm considering writing a deps.edn tool implementation for shadow-cljs. Mostly because clj -Ttools install-latest makes it easy to install. Comparable to npm install shadow-cljs, although I have no intention of replacing that. Just offering alternate options.

The part however I'm absolutely not on board with and would like to opt out of is the pre-defined arguments parsing that is done for such tools. Has that been considered?

Tools are all invoked with a clojure map. However, the tooling already exists and has its own argument parsing. I want to avoid having to adjust all existing docs and always mentioning two ways to invoke stuff.

For example the most common command you'll run currently is

npx shadow-cljs watch app

Or, translated to what I'd want for tools

clj -Tshadow-cljs watch app

Which I believe is invalid, since it expects key/value pairs after the watch function. So it would need to be something like

clj -Tshadow-cljs watch :build :app

Currently this is all possible by conventional means of using clojure.main

 clj -M:shadow-cljs watch app

But that requires creating an alias and manually specifying :main-opts. It also cannot really take advantage of -Tinstall-latest.

I can think of many ways of letting tools opt-out of this behavior. Either by directly specifying it in the :tools/usage map of their deps.edn. Or via CLJ metadata on the namespace or vars directly, since the tooling resolves those already.

(ns my.tool
   {:tools/usage {:parse-args false}}

;; and/or

(defn watch
   {:tools/usage {:parse-args false}}
   [& args] ;; just the usual strings array

I feel this has been discussed before, but couldn't find it. Also, which library does the clojure.run.exec helper belong to? I couldn't find it.

1 Answer

+1 vote
selected by
Best answer

We don't plan to make any of the arg parsing optional - the -X and -T execution have a point of view, and tools not subscribing to this should use -M -m which gives you full control over arg parsing.

The clojure.run.exec ns is injected in the Clojure CLI (the code itself is in the brew-install repo). It's not easily available (somewhat intentionally) for external use as we have been evolving it over time and have not committed to a public api for that yet. I do expect that eventually it will be available, either in Clojure lib itself (which would make it analogous to clojure.main) or as a separate tiny lib.

Unfortunate for me, but probably a good thing to present a consistent API of sorts for users.