Skip to content
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

No way to map multiple args to single positional arg #54

Closed
wsascha opened this issue Feb 10, 2022 · 7 comments
Closed

No way to map multiple args to single positional arg #54

wsascha opened this issue Feb 10, 2022 · 7 comments
Assignees
Labels
enhancement New feature or request

Comments

@wsascha
Copy link

wsascha commented Feb 10, 2022

Hey @nat-n, first of all thanks for that great tool! ❤️

I couldn't find any functionality to map more than one arg to a single arg.

Example

Maybe someone wants to have a python formatting task a la

[tool.poe.tasks.format]
cmd = "black ${files}" 
help = "Format files
args = [
  { name = "files", positional = true, default = ".", help = "List of files (optional)" },
]

Then, this task may be run e.g. via

  • poe format
  • poe format "."
  • poe format /path/to/file
  • poe format "/path/to/file"
  • poe format "/path/to/file/one /path/to/file/two", etc.

but not poe format /path/to/file/one /path/to/file/two. – Note the missing "'s in the example.

In my special case, I want to run tasks as pre-commit hooks using the pre-commit tool which, unfortunately, passes multiple filenames without the "'s.

Any idea how this can be resolved? – Maybe I have also just missed something :-)

@nat-n nat-n added the enhancement New feature or request label Feb 10, 2022
@nat-n
Copy link
Owner

nat-n commented Feb 10, 2022

Hi @wsascha, thanks for the feedback :)

I'm afraid this feature was on my list but didn't quit make it into the initial implementation of structured arguments. I'll take this as validation that it's worth adding, and so leave this issue open. Though there are a couple of higher priority features in progress so I'm not sure when I'll get around to it.

One thing that I'm not sure about though, is how multiple value arguments should be handled by tasks given that single argument values are expected to be strings which can be set as env vars or python variables within tasks. Only three solutions occur to me though none are very satisfactory:

  1. take the list of arguments as a whitespace delimited string, in which case result is basically the same as your example of poe format "/path/to/file/one /path/to/file/two", and makes it impossible to distinguish between multiple args and a single arg containing a space
  2. store the argument with a variable for each item, e.g. files0 and files1. This is kind of complicated, and requires you to know how many values you expect, in which case you might as well just define multiple positional args with those names.
  3. Do both 1 & 2, this should cover more use cases but it's a bit complicated and inelegant, and maybe also pass the argument as a python list of script tasks. Probably the best solution though.

What do you think?

@nat-n
Copy link
Owner

nat-n commented Feb 11, 2022

@wsascha Although looking again at your example, unless you're just using this simple example as a stand in for a more complicated use case... You don't need a named arguments at all. The following will work just fine:

[tool.poe.tasks.format]
cmd = "black" 
help = "Format files, optionally accepts any number of files to format"

@wsascha
Copy link
Author

wsascha commented Feb 12, 2022

Hey, thanks for your quick response!

  1. I'm not sure if I get your idea right, but sometimes passing a multiple args as a single string can't be controlled, e.g. when using third-party tools like pre-commit – I think there are several of those tools, but that's a popular one.
  2. That doesn't generalize well and isn't known upfront in most cases

The example I provided is just a minimum working example, but still: running tasks on a subset of all files often decreases runtime (e.g. running stages only on the added or changed files) or necessary for legacy code where some tasks shouldn't be run.

One pragmatic idea would be to add a separate optional boolean argument parameter, maybe called "list", which sets argparse's nargs="+". It's probably not cool to add another parameter, but would be backwards compatible and resolve this issue. What do you think?

Declaring an arg as a list, also imposes constraints on other args:

  • There can only be one arg with a list
  • all other args need to come first

@nat-n nat-n self-assigned this May 8, 2022
@nat-n
Copy link
Owner

nat-n commented May 29, 2022

@wsascha Quick update: I've got a working prototype for this, but there's a bit of work left to properly test and document it. if you're interested I could make a pre-release so you can use it already.

@wsascha
Copy link
Author

wsascha commented May 29, 2022

Hey, that's great news! You can also create a (draft) PR already and I can help review and support with tests and docs.

@nat-n nat-n mentioned this issue May 30, 2022
6 tasks
@nat-n
Copy link
Owner

nat-n commented May 30, 2022

@wsascha sure, happy to have some help, particularly with testing. I think the functionality I've prototypes is about right now (assuming it all works), though I'd be happy to have feedback on that too.

@nat-n
Copy link
Owner

nat-n commented Jun 18, 2022

This is now available in v0.14.0

@nat-n nat-n closed this as completed Jun 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants