radeklat / delfino

A toolbox of command line helper script, wrapping tools used during Python development.
MIT License
12 stars 3 forks source link

Accept undefined options/arguments with commands and pass them to undelying toolings (like mypy) #34

Closed shimpeko closed 1 year ago

shimpeko commented 2 years ago

What

Pass undefined options/arguments with commands and pass them to underlying toolings (likes mypy)

Example

With a command definition like following;

@click.command(help="Run unit tests.")
@click.option("--maxfail", type=int, default=0)
@click.option("--debug", is_flag=True, help="Disables capture, allowing debuggers like `pdb` to be used.")
@pass_app_context
def test_unit(app_context: AppContext, maxfail: int, debug: bool):

Current behaviour

delfino % poetry run delfino test-unit -k keyword
Usage: delfino test-unit [OPTIONS]

Error: No such option: -k

Expected behaviour

delfino % poetry run delfino test-unit -k keyword
=============================== test session starts ===============================
platform darwin -- Python 3.10.4, pytest-7.1.2, pluggy-1.0.0
rootdir: /Users/shimpei-kodama/github.com/radeklat/delfino, configfile: pyproject.toml
plugins: mock-3.8.2, dotenv-0.5.2, cov-3.0.0
collected 1 item / 1 deselected / 0 selected                                      

============================== 1 deselected in 0.08s ==============================

Why

Currently, existing commands accept only a defined set of options/arguments. It makes it impossible to add/remove options to/from exiting command withoug rewriting it. In another word, it is required to rewrite the whole command to add/remove one option.

Considerations

radeklat commented 2 years ago

Not being able to override/remove the default options is fine I think. One can always run tools manually without delfino if they need something specific. Delfino is meant to provide sensible defaults for repeated execution. Not to be a golden hammer for any conceivable use case.

But if doesn't work well with the @filepaths_argument decorator.

Do you have details of what the problem is please?

shimpeko commented 2 years ago

But if doesn't work well with the @filepaths_argument decorator.

Do you have details of what the problem is, please?

When ignore_unknown_options is used in combination with @click.argument with nargs=-1 the argument captures all undefined options/aruguments (official doc says, https://click.palletsprojects.com/en/8.1.x/arguments/#option-like-arguments).

Currently the @filepaths_argument decorator is configured with nargs=-1. So it gonna capture all options/arguments.

I think we have to replace the decorator with one which accepts arbitrary options/arguments (not specific for file paths). But it makes it difficult to set default paths, like [src, tests], only when file path arguments are not passed (=overwrite default paths when files path arguments are passed). Because we will no longer be able to distinguish file paths and other options with a decorator which accepts arbitrary options/arguments (not specific for filepaths).

note: Underline toolings like mypy can distinguish options and file path arguments because they know their own set of options.

@click.argument(args, nargs=-1)
def command(args):
    default_paths = [`src`]
    # want to overwrite default paths when args include path arguments but it is not possible to identify path arguments in args. 

I think we need to use click.option (like --path) with multiple=True for file paths instead of click.argumet.

jacksmith15 commented 2 years ago

I'm a bit unclear on what the use case for this issue is. I agree with @radeklat on the following:

One can always run tools manually without delfino if they need something specific

@shimpeko can you provide some example use cases where there is need to override particular options, and where configuring the normal way (pyproject.toml) isn't appropriate?

shimpeko commented 1 year ago

discussed offline w/ @radeklat @jacksmith15


Usecase;

In some repositories, we'd like to provide additional options for underlying tooling for some commands in CI. For example, the test-unit command in our internal repository has options like hypothesis_profile or slow that are not supported by Delfino's test-unit command currently. In such a case, we cannot use Delfino's test-unit command and need to rewrite the whole command by ourselves (when the option is not configurable via pytest.ini or when we want to use python code to decide the option value).

If it is possible to pass options/arguments directly to underlying tooling, we can add repository-specific options easily without writing additional code.

Discussion;

radeklat commented 1 year ago

Closing this as the implementation is now available (any arguments after -- are passed through).