chore(refactoring): Introduce a Python CLI app layout#738
chore(refactoring): Introduce a Python CLI app layout#738MaxymVlasov merged 6 commits intoantonbabenko:masterfrom
Conversation
Cool. Thanks. Too much of Python'ish stuff for me 🤣
Could you please drop a README.md file with the above info into the directory with these files for future reference? Thank you. |
MaxymVlasov
left a comment
There was a problem hiding this comment.
Why there so much boilerplate -_-
| from .terraform_docs_replace import ( | ||
| populate_argument_parser as populate_replace_docs_argument_parser, | ||
| ) | ||
|
|
||
|
|
||
| PARSER_MAP = { | ||
| 'replace-docs': populate_replace_docs_argument_parser, | ||
| } |
There was a problem hiding this comment.
So I will need to add here all python hooks?
There was a problem hiding this comment.
And how it should work with common.py?
I don't understand how I will use it with
There was a problem hiding this comment.
Yes, this mapping is for parsers, and another file has a mapping for callables with the logic.
There was a problem hiding this comment.
I don't understand how I will use it with
You won't need to call common.parse_cmdline(argv) manually in several places anymore. It'll be called for you, and you'll get the result of a parse_args() invocation into a function you'll define to accept an argparse.Namespace instance.
|
Why you used Sorry, but I have no idea how to reuse half of code implemented here with actual hooks |
Because it is a working example of implementing custom check subcommands until you add new ones. You can swap it out for new things later.
Hence, the example integration of the only existing thing. I'll drop the instructions into a readme as suggested. |
|
I've added a document. While doing that, I realized that I can simplify the new subcommand integration a bit, so I've marked this as a draft until I do that. |
Pretty nice and clear ❤️ |
cdf5b6e to
3af52a9
Compare
|
@yermulnik @MaxymVlasov this is now mergeable, but #734 should go in first to unblock the CI. |
|
pre-commit.ci run |
yermulnik
left a comment
There was a problem hiding this comment.
LGTM. Though since @MaxymVlasov is mainly the only one who develops code at this moment I'm deferring final decision to him.
This includes a structure with purpose-based modules and a standard mechanism for adding more subcommands. When adding a new subcommand, one has to wire the `invoke_cli_app()` and `populate_argument_parser()` from their new module into the mappings defined in `_cli_subcommands.py` and `_cli_parsing.py` respectively. This is the only integration point necessary. `populate_argument_parser()` accepts a subparser instance of `argparse.ArgumentParser()` that a new subcommand would need to attach new arguments into. It does not need to return anything. And the `invoke_cli_app()` hook is called with an instance of `argparse.Namespace()` with all the arguments parsed and pre-processed. This function is supposed to have the main check logic and return an instance of `._structs.ReturnCode()` or `int`.
Previously, adding a new subcommand required importing it into two separate Python modules, adding them into two mappings, maintaining the same dictionary key string. This is prone to human error and is underintegrated. This patch makes it easier by defining a required subcommand module shape on the typing level. Now, one just need to implement two hook- functions and a constant with specific signatures and import it in a single place.
1c12549 to
52cf580
Compare
MaxymVlasov
left a comment
There was a problem hiding this comment.
Let's hope that I'll understand all later :)
IT somehow works with new hooks, but need some polishing, which will be done in other PRs
|
This PR is included in version 1.97.0 🎉 |
This includes a structure with purpose-based modules and a standard mechanism for adding more subcommands.
When adding a new subcommand, one has to define the
invoke_cli_app()andpopulate_argument_parser()hooks in their new module together with aCLI_SUBCOMMAND_NAMEstring constant. I can then be wired into the framework via_cli_subcommands.py. This is the only integration point necessary.populate_argument_parser()accepts a subparser instance ofargparse.ArgumentParser()that a new subcommand would need to attach new arguments into. It does not need to return anything. And theinvoke_cli_app()hook is called with an instance ofargparse.Namespace()with all the arguments parsed and pre-processed. This function is supposed to have the main check logic and return an instance of._structs.ReturnCode()orint.CLI_SUBCOMMAND_NAMEneeds to be annotated as aFinal[str].pre-commitintegration is done through the runpy interface:python -m pre_commit_terraform <subcommand>.The import package folder also contains a more detailed maintenance manual: https://github.com/antonbabenko/pre-commit-terraform/tree/8e77580805322e5d264a2667b4f4cba53e8bf94c/src/pre_commit_terraform#readme.
Put an
xinto the box if that apply:Description of your changes
I think the most important details are in the commit messages. Everything that is unlikely to change much over time is in "_private" modules.
How can we test changes
Something like
python -Im pip install -e . && python -Im pre_commit_terraform replace-docs. Or invoke it via pre-commit.