-
-
Notifications
You must be signed in to change notification settings - Fork 11
Description
Hi,
I've been wanting to parse options in a lenient way, so that unknown options are kept as free args. I found about unknown-option and treat-as-argument, the only issue is that run, which calls parse-command-line, handles everything with a handler-case. So I can't put a handler-bind around run to do my logic.
This is what I want to do:
(handler-bind ((clingon.conditions:unknown-option
(lambda (c)
(format t "debug: ~a: treating it as a free argument.~&" c)
(clingon:treat-as-argument c))))
(let ((app (top-level/command)))
(clingon:run app)))if you replace clingon:run by (clingon:parse-command-line (top-level/command) (list "whatever" "--xyz-unknown-option")) it works.
How could we allow run to be lenient?
option 1: wrap the parsing with handler-bind and add a key argument to the run function to tell how to manage the unknown-option, i.e. modularizing this:
(defmethod run ((top-level command) &optional arguments)
(handler-case
(handler-bind ((unknown-option
(lambda (c)
(treat-as-argument c))))
(let* ((arguments (or arguments (argv)))
(cmd (parse-command-line top-level arguments)))
…For completeness, we would need to do this for every condition, and change the method signature. Doesn't seem like ideal.
option 2: give the parse-command-line function as argument so I can provide my own.
option 3: I tried to locally override the parse function, with (flet ((clingon.command:parse-command-line (command arguments) …) (clingon:run)), to no avail, it's still using the original one. Maybe I'm doing it wrong.
option 4: copy-paste run and tweak it.
option 5 (brainstorming): somehow extract the parsing from run. We would have a chain of two functions:
(run (parse top/level))so I could use my parse function:
(run (my-parse top/level))More context (I'm brainstorming here too): my CLI looks like:
$ tool [options] free-arg
and this free arg names a lisp script that will in turn be loaded and executed.
I want to give more options to this script. I can use "--":
$ tool [options] free-arg -- -a
so far so good. But I managed to be able to call the script directly:
$ ./free-arg
it's still calling tool [options] free-arg under the hood though. This is where I'd like to not use "--", but give it options directly like a real script:
$ ./free-arg -a
if I do this, currently Clingon barks and exits because -a is an unknown option (if it was not defined with the options of tool).
There is the machinery to turn an unknown-option to a free-arg, but I don't see how to do it with run.
The tool is CIEL, I'm trying to ease CL's scripting facilities.
my 2c: https://github.com/vindarel/lisp-maintainers#dnaeon---marin-atanasov-nikolov
Thanks!