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

0 votes
ago in tools.cli by

Hello, newbie user of tools.cli here.

I'm having a use case where I'd like to describe dependencies between options.
For example : if option -a is used, then options -f and -d are required too.

Looking at the documentation, it seems that the function option :in-order may allow that, but I haven't been able to figure how to use it. And haven't found any tutorial on that topic.

Anyone who could provide some pointers and/or example on how to express such dependencies (if that's possible).

Thank you!

2 Answers

0 votes
ago by
selected ago by
 
Best answer

Here's one way to do it, but it requires for the -f and -d options to be specified on the command line before the -a option:

(let [opts [["-a" nil "something"
             :id :a
             :assoc-fn (fn [opts opt-id val]
                         (assoc opts opt-id
                                     (if (and (:file opts) (:dir opts))
                                       val
                                       ::missing-required)))
             :validate [#(not= % ::missing-required)
                        "Missing required -f and -d options"]
             :post-validation true]
            ["-f" "--file FILE" "file doc"]
            ["-d" "--dir DIR" "dir doc"]]]
  [(cli/parse-opts ["-a"] opts)
   (cli/parse-opts ["-f x" "-d y" "-a"] opts)])
=>
[{:options {},
  :arguments [],
  :summary "  -a               something\n  -f, --file FILE  file doc\n  -d, --dir DIR    dir doc",
  :errors ["Failed to validate \"-a \": Missing required -f and -d options"]}
 {:options {:file " x", :dir " y", :a true},
  :arguments [],
  :summary "  -a               something\n  -f, --file FILE  file doc\n  -d, --dir DIR    dir doc",
  :errors nil}]
0 votes
ago by

There's nothing built-in. The simplest solution would probably be to post-process the result of calling parse-opts to check that if :a is present, so are both :f and :d.

I often wrap parse-opts in a post-processing step for "global validation" (that takes the result of parse-opts and produces an identical structure, with extra :errors entries).

ago by
Yes, post-processing was my "backup" plan in case cli.tools had no support for this feature.
But as the order of options is not a problem for my use case, I'm going to use Eugene's solution.

Thank you very much to both of you for your answers.
...