pyinvoke / invoke

Pythonic task management & command execution.
http://pyinvoke.org
BSD 2-Clause "Simplified" License
4.41k stars 369 forks source link

task: positional arguments and cardinality -- only required_positional_arg is supported #760

Open jenisys opened 4 years ago

jenisys commented 4 years ago

Positional arguments could be really useful in invoke tasks, but currently only the case as required_positional_arg (cardinality=1) seems to be supported.

In general, there are three/four use cases of cardinality for positional arguments (considering only one positional argument):

For the many cases, there exists the problem to discover where the last item ends and where the next task (name) begins. The only idea, that I have, is to use the known task names as "sentinels" (not a wonderful solution) or disallow multiple tasks in this special case (also not great).

If you have more than one positional argument, trap doors open up. In this case, you basically need the constraint that only the last positional argument can be optional, optional-many or required-many. The leading positional arguments must all be required positional arguments (with cardinality=1).

ADDITIONALLY: Using the other task-param-lists, optional and/or iterable, to describe the cardinality cases above does not work and seems to make the positional argument into an option-argument again (usable as option but no longer a positional argument).

RELATED:

vvuk commented 2 weeks ago

disallow multiple tasks in this special case (also not great).

As a suggestion, I think -- could help here... if you have a task that requires optional positional args (including 1..N -- basically anything other than a fixed required N), maybe require the task to be invoked with -- at least before the positional args to explicitly indicate that the following are all positional. It does make multiple tasks not work, but maybe that's ok as a start if the invocation is explicit. Maybe in order to allow multiple task invocations, allow a second -- to end the positional argument set? Or a user-specified sentinel (invoke --task-separator='#' firsttask .... '#' nexttask)

I just ran into a case where this would be useful; I'm using invoke really only for local command invocation, basically making a simple CLI entry point for our monorepo. There's a few things where I'd like the user to be able to pass arbitrary arguments that I'd then pass down to an underlying command.