-
Notifications
You must be signed in to change notification settings - Fork 233
Implement command line interface #165
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
Draft
Gobot1234
wants to merge
54
commits into
danielgtaylor:master
Choose a base branch
from
Gobot1234:better-cli-interface
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from 47 commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
0d6ced5
Implement Message.__bool__ for #130
Gobot1234 7746b91
Add a test for it
Gobot1234 53a7df0
Merge branch 'master' into master
Gobot1234 9da923d
Blacken
Gobot1234 17e31f4
Update tests
Gobot1234 a53d805
Fix bool
Gobot1234 b3b7c00
Fix failing tests
Gobot1234 18f22fa
Make plugin use betterproto generated classes internally
nat-n 2cc3e05
Update deps & add generate_lib task
nat-n 230721f
Fix template bug resulting in empty __post_init__ methods
nat-n de9c0a0
Implement command line interface
Gobot1234 4a4429d
Update docs
Gobot1234 48e80cf
Merge branch 'master' into master
Gobot1234 86d7c30
Add __bool__ to special members
Gobot1234 5c8e926
Update __init__.py
Gobot1234 f10bec4
Simplify bool
Gobot1234 e0eb291
Fix some typos
Gobot1234 e04fcb6
Tweak __bool__ docstring
nat-n 53b2bca
Sort the list of sources in generated file headers
nat-n 9c4e8d8
Implement command line interface
Gobot1234 2e9ec7a
Fix some typos
Gobot1234 4fde7b1
Implement command line interface
Gobot1234 ee40943
Fix some typos
Gobot1234 a68e36f
Merge remote-tracking branch 'origin/better-cli-interface' into bette…
Gobot1234 e6d1eaa
Initial update
Gobot1234 231dc05
Write files concurrently and general improvements
Gobot1234 1f5df3d
Fix up everything
Gobot1234 b908c58
Improve stuff a lot
Gobot1234 8b4380f
Final stuff to make it work
Gobot1234 16af499
More stuff
Gobot1234 7faec49
Fix some weird bugs
Gobot1234 305b7df
Boring stuff
Gobot1234 3553e0e
Fix some bugs
Gobot1234 8eb7c90
Ensure paths are sorted
Gobot1234 0c4277b
Redo error handling to be much more reliable
Gobot1234 f807e39
Finish up
Gobot1234 944a6be
Update docs
Gobot1234 5a1819e
Update docs again
Gobot1234 f31eb98
Regen lock
Gobot1234 9f636d0
Merge branch 'master' into better-cli-interface
Gobot1234 48a5e7c
Cleanup code
Gobot1234 8596a61
Regen lock
Gobot1234 07a2e9d
Make the CLI better behaved
Gobot1234 c2d1fdb
Merge remote-tracking branch 'origin/master' into better-cli-interface
Gobot1234 1f69bdd
Merge remote-tracking branch 'upstream/master' into better-cli-interface
Gobot1234 dd54d54
Merge remote-tracking branch 'upstream/master' into better-cli-interface
Gobot1234 23747c5
Rebase stuff
Gobot1234 a72b907
Pick this back up
Gobot1234 329d25d
More stuff
Gobot1234 63c9fd4
Merge remote-tracking branch 'upstream/master' into better-cli-interface
Gobot1234 e595356
Revive this
Gobot1234 66f96c4
Revive this
Gobot1234 8f1746f
Add NoopProgress
Gobot1234 61f0335
Make stuff work slightly more
Gobot1234 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from .plugin.cli import app as main | ||
|
||
if __name__ == "__main__": | ||
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,50 @@ | ||
import sys | ||
import traceback | ||
from pathlib import Path | ||
from types import TracebackType | ||
from typing import Type | ||
|
||
IMPORT_ERROR_MESSAGE = ( | ||
"Unable to import `{0.name}` from betterproto plugin! Please ensure that you've installed " | ||
'betterproto as `pip install "betterproto[compiler]"` so that compiler dependencies are ' | ||
"included." | ||
) | ||
|
||
STDLIB_MODULES = getattr( | ||
sys, | ||
"builtin_module_names", | ||
[ | ||
p.with_suffix("").name | ||
for p in Path(traceback.__file__).parent.iterdir() | ||
if p.suffix == ".py" or p.is_dir() | ||
], | ||
) | ||
|
||
|
||
def import_exception_hook( | ||
type: Type[BaseException], value: ImportError, tb: TracebackType | ||
) -> None: | ||
"""Set an exception hook to automatically print: | ||
|
||
"Unable to import `x` from betterproto plugin! Please ensure that you've installed | ||
betterproto as `pip install "betterproto[compiler]"` so that compiler dependencies are | ||
included." | ||
|
||
if the module imported is not found and the exception is raised in this sub module | ||
""" | ||
module = list(traceback.walk_tb(tb))[-1][0].f_globals.get("__name__", "__main__") | ||
if ( | ||
not module.startswith(__name__) | ||
or not isinstance(value, ImportError) | ||
or value.name in STDLIB_MODULES | ||
or value.name.startswith("betterproto") | ||
): | ||
return sys.__excepthook__(type, value, tb) | ||
|
||
print(f"\033[31m{IMPORT_ERROR_MESSAGE.format(value)}\033[0m", file=sys.stderr) | ||
exit(1) | ||
|
||
|
||
sys.excepthook = import_exception_hook | ||
|
||
from .main import main |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
from .main import main | ||
|
||
|
||
main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import asyncio | ||
import platform | ||
|
||
try: | ||
import grpc_tools.protoc | ||
except ImportError: | ||
USE_PROTOC = True | ||
else: | ||
USE_PROTOC = False | ||
|
||
VERBOSE = False | ||
from black import DEFAULT_LINE_LENGTH as DEFAULT_LINE_LENGTH # noqa | ||
|
||
from .commands import app | ||
from .runner import compile_protobufs | ||
|
||
if platform.system() == "Windows": | ||
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import sys | ||
from pathlib import Path | ||
from typing import List, Optional | ||
|
||
import rich | ||
import typer | ||
from rich.syntax import Syntax | ||
|
||
from ..models import monkey_patch_oneof_index | ||
from . import DEFAULT_LINE_LENGTH, USE_PROTOC, VERBOSE, utils | ||
from .errors import CLIError, ProtobufSyntaxError | ||
from .runner import compile_protobufs | ||
|
||
monkey_patch_oneof_index() | ||
app = typer.Typer() | ||
|
||
|
||
@app.callback(context_settings={"help_option_names": ["-h", "--help"]}) | ||
def callback(ctx: typer.Context) -> None: | ||
"""The callback for all things betterproto""" | ||
if ctx.invoked_subcommand is None: | ||
rich.print(ctx.get_help()) | ||
|
||
|
||
@app.command(context_settings={"help_option_names": ["-h", "--help"]}) | ||
@utils.run_sync | ||
async def compile( | ||
verbose: bool = typer.Option( | ||
VERBOSE, "-v", "--verbose", help="Whether or not to be verbose" | ||
), | ||
protoc: bool = typer.Option( | ||
USE_PROTOC, | ||
"-p", | ||
"--protoc", | ||
help="Whether or not to use protoc to compile the protobufs if this is false " | ||
"it will attempt to use grpc instead", | ||
), | ||
line_length: int = typer.Option( | ||
DEFAULT_LINE_LENGTH, | ||
"-l", | ||
"--line-length", | ||
help="The line length to format with", | ||
), | ||
generate_services: bool = typer.Option( | ||
True, help="Whether or not to generate servicer stubs" | ||
), | ||
output: Optional[Path] = typer.Option( | ||
None, | ||
help="The name of the output directory", | ||
file_okay=False, | ||
allow_dash=True, | ||
), | ||
paths: List[Path] = typer.Argument( | ||
..., | ||
help="The protobuf files to compile", | ||
exists=True, | ||
allow_dash=True, | ||
readable=False, | ||
), | ||
) -> None: | ||
"""The recommended way to compile your protobuf files.""" | ||
files = utils.get_files(paths) | ||
|
||
if not files: | ||
return rich.print("[bold]No files found to compile") | ||
|
||
for output_path, protos in files.items(): | ||
output = output or (Path(output_path.parent.name) / output_path.name).resolve() | ||
output.mkdir(exist_ok=True, parents=True) | ||
|
||
errors = await compile_protobufs( | ||
*protos, | ||
output=output, | ||
verbose=verbose, | ||
use_protoc=protoc, | ||
generate_services=generate_services, | ||
line_length=line_length, | ||
from_cli=True, | ||
) | ||
|
||
for error in errors: | ||
if isinstance(error, ProtobufSyntaxError): | ||
rich.print( | ||
f"[red]File {str(error.file).strip()}:\n", | ||
Syntax( | ||
error.file.read_text(), | ||
"proto", | ||
line_numbers=True, | ||
line_range=(max(error.lineno - 5, 0), error.lineno), | ||
), # TODO switch to .from_path but it appears to be bugged and doesnt render properly | ||
f"{' ' * (error.offset + 3)}^\nSyntaxError: {error.msg}[red]", | ||
file=sys.stderr, | ||
) | ||
elif isinstance(error, Warning): | ||
rich.print(f"Warning: {error}", file=sys.stderr) | ||
elif isinstance(error, CLIError): | ||
failed_files = "\n".join(f" - {file}" for file in protos) | ||
rich.print( | ||
f"[red]{'Protoc' if protoc else 'GRPC'} failed to generate outputs for:\n\n" | ||
f"{failed_files}\n\nSee the output for the issue:\n{' '.join(error.args)}[red]", | ||
file=sys.stderr, | ||
) | ||
|
||
has_warnings = all(isinstance(e, Warning) for e in errors) | ||
if not errors or has_warnings: | ||
rich.print( | ||
f"[bold green]Finished generating output for " | ||
f"{len(protos)} file{'s' if len(protos) != 1 else ''}, " | ||
f"output is in {output.as_posix()}" | ||
) | ||
|
||
if errors: | ||
if not has_warnings: | ||
exit(2) | ||
exit(1) | ||
exit(0) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.