Skip to content

Commit e5e03e6

Browse files
committed
Replace dependency on protoc with grpcio-tools
This change removes the dependency on platform provided protobuf tools in favour of `grpcio-tools` dependency. This makes both development and compiler use independent from platform dependencies.
1 parent 3273ae4 commit e5e03e6

File tree

6 files changed

+182
-94
lines changed

6 files changed

+182
-94
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ jobs:
4949
${{ runner.os }}-poetry-
5050
- name: Install dependencies
5151
run: |
52-
sudo apt install protobuf-compiler libprotobuf-dev
5352
poetry install
5453
- name: Run tests
5554
run: |

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ clean: ## - Clean out generated files from the workspace
3131
o=output
3232
plugin: ## - Execute the protoc plugin, with output write to `output` or the value passed to `-o`
3333
mkdir -p $(o)
34-
protoc --plugin=protoc-gen-custom=betterproto/plugin.py $(i) --custom_out=$(o)
34+
poetry run python -m grpc.tools.protoc $(i) --python_betterproto_out=$(o)
3535

3636
# CI tasks
3737

betterproto/tests/generate.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
inputs_path,
1212
output_path_betterproto,
1313
output_path_reference,
14-
protoc_plugin,
15-
protoc_reference,
14+
protoc,
1615
)
1716

1817
# Force pure-python implementation instead of C++, otherwise imports
@@ -88,8 +87,8 @@ async def generate_test_case_output(
8887
(ref_out, ref_err, ref_code),
8988
(plg_out, plg_err, plg_code),
9089
) = await asyncio.gather(
91-
protoc_reference(test_case_input_path, test_case_output_path_reference),
92-
protoc_plugin(test_case_input_path, test_case_output_path_betterproto),
90+
protoc(test_case_input_path, test_case_output_path_reference, True),
91+
protoc(test_case_input_path, test_case_output_path_betterproto, False),
9392
)
9493

9594
message = f"Generated output for {test_case_name!r}"

betterproto/tests/util.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
import importlib
33
import os
44
import pathlib
5+
import sys
56
from pathlib import Path
67
from types import ModuleType
7-
from typing import Callable, Generator, Optional
8+
from typing import Callable, Generator, Optional, Union
89

910
os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "python"
1011

@@ -13,11 +14,6 @@
1314
output_path_reference = root_path.joinpath("output_reference")
1415
output_path_betterproto = root_path.joinpath("output_betterproto")
1516

16-
if os.name == "nt":
17-
plugin_path = root_path.joinpath("..", "plugin.bat").resolve()
18-
else:
19-
plugin_path = root_path.joinpath("..", "plugin.py").resolve()
20-
2117

2218
def get_files(path, suffix: str) -> Generator[str, None, None]:
2319
for r, dirs, files in os.walk(path):
@@ -31,22 +27,25 @@ def get_directories(path):
3127
yield directory
3228

3329

34-
async def protoc_plugin(path: str, output_dir: str):
35-
proc = await asyncio.create_subprocess_shell(
36-
f"protoc --plugin=protoc-gen-custom={plugin_path} --custom_out={output_dir} --proto_path={path} {path}/*.proto",
37-
stdout=asyncio.subprocess.PIPE,
38-
stderr=asyncio.subprocess.PIPE,
39-
)
40-
return (*(await proc.communicate()), proc.returncode)
41-
42-
43-
async def protoc_reference(path: str, output_dir: str):
44-
proc = await asyncio.create_subprocess_shell(
45-
f"protoc --python_out={output_dir} --proto_path={path} {path}/*.proto",
46-
stdout=asyncio.subprocess.PIPE,
47-
stderr=asyncio.subprocess.PIPE,
30+
async def protoc(
31+
path: Union[str, Path], output_dir: Union[str, Path], reference: bool = False
32+
):
33+
path: Path = Path(path).resolve()
34+
output_dir: Path = Path(output_dir).resolve()
35+
python_out_option: str = "python_betterproto_out" if not reference else "python_out"
36+
command = [
37+
sys.executable,
38+
"-m",
39+
"grpc.tools.protoc",
40+
f"--proto_path={path.as_posix()}",
41+
f"--{python_out_option}={output_dir.as_posix()}",
42+
*[p.as_posix() for p in path.glob("*.proto")],
43+
]
44+
proc = await asyncio.create_subprocess_exec(
45+
*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
4846
)
49-
return (*(await proc.communicate()), proc.returncode)
47+
stdout, stderr = await proc.communicate()
48+
return stdout, stderr, proc.returncode
5049

5150

5251
def get_test_case_json_data(test_case_name: str, json_file_name: Optional[str] = None):

0 commit comments

Comments
 (0)