diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index dda1c7e6..faeb7913 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -31,6 +31,10 @@ But you might still need to adapt your code: ## Bug Fixes - Fixed some typos in the docs. +- `setuptools.grpc_tools`: Fix wrong passing of include paths when passed via: + + * Command-line: Now extra white-spaces and empty strings are removed, before they were passed to `protoc -I`. + * `pyproject.toml`: Now an empty array/list can be passed to override the default paths, before this resulted in an empty string being passed to `protoc -I`. ### Cookiecutter template diff --git a/src/frequenz/repo/config/setuptools/grpc_tools.py b/src/frequenz/repo/config/setuptools/grpc_tools.py index 9d0559eb..d0da3362 100644 --- a/src/frequenz/repo/config/setuptools/grpc_tools.py +++ b/src/frequenz/repo/config/setuptools/grpc_tools.py @@ -13,7 +13,8 @@ import pathlib as _pathlib import subprocess as _subprocess import sys as _sys -from typing import cast +from collections.abc import Iterable +from typing import assert_never, cast import setuptools as _setuptools import setuptools.command.build as _build_command @@ -30,8 +31,8 @@ class CompileProto(_setuptools.Command): proto_glob: str """The glob pattern to use to find the protobuf files.""" - include_paths: str - """Comma-separated list of paths to include when compiling the protobuf files.""" + include_paths: str | Iterable[str] + """Iterable or comma-separated list of paths to include when compiling the protobuf files.""" py_path: str """The path of the root directory where the Python files will be generated.""" @@ -72,7 +73,7 @@ def initialize_options(self) -> None: self.proto_path = config.proto_path self.proto_glob = config.proto_glob - self.include_paths = ",".join(config.include_paths) + self.include_paths = config.include_paths self.py_path = config.py_path def finalize_options(self) -> None: @@ -80,7 +81,17 @@ def finalize_options(self) -> None: def run(self) -> None: """Compile the Python protobuf files.""" - include_paths = self.include_paths.split(",") + include_paths: Iterable[str] + match self.include_paths: + case str() as str_paths: + # If it comes as a comma-separated string, split it into a list, + # stripping whitespace and ignoring empty strings. + include_paths = filter(len, map(str.strip, str_paths.split(","))) + case Iterable() as paths_it: + include_paths = paths_it + case unexpected: + assert_never(unexpected) + proto_files = [ str(p) for p in _pathlib.Path(self.proto_path).rglob(self.proto_glob) ]