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

Accept unknown options (for poetry plugin) #126

Open
nat-n opened this issue Dec 23, 2021 · 0 comments
Open

Accept unknown options (for poetry plugin) #126

nat-n opened this issue Dec 23, 2021 · 0 comments
Milestone

Comments

@nat-n
Copy link

nat-n commented Dec 23, 2021

I require a way to make a cleo Command accept unknown options and arguments, and not inherit the application options.

The equivalent in argparse would be something like:

parser.add_argument("command_args", nargs=argparse.REMAINDER)

however I need to use cleo because I'm creating a poetry plugin for PoeThePoet which allows users to pass unknown arguments to a task e.g.

poe test <any args passed here will be forwarded to pytest>

It looks like this is currently not supported though I'd be happy to be proven wrong on that.

I'm willing to do the leg work to add support for this, since the only alternatives for integrating with poetry are either to drop key features when used as a plugin or to monkey patch Cleo at runtime 😞.

Workaround

I've found the following workaround that seems to produce the desired result (for now) by monkey patching cleo:

def monkey_patch_cleo(command: str):
    """Monkey patch cleo, e.g. while activating the poetry plugin"""
    import cleo.application

    continue_run = cleo.application.Application._run

    def _run(self, io):
        # Trick cleo to ignoring anything following the command from this plugin 
        # by injecting a '--' token at the start of the list of command line tokens
        tokens = io.input._tokens
        if tokens and tokens[0] == command:
            # update tokens list in place
            tokens.insert(0, "--")

        continue_run(self, io)

    # Apply the patch
    cleo.application.Application._run = _run


class MyCommand(Command):
    name = "my-command"
    
    def __init__(self):
        super().__init__()
        self._ignore_validation_errors = True # Don't fail given unknown arguments

    def handle(self):
        args = self.io.input._tokens[:]
        if args[0] == "--": # ignore the extra token introduced by the monkey patch
            args = tokenized_input[1:]
         ...

Proposal

A better solution would involve being able to configure the Command to have freeform arguments, e.g.

class MyCommand(Command):
    name = "my-command"
    parse_options = False

Which carries over to resulting Definition object which in turn causes the ArgvInput instance to skip parsing of options. Parsing of positional arguments could still work the same I think.

@nat-n nat-n changed the title Any way to accept unknown arguments Accept unknown arguments (for poetry plugin) Dec 28, 2021
@nat-n nat-n changed the title Accept unknown arguments (for poetry plugin) Accept unknown options (for poetry plugin) Dec 28, 2021
@Secrus Secrus added this to the Future milestone Sep 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants