Hello, friends! I’m relatively new to Clojure, and I first got introduced to Leiningen via “Clojure for the Brave and True.” Today, I spent a couple of hours setting up the tools clojure/`clj` on macOS and Windows, and also trying out clj-new and deps-new. It works well, but I’m struggling to grok the man page for clojure/`clj`, and mentally “map” the synopsis from the man page to the example deps-new commands. Because the synopsis in the man page for clojure/`clj` is a bit alien and dense to me, and I’m not sure how to read it correctly. More specifically, in the command clojure -Tnew app :name myusername/mynewapp, if I try to break it down into separate “pieces,” why is there no space between -T and new, as would be the case with most other command-line utilities. Is app a function name, and/or a parameter to -Tnew? Why is :name a keyword, but not app? Why is there a / between myusername and mynewapp if this is not a path, and is this one parameter or two? I’m trying to see how these “pieces” correspond to the synopsis in the man page (see screenshot). But I’m thoroughly confused, so I would appreciate it if someone could explain this to me as if I’m a first-grader with a learning disability. I apologize in advance for asking very basic stuff, but I want to ensure I understand.
Calling clojure cli with T invokes a tool aliased as the string following that T, everything else is arguments to the tool
You can see the command on the left maps to the 3rd option in the man page
-T is like -X in that it invokes a specific Clojure function and passes the command-line arguments as a hash map. -T is "tool" mode and implicitly uses :paths ["."] :replace-deps ... for building the classpath. -X is "exec" mode and uses the regular classpath, based on your deps.edn file.
Both options can take aliases, e.g., -T:foo uses the alias :foo when identifying dependencies and other data (such as default namespace etc). -Tbar is a special form that uses an installed tool called bar rather than an alias.
clojure -Ttools invokes the built-in tool called tools (which handles core tool-related functionality).
clojure -Ttools install lib/name '{... dependency ...}' :as tool-name invokes the install function in the tools tool's default namespace and passes a hash map with two keys (`:as` and lib/name) and that downloads the dependency and installs it under the tool-name for use with -T.
So, going back to your Q: clojure -Tnew app :name myusername/mynewapp invokes the app function in the default namespace of the tool installed as new and passes it a hash map {:name 'myusername/mynewapp}
deps-new declares its default namespace for tool usage here: https://github.com/seancorfield/deps-new/blob/develop/deps.edn#L6
So clojure -Tnew app ... invokes org.corfield.new/app specifically.
myusername/mynewapp is a qualified symbol name (just as io.github.seancorfield/deps-new is in the clojure -Ttools install ... command).
-T and -X treat the command-line arguments after the initial function name as key/value pairs that are parsed as EDN (sort of a superset of JSON that matches Clojure more closely, support symbols, keywords, hash maps, vectors, etc).
Amazing! Thanks, @seancorfield! I think what threw me off is how :name myusername/mynewapp is equivalent to {:name 'myusername/mynewapp}, and -T and -X treat the command-line arguments after the initial function name as key/value pairs. I also did not understand that -T invoked “another tool installed within the tool,” and how new in -Tnew is an alias to that tool, and app is a function within that tool. It makes a lot more sense now! Although I must admit that the synopsis in the man page is still quite difficult to read and understand.
The guide and the reference are more expansive and may be better background reading: https://clojure.org/guides/deps_and_cli (reference is linked from that)