-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trying to handle parse errors inside run (to use unknown options as free args) #11
Comments
Hey @vindarel , Thanks for the detailed issue! :) The existing
That last point is the one that is causing you troubles, but it is there because I think it is a good default for most of the use-cases. In situations like yours I think it is best to have a custom If you don't want to go with a separate Option 1The tool you have specified in the description looks like this. $ tool [options] free-arg [additional-args] Is If that's the case you can have a command like this in your (defun exec/command ()
"Returns the command for the `exec' command"
(clingon:make-command
:name "exec"
:description "execute any command"
:usage ""
:handler (lambda (cmd)
(let ((args (clingon:command-arguments cmd)))
(format t "Executing command: ~A~%" (clingon:command-arguments cmd))
(format t "Output: ~%~A~%" (uiop:run-program args :output '(:string :stripped t))))))) You can copy-paste the above handler and register it into your existing my-cli exec -- uname -a This will still require that you use Option 2Provide a custom behaviour for (defmethod clingon:parse-command-line :around ((command clingon:command) arguments)
"Treats unknown options as free arguments"
(handler-bind ((clingon:unknown-option
(lambda (c)
(clingon:treat-as-argument c))))
(call-next-method))) With only this change and the Example usage of a CLI tool built with this code, where the $ cli-tool exec uname -a
Executing command: (uname -a)
Output:
Linux <hostname> 6.2.11-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 13 Apr 2023 16:59:24 +0000 x86_64 GNU/Linux Let me know what do you think about these two options. P.S.: Thanks for listing me on https://github.com/vindarel/lisp-maintainers ! |
Niiiice, your option 2 is clean and is perfectly what I was looking for. I had spotted the defmethod, but had not thought about an around method. Turns out you put a method for a reason :)
good point too, though now I don't need it. It will help others to spot other ways of customizing Clingon's behaviour. In your option 1:
"tool" is the clingon app. "free-arg" is not an external tool, in my case it's another Lisp file, but we might see it as an external tool, because its set of options is not known in advance. My "tool" is a binary, its CLI usage is known in advance, and my goal (completed) was to call this other Lisp file with any options I wish. We have the luxury to avoid the double "--", that's pretty nice. I see a usability issue (the unknown argument appears before the "free-arg" script name) but I'll test like this. Best, |
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
andtreat-as-argument
, the only issue is thatrun
, which callsparse-command-line
, handles everything with a handler-case. So I can't put a handler-bind aroundrun
to do my logic.This is what I want to do:
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 theunknown-option
, i.e. modularizing this: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:
so I could use my parse function:
More context (I'm brainstorming here too): my CLI looks like:
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 "--":
so far so good. But I managed to be able to call the script directly:
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:if I do this, currently Clingon barks and exits because
-a
is an unknown option (if it was not defined with the options oftool
).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!
The text was updated successfully, but these errors were encountered: