wizard-codegen 0.1.5__tar.gz → 0.1.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/PKG-INFO +4 -4
  2. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/README.md +3 -3
  3. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/cli/main.py +21 -0
  4. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/core/context_builder.py +2 -2
  5. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/core/renderer.py +4 -3
  6. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/proto/proto_source.py +7 -4
  7. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/proto/protoc_runner.py +5 -2
  8. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/pyproject.toml +1 -1
  9. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/utils/__init__.py +3 -1
  10. wizard_codegen-0.1.7/utils/path.py +27 -0
  11. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/.gitignore +0 -0
  12. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/cli/__init__.py +0 -0
  13. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/core/__init__.py +0 -0
  14. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/core/config.py +0 -0
  15. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/core/filter.py +0 -0
  16. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/core/writer.py +0 -0
  17. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/hooks/__init__.py +0 -0
  18. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/hooks/hooks.py +0 -0
  19. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/proto/__init__.py +0 -0
  20. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/proto/discover.py +0 -0
  21. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/proto/fds_loader.py +0 -0
  22. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/tests/fixtures/hooks/__init__.py +0 -0
  23. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/tests/fixtures/hooks/type_mapping.py +0 -0
  24. {wizard_codegen-0.1.5 → wizard_codegen-0.1.7}/utils/name.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wizard-codegen
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: A powerful, template-driven code generation tool for Protocol Buffers
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: click==8.3.1
@@ -15,8 +15,8 @@ Description-Content-Type: text/markdown
15
15
 
16
16
  # 🧙 Wizard Codegen
17
17
 
18
- [![CircleCI](https://dl.circleci.com/status-badge/img/gh/ConsultingMD/wizard-codegen-experiment/tree/main.svg?style=svg&circle-token=CCIPRJ_6cYihJ2CPYtLrt8VjrCcSV_f02bbbce30f122a85da4e93588e8887e973128fd)](https://dl.circleci.com/status-badge/redirect/gh/ConsultingMD/wizard-codegen-experiment/tree/main)
19
- [![codecov](https://codecov.io/gh/ConsultingMD/wizard-codegen-experiment/graph/badge.svg?token=NKzMlLPzqy)](https://codecov.io/gh/ConsultingMD/wizard-codegen-experiment)
18
+ [![CircleCI](https://dl.circleci.com/status-badge/img/gh/ConsultingMD/wizard-codegen/tree/main.svg?style=svg&circle-token=CCIPRJ_6cYihJ2CPYtLrt8VjrCcSV_f02bbbce30f122a85da4e93588e8887e973128fd)](https://dl.circleci.com/status-badge/redirect/gh/ConsultingMD/wizard-codegen/tree/main)
19
+ [![codecov](https://codecov.io/gh/ConsultingMD/wizard-codegen/graph/badge.svg?token=NKzMlLPzqy)](https://codecov.io/gh/ConsultingMD/wizard-codegen)
20
20
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
21
21
 
22
22
  > **A powerful, template-driven code generation tool for Protocol Buffers**
@@ -867,7 +867,7 @@ make test PYTEST_ARGS="tests/test_e2e.py::TestFullPipelineGeneration -v"
867
867
 
868
868
  ### Code Coverage
869
869
 
870
- [![codecov](https://codecov.io/gh/ConsultingMD/wizard-codegen-experiment/graphs/tree.svg?token=NKzMlLPzqy)](https://codecov.io/gh/ConsultingMD/wizard-codegen-experiment)
870
+ [![codecov](https://codecov.io/gh/ConsultingMD/wizard-codegen/graphs/tree.svg?token=NKzMlLPzqy)](https://codecov.io/gh/ConsultingMD/wizard-codegen)
871
871
 
872
872
  ### Test Categories
873
873
 
@@ -1,7 +1,7 @@
1
1
  # 🧙 Wizard Codegen
2
2
 
3
- [![CircleCI](https://dl.circleci.com/status-badge/img/gh/ConsultingMD/wizard-codegen-experiment/tree/main.svg?style=svg&circle-token=CCIPRJ_6cYihJ2CPYtLrt8VjrCcSV_f02bbbce30f122a85da4e93588e8887e973128fd)](https://dl.circleci.com/status-badge/redirect/gh/ConsultingMD/wizard-codegen-experiment/tree/main)
4
- [![codecov](https://codecov.io/gh/ConsultingMD/wizard-codegen-experiment/graph/badge.svg?token=NKzMlLPzqy)](https://codecov.io/gh/ConsultingMD/wizard-codegen-experiment)
3
+ [![CircleCI](https://dl.circleci.com/status-badge/img/gh/ConsultingMD/wizard-codegen/tree/main.svg?style=svg&circle-token=CCIPRJ_6cYihJ2CPYtLrt8VjrCcSV_f02bbbce30f122a85da4e93588e8887e973128fd)](https://dl.circleci.com/status-badge/redirect/gh/ConsultingMD/wizard-codegen/tree/main)
4
+ [![codecov](https://codecov.io/gh/ConsultingMD/wizard-codegen/graph/badge.svg?token=NKzMlLPzqy)](https://codecov.io/gh/ConsultingMD/wizard-codegen)
5
5
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
6
6
 
7
7
  > **A powerful, template-driven code generation tool for Protocol Buffers**
@@ -852,7 +852,7 @@ make test PYTEST_ARGS="tests/test_e2e.py::TestFullPipelineGeneration -v"
852
852
 
853
853
  ### Code Coverage
854
854
 
855
- [![codecov](https://codecov.io/gh/ConsultingMD/wizard-codegen-experiment/graphs/tree.svg?token=NKzMlLPzqy)](https://codecov.io/gh/ConsultingMD/wizard-codegen-experiment)
855
+ [![codecov](https://codecov.io/gh/ConsultingMD/wizard-codegen/graphs/tree.svg?token=NKzMlLPzqy)](https://codecov.io/gh/ConsultingMD/wizard-codegen)
856
856
 
857
857
  ### Test Categories
858
858
 
@@ -64,6 +64,7 @@ def generate(ctx: typer.Context):
64
64
  config = _load_config(ctx.obj.config_path, ctx)
65
65
  proto_root = resolve_proto_root(config, use_local=ctx.obj.local)
66
66
  files = discover_proto_files(proto_root, config)
67
+ _validate_proto_files(files, config, proto_root)
67
68
  if ctx.obj.verbose:
68
69
  _print_files_table(files, proto_root)
69
70
 
@@ -101,6 +102,7 @@ def validate(ctx: typer.Context):
101
102
  config = _load_config(ctx.obj.config_path, ctx)
102
103
  proto_root = resolve_proto_root(config, use_local=ctx.obj.local)
103
104
  files = discover_proto_files(proto_root, config)
105
+ _validate_proto_files(files, config, proto_root)
104
106
 
105
107
  if ctx.obj.verbose:
106
108
  _print_files_table(files, proto_root)
@@ -128,6 +130,25 @@ def _print_files_table(files, proto_root):
128
130
  console.print(table)
129
131
 
130
132
 
133
+ def _validate_proto_files(files: list[Path], config: CodegenConfig, proto_root: Path) -> None:
134
+ """Validate that proto files were discovered, exit with helpful error if not."""
135
+ if files:
136
+ return
137
+
138
+ includes = config.proto.includes or ["(root)"]
139
+ patterns = config.proto.files
140
+
141
+ console.print("[bold red]Error:[/] No proto files found!")
142
+ console.print()
143
+ console.print(f"[dim]Proto root:[/] {proto_root}")
144
+ console.print(f"[dim]Includes:[/] {', '.join(includes)}")
145
+ console.print(f"[dim]File patterns:[/] {', '.join(patterns)}")
146
+ console.print()
147
+ console.print("[yellow]Hint:[/] Check that your [bold]proto.includes[/] directories exist and contain")
148
+ console.print(f" files matching [bold]{', '.join(patterns)}[/]")
149
+ raise typer.Exit(1)
150
+
151
+
131
152
  def _print_verbose_enabled(ctx: typer.Context):
132
153
  if ctx.obj.verbose:
133
154
  console.print("[dim]Verbose enabled[/]")
@@ -266,8 +266,8 @@ def _process_proto_file(
266
266
  services = _process_services(proto_file, file_name, package, service_index)
267
267
 
268
268
  return {
269
- "name": Name(file_name),
270
- "basename": base_name,
269
+ "name": Name(base_name),
270
+ "full_name": file_name,
271
271
  "package": package,
272
272
  "package_path": _pkg_path(package),
273
273
  "imports": list(proto_file.dependency),
@@ -6,6 +6,7 @@ from jinja2 import Environment, FileSystemLoader, StrictUndefined
6
6
  from .config import CodegenConfig
7
7
  from hooks import load_hooks
8
8
  from .filter import where_ok
9
+ from utils import expand_path
9
10
 
10
11
  @dataclass
11
12
  class PlanItem:
@@ -49,12 +50,12 @@ def render_all(cfg: CodegenConfig, context: dict, out_override: Path | None = No
49
50
  plan: list[PlanItem] = []
50
51
 
51
52
  for target, tcfg in cfg.targets.items():
52
- template_dir = (Path(tcfg.templates)).resolve()
53
- out_root = (out_override or Path(tcfg.out)).resolve()
53
+ template_dir = expand_path(tcfg.templates).resolve()
54
+ out_root = (out_override or expand_path(tcfg.out)).resolve()
54
55
 
55
56
  env = _make_env(template_dir)
56
57
 
57
- hooks = load_hooks(cfg, Path(cfg.hooks.root))
58
+ hooks = load_hooks(cfg, expand_path(cfg.hooks.root))
58
59
  if hooks:
59
60
  hooks.register(env, target=target, config=cfg)
60
61
 
@@ -4,6 +4,7 @@ import subprocess
4
4
  import re
5
5
 
6
6
  from core.config import CodegenConfig, ProtoSource
7
+ from utils import expand_path
7
8
 
8
9
  LATEST_TAG = "latest-tag"
9
10
 
@@ -84,6 +85,8 @@ def resolve_proto_root(cfg: CodegenConfig, *, use_local: bool = False) -> Path:
84
85
  """
85
86
  Resolve the proto root directory.
86
87
 
88
+ Supports environment variables ($VAR, ${VAR}) and ~ in paths.
89
+
87
90
  When use_local=True (--local flag):
88
91
  Uses proto.root from config (local filesystem path)
89
92
 
@@ -94,10 +97,10 @@ def resolve_proto_root(cfg: CodegenConfig, *, use_local: bool = False) -> Path:
94
97
  if use_local:
95
98
  # --local flag: use local proto.root
96
99
  if cfg.proto.root and cfg.proto.root != "":
97
- p = Path(cfg.proto.root).resolve()
100
+ p = expand_path(cfg.proto.root).resolve()
98
101
  if p.exists():
99
102
  return p
100
- raise RuntimeError(f"proto.root path does not exist: {cfg.proto.root}")
103
+ raise RuntimeError(f"proto.root path does not exist: {cfg.proto.root} (resolved to: {p})")
101
104
  raise RuntimeError("--local flag requires proto.root to be configured")
102
105
 
103
106
  # Default: use git source
@@ -106,13 +109,13 @@ def resolve_proto_root(cfg: CodegenConfig, *, use_local: bool = False) -> Path:
106
109
  git_url = src.git
107
110
  ref = src.ref or LATEST_TAG # Default to latest-tag if not specified
108
111
  if git_url:
109
- cache_dir = Path(cfg.proto.cache_dir).resolve()
112
+ cache_dir = expand_path(cfg.proto.cache_dir).resolve()
110
113
  ensure_git_checkout(git_url, ref, cache_dir)
111
114
  return cache_dir
112
115
 
113
116
  # Fallback to local root if no git source configured
114
117
  if cfg.proto.root and cfg.proto.root != "":
115
- p = Path(cfg.proto.root).resolve()
118
+ p = expand_path(cfg.proto.root).resolve()
116
119
  if p.exists():
117
120
  return p
118
121
 
@@ -4,6 +4,8 @@ import subprocess
4
4
  import tempfile
5
5
 
6
6
  from core import CodegenConfig
7
+ from utils import expand_path
8
+
7
9
 
8
10
  def build_descriptor_set(
9
11
  config: CodegenConfig,
@@ -14,9 +16,10 @@ def build_descriptor_set(
14
16
  proto_root = proto_root.resolve()
15
17
 
16
18
  if config.proto.source and config.proto.source.fds:
17
- return Path(config.proto.source.fds), None
19
+ fds_path = expand_path(config.proto.source.fds).resolve()
20
+ return fds_path, None
18
21
 
19
- cache_dir = Path(config.proto.cache_dir).resolve() if config.proto.cache_dir else (Path.cwd() / ".cache")
22
+ cache_dir = expand_path(config.proto.cache_dir).resolve() if config.proto.cache_dir else (Path.cwd() / ".cache")
20
23
  out_dir = Path(tempfile.mkdtemp(prefix="wizard_protoc_codegen_", dir=cache_dir))
21
24
  fds_path = out_dir / "descriptor.pb"
22
25
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "wizard-codegen"
3
- version = "0.1.5"
3
+ version = "0.1.7"
4
4
  description = "A powerful, template-driven code generation tool for Protocol Buffers"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -5,6 +5,7 @@ Contains helper functions for name transformations and other utilities.
5
5
  """
6
6
 
7
7
  from .name import Name, to_snake, to_kebab, to_pascal, to_camel, to_macro_snake, to_macro
8
+ from .path import expand_path
8
9
 
9
10
  __all__ = [
10
11
  "Name",
@@ -13,5 +14,6 @@ __all__ = [
13
14
  "to_pascal",
14
15
  "to_camel",
15
16
  "to_macro",
16
- "to_macro_snake"
17
+ "to_macro_snake",
18
+ "expand_path",
17
19
  ]
@@ -0,0 +1,27 @@
1
+ """
2
+ Path utility functions.
3
+
4
+ Contains helpers for path expansion and resolution.
5
+ """
6
+ from __future__ import annotations
7
+ from pathlib import Path
8
+ import os
9
+
10
+
11
+ def expand_path(path_str: str) -> Path:
12
+ """
13
+ Expand environment variables and ~ in a path string.
14
+
15
+ Supports:
16
+ - Environment variables: $VAR, ${VAR}
17
+ - Home directory: ~, ~/path
18
+
19
+ Args:
20
+ path_str: Path string that may contain variables
21
+
22
+ Returns:
23
+ Path object with variables expanded
24
+ """
25
+ expanded = os.path.expandvars(path_str) # $VAR, ${VAR}
26
+ expanded = os.path.expanduser(expanded) # ~
27
+ return Path(expanded)