Skip to content

Commit 3db233a

Browse files
committed
split readme; reorg code; start more detailed docs
1 parent 2168a34 commit 3db233a

File tree

5 files changed

+527
-306
lines changed

5 files changed

+527
-306
lines changed

README.md

Lines changed: 7 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This project follows the version scheme MAJOR.MINOR.COMMITS where MAJOR and MINO
88

99
Latest stable release: 1.0.219
1010

11-
* [All Released Versions](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.clojure%22%20AND%20a%3A%22tools.cli%22)
11+
* [All Released Versions](https://central.sonatype.com/artifact/org.clojure/tools.cli/versions)
1212

1313
* [Development Snapshot Versions](https://oss.sonatype.org/index.html#nexus-search;gav~org.clojure~tools.cli~~~)
1414

@@ -17,7 +17,7 @@ Latest stable release: 1.0.219
1717
org.clojure/tools.cli {:mvn/version "1.0.219"}
1818
```
1919

20-
[Leiningen](https://github.com/technomancy/leiningen) dependency information:
20+
[Leiningen](https://leiningen.org/) dependency information:
2121
```clojure
2222
[org.clojure/tools.cli "1.0.219"]
2323
```
@@ -105,136 +105,11 @@ http://clojure.github.io/tools.cli/index.html#clojure.tools.cli/parse-opts
105105
An interesting library built on top of `tool.cli` that provides a more compact,
106106
higher-level API is [cli-matic](https://github.com/l3nz/cli-matic).
107107

108-
## Since Release 0.3.x
109-
110-
### Better Option Tokenization
111-
112-
In accordance with the [GNU Program Argument Syntax Conventions][GNU], two
113-
features have been added to the options tokenizer:
114-
115-
* Short options may be grouped together.
116-
117-
For instance, `-abc` is equivalent to `-a -b -c`. If the `-b` option
118-
requires an argument, the same `-abc` is interpreted as `-a -b "c"`.
119-
120-
* Long option arguments may be specified with an equals sign.
121-
122-
`--long-opt=ARG` is equivalent to `--long-opt "ARG"`.
123-
124-
If the argument is omitted, it is interpreted as the empty string.
125-
e.g. `--long-opt=` is equivalent to `--long-opt ""`
126-
127-
[GNU]: https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
128-
129-
### In-order Processing for Subcommands
130-
131-
Large programs are often divided into subcommands with their own sets of
132-
options. To aid in designing such programs, `clojure.tools.cli/parse-opts`
133-
accepts an `:in-order` option that directs it to stop processing arguments at
134-
the first unrecognized token.
135-
136-
For instance, the `git` program has a set of top-level options that are
137-
unrecognized by subcommands and vice-versa:
138-
139-
git --git-dir=/other/proj/.git log --oneline --graph
140-
141-
By default, `clojure.tools.cli/parse-opts` interprets this command line as:
142-
143-
options: [[--git-dir /other/proj/.git]
144-
[--oneline]
145-
[--graph]]
146-
arguments: [log]
147-
148-
When :in-order is true however, the arguments are interpreted as:
149-
150-
options: [[--git-dir /other/proj/.git]]
151-
arguments: [log --oneline --graph]
152-
153-
Note that the options to `log` are not parsed, but remain in the unprocessed
154-
arguments vector. These options could be handled by another call to
155-
`parse-opts` from within the function that handles the `log` subcommand.
156-
157-
### Options Summary
158-
159-
`parse-opts` returns a minimal options summary string:
160-
161-
-p, --port NUMBER 8080 Required option with default
162-
--host HOST localhost Short and long options may be omitted
163-
-d, --detach Boolean option
164-
-h, --help
165-
166-
This may be inserted into a larger usage summary, but it is up to the caller.
167-
168-
If the default formatting of the summary is unsatisfactory, a `:summary-fn`
169-
may be supplied to `parse-opts`. This function will be passed the sequence
170-
of compiled option specification maps and is expected to return an options
171-
summary.
172-
173-
The default summary function `clojure.tools.cli/summarize` is public and may
174-
be useful within your own `:summary-fn` for generating the default summary.
175-
176-
### Option Argument Validation
177-
178-
By default, option validation is performed immediately after parsing, which
179-
means that "flag" arguments will have a Boolean value, even if a `:default`
180-
is specified with a different type of value.
181-
182-
You can choose to perform validation after option processing instead, with
183-
the `:post-validation true` flag. During option processing, `:default` values
184-
are applied and `:assoc-fn` and `:update-fn` are invoked. If an option is
185-
specified more than once, `:post-validation true` will cause validation to
186-
be performed after each new option value is processed.
187-
188-
There is a new option entry `:validate`, which takes a tuple of
189-
`[validation-fn validation-msg]`. The validation-fn receives an option's
190-
argument *after* being parsed by `:parse-fn` if it exists. The validation-msg
191-
can either be a string or a function of one argument that can be called on
192-
the invalid option argument to produce a string:
193-
194-
["-p" "--port PORT" "A port number"
195-
:parse-fn #(Integer/parseInt %)
196-
:validate [#(< 0 % 0x10000) #(str % " is not a number between 0 and 65536")]]
197-
198-
If the validation-fn returns a falsey value, the validation-msg is added to the
199-
errors vector.
200-
201-
### Error Handling and Return Values
202-
203-
Instead of throwing errors, `parse-opts` collects error messages into a vector
204-
and returns them to the caller. Unknown options, missing required arguments,
205-
validation errors, and exceptions thrown during `:parse-fn` are all added to
206-
the errors vector.
207-
208-
Any option can be flagged as required by providing a `:missing` key in the
209-
option spec with a string that should be used for the error message if the
210-
option is omitted.
211-
212-
The error message when a required argument is omitted (either a short opt with
213-
`:require` or a long opt describing an argument) is:
214-
215-
`Missing required argument for ...`
216-
217-
Correspondingly, `parse-opts` returns the following map of values:
218-
219-
{:options A map of default options merged with parsed values from the command line
220-
:arguments A vector of unprocessed arguments
221-
:summary An options summary string
222-
:errors A vector of error messages, or nil if no errors}
223-
224-
During development, parse-opts asserts the uniqueness of option `:id`,
225-
`:short-opt`, and `:long-opt` values and throws an error on failure.
226-
227-
### ClojureScript Support
228-
229-
As of 0.4.x, the namespace is `clojure.tools.cli` for both Clojure and
230-
ClojureScript programs. The entire API, including the legacy (pre-0.3.x)
231-
functions, is now available in both Clojure and ClojureScript.
232-
233-
For the 0.3.x releases, the ClojureScript namespace was `cljs.tools.cli` and
234-
only `parse-opts` and `summarize` were available.
235-
236108
## Example Usage
237109

110+
This is an example of a program that uses most of the `tools.cli` features.
111+
For detailed documentation, please see the docstring of `parse-opts`.
112+
238113
```clojure
239114
(ns cli-example.core
240115
(:require [cli-example.server :as server]
@@ -287,6 +162,8 @@ only `parse-opts` and `summarize` were available.
287162
;; case any :default value is used as the initial option value rather than nil,
288163
;; and :default-fn will be called to compute the final option value if none was
289164
;; given on the command-line (thus, :default-fn can override :default)
165+
;; Note: validation is *not* performed on the result of :default-fn (this is
166+
;; an open issue for discussion and is not currently considered a bug).
290167

291168
(defn usage [options-summary]
292169
(->> ["This is my program. There are many like it, but this one is mine."

doc/cljdoc.edn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{:cljdoc.doc/tree [["Readme" {:file "README.md"}]
2+
["Changes" {:file "CHANGELOG.md"}]
3+
["Command-Line Options" {:file "doc/parse-opts.md"}]
4+
["Changes since 0.3.x" {:file "doc/new-in-0-4.md"}]]}

doc/new-in-0-4.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
## Improvements in 0.4.x
2+
3+
This section highlights the changes/improvents in the 0.4.x series of
4+
releases, compared to the earlier 0.3.x series.
5+
6+
As a general note, `clojure.tools.cli/cli` is deprecated and you should
7+
use `clojure.tools.cli/parse-opts` instead. The legacy function will remain
8+
for the foreseeable future, but will not get bug fixes or new features.
9+
10+
### Better Option Tokenization
11+
12+
In accordance with the [GNU Program Argument Syntax Conventions][GNU], two
13+
features have been added to the options tokenizer:
14+
15+
* Short options may be grouped together.
16+
17+
For instance, `-abc` is equivalent to `-a -b -c`. If the `-b` option
18+
requires an argument, the same `-abc` is interpreted as `-a -b "c"`.
19+
20+
* Long option arguments may be specified with an equals sign.
21+
22+
`--long-opt=ARG` is equivalent to `--long-opt "ARG"`.
23+
24+
If the argument is omitted, it is interpreted as the empty string.
25+
e.g. `--long-opt=` is equivalent to `--long-opt ""`
26+
27+
[GNU]: https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
28+
29+
### In-order Processing for Subcommands
30+
31+
Large programs are often divided into subcommands with their own sets of
32+
options. To aid in designing such programs, `clojure.tools.cli/parse-opts`
33+
accepts an `:in-order` option that directs it to stop processing arguments at
34+
the first unrecognized token.
35+
36+
For instance, the `git` program has a set of top-level options that are
37+
unrecognized by subcommands and vice-versa:
38+
39+
git --git-dir=/other/proj/.git log --oneline --graph
40+
41+
By default, `clojure.tools.cli/parse-opts` interprets this command line as:
42+
43+
options: [[--git-dir /other/proj/.git]
44+
[--oneline]
45+
[--graph]]
46+
arguments: [log]
47+
48+
When :in-order is true however, the arguments are interpreted as:
49+
50+
options: [[--git-dir /other/proj/.git]]
51+
arguments: [log --oneline --graph]
52+
53+
Note that the options to `log` are not parsed, but remain in the unprocessed
54+
arguments vector. These options could be handled by another call to
55+
`parse-opts` from within the function that handles the `log` subcommand.
56+
57+
### Options Summary
58+
59+
`parse-opts` returns a minimal options summary string:
60+
61+
-p, --port NUMBER 8080 Required option with default
62+
--host HOST localhost Short and long options may be omitted
63+
-d, --detach Boolean option
64+
-h, --help
65+
66+
This may be inserted into a larger usage summary, but it is up to the caller.
67+
68+
If the default formatting of the summary is unsatisfactory, a `:summary-fn`
69+
may be supplied to `parse-opts`. This function will be passed the sequence
70+
of compiled option specification maps and is expected to return an options
71+
summary.
72+
73+
The default summary function `clojure.tools.cli/summarize` is public and may
74+
be useful within your own `:summary-fn` for generating the default summary.
75+
76+
### Option Argument Validation
77+
78+
By default, option validation is performed immediately after parsing, which
79+
means that "flag" arguments will have a Boolean value, even if a `:default`
80+
is specified with a different type of value.
81+
82+
You can choose to perform validation after option processing instead, with
83+
the `:post-validation true` flag. During option processing, `:default` values
84+
are applied and `:assoc-fn` and `:update-fn` are invoked. If an option is
85+
specified more than once, `:post-validation true` will cause validation to
86+
be performed after each new option value is processed.
87+
88+
There is a new option entry `:validate`, which takes a tuple of
89+
`[validation-fn validation-msg]`. The validation-fn receives an option's
90+
argument *after* being parsed by `:parse-fn` if it exists. The validation-msg
91+
can either be a string or a function of one argument that can be called on
92+
the invalid option argument to produce a string:
93+
94+
["-p" "--port PORT" "A port number"
95+
:parse-fn #(Integer/parseInt %)
96+
:validate [#(< 0 % 0x10000) #(str % " is not a number between 0 and 65536")]]
97+
98+
If the validation-fn returns a falsey value, the validation-msg is added to the
99+
errors vector.
100+
101+
### Error Handling and Return Values
102+
103+
Instead of throwing errors, `parse-opts` collects error messages into a vector
104+
and returns them to the caller. Unknown options, missing required arguments,
105+
validation errors, and exceptions thrown during `:parse-fn` are all added to
106+
the errors vector.
107+
108+
Any option can be flagged as required by providing a `:missing` key in the
109+
option spec with a string that should be used for the error message if the
110+
option is omitted.
111+
112+
The error message when a required argument is omitted (either a short opt with
113+
`:require` or a long opt describing an argument) is:
114+
115+
`Missing required argument for ...`
116+
117+
Correspondingly, `parse-opts` returns the following map of values:
118+
119+
{:options A map of default options merged with parsed values from the command line
120+
:arguments A vector of unprocessed arguments
121+
:summary An options summary string
122+
:errors A vector of error messages, or nil if no errors}
123+
124+
During development, parse-opts asserts the uniqueness of option `:id`,
125+
`:short-opt`, and `:long-opt` values and throws an error on failure.
126+
127+
### ClojureScript Support
128+
129+
As of 0.4.x, the namespace is `clojure.tools.cli` for both Clojure and
130+
ClojureScript programs. The entire API, including the legacy (pre-0.3.x)
131+
functions, is now available in both Clojure and ClojureScript.
132+
133+
For the 0.3.x releases, the ClojureScript namespace was `cljs.tools.cli` and
134+
only `parse-opts` and `summarize` were available.

0 commit comments

Comments
 (0)