Skip to content

Commit ff1d8c8

Browse files
committed
fix(cli): conditionally generate tests directory and CI steps
- Only generate test directories for `to_sdk` and `to_sdk_cli` if the `--tests` flag is passed. - Only scaffold `pytest` in GitHub actions if `--tests` is passed. chore: refactor pre-commit to use cross-platform primitives - Replaced the platform-specific bash script with official pre-commit package via uv. - Created cross-platform Python scripts (`scripts/run_petstore_test.py`, `scripts/build_wasm.py`) to replace bash commands (`bash -c`, `rm -rf`, `make`) that previously failed on Windows natively.
1 parent 8695a90 commit ff1d8c8

9 files changed

Lines changed: 300 additions & 67 deletions

File tree

‎.pre-commit-config.yaml‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,19 @@ repos:
2828
always_run: true
2929
- id: swagger-2-0-petstore
3030
name: Swagger 2.0 Petstore Test
31-
entry: bash -c "TEST_HARNESS=${TEST_HARNESS_DIR:-/Users/samuel/repos/cdd-openapi-test-harness};
32-
uv run cdd-python from_openapi to_sdk_cli -i $TEST_HARNESS/petstore.json -o
33-
.tmp_swagger && rm -rf .tmp_swagger"
31+
entry: uv run python scripts/run_petstore_test.py petstore.json .tmp_swagger
3432
language: system
3533
pass_filenames: false
3634
always_run: true
3735
- id: openapi-3-2-0-petstore
3836
name: OpenAPI 3.2.0 Petstore Test
39-
entry: bash -c "TEST_HARNESS=${TEST_HARNESS_DIR:-/Users/samuel/repos/cdd-openapi-test-harness};
40-
uv run cdd-python from_openapi to_sdk_cli -i $TEST_HARNESS/petstore_oas3.json
41-
-o .tmp_oas3 && rm -rf .tmp_oas3"
37+
entry: uv run python scripts/run_petstore_test.py petstore_oas3.json .tmp_oas3
4238
language: system
4339
pass_filenames: false
4440
always_run: true
4541
- id: build-wasm
4642
name: Build WASM
47-
entry: make build_wasm
43+
entry: uv run python scripts/build_wasm.py
4844
language: system
4945
pass_filenames: false
5046
always_run: true

‎Makefile‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ build:
4848

4949
build_wasm:
5050
@echo "Building WASM to bin/"
51-
@mkdir -p bin
52-
uv run py2wasm src/openapi_client/cli.py -o bin/cdd-python-all.wasm || (echo "WASI build failed. Falling back to Pyodide zip bundle." && rm -f bin/cdd-python-all.wasm && zip -r bin/cdd-python-all.wasm src pyproject.toml)
51+
uv run python scripts/build_wasm.py
5352
test:
5453
uv run pytest tests/
5554
run: build

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ cdd-python-all
22
==============
33
[![License](https://img.shields.io/badge/license-Apache--2.0%20OR%20MIT-blue.svg)](https://opensource.org/licenses/Apache-2.0)
44
[![CI](https://github.com/offscale/cdd-python-all/actions/workflows/ci.yml/badge.svg)](https://github.com/offscale/cdd-python-all/actions)
5-
[![Test Coverage](https://img.shields.io/badge/test_coverage-100%25-brightgreen.svg)](#)
5+
[![Test Coverage](https://img.shields.io/badge/test_coverage-99%25-brightgreen.svg)](#)
66
[![Doc Coverage](https://img.shields.io/badge/doc_coverage-100%25-brightgreen.svg)](#)
77

88
----

‎pyproject.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ testpaths = ["tests", "test"]
3939

4040
[dependency-groups]
4141
dev = [
42+
"pre-commit>=4.3.0",
4243
"ruff>=0.15.13",
4344
]

‎scripts/build_wasm.py‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import os
2+
import subprocess
3+
4+
def main():
5+
os.makedirs("bin", exist_ok=True)
6+
wasm_out = os.path.join("bin", "cdd-python-all.wasm")
7+
8+
try:
9+
print("Building WASI...")
10+
subprocess.run(["uv", "run", "py2wasm", "src/openapi_client/cli.py", "-o", wasm_out], check=True)
11+
except subprocess.CalledProcessError:
12+
print("WASI build failed. Falling back to Pyodide zip bundle.")
13+
if os.path.exists(wasm_out):
14+
os.remove(wasm_out)
15+
16+
# Cross-platform zip
17+
import zipfile
18+
with zipfile.ZipFile(wasm_out, 'w', zipfile.ZIP_DEFLATED) as zipf:
19+
for root, dirs, files in os.walk("src"):
20+
for file in files:
21+
if "__pycache__" not in root and file.endswith(".py"):
22+
file_path = os.path.join(root, file)
23+
zipf.write(file_path, file_path)
24+
if os.path.exists("pyproject.toml"):
25+
zipf.write("pyproject.toml", "pyproject.toml")
26+
27+
if __name__ == "__main__":
28+
main()

‎scripts/pre-commit‎

Lines changed: 0 additions & 39 deletions
This file was deleted.

‎scripts/run_petstore_test.py‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import os
2+
import sys
3+
import shutil
4+
import subprocess
5+
6+
def main():
7+
test_harness_dir = os.environ.get("TEST_HARNESS_DIR", os.path.expanduser("~/repos/cdd-openapi-test-harness"))
8+
9+
if len(sys.argv) < 3:
10+
print("Usage: run_petstore_test.py <json_file> <tmp_dir>")
11+
sys.exit(1)
12+
13+
json_file = sys.argv[1]
14+
tmp_dir = sys.argv[2]
15+
16+
input_path = os.path.join(test_harness_dir, json_file)
17+
if not os.path.exists(input_path):
18+
print(f"Skipping test, missing {input_path}")
19+
sys.exit(0)
20+
21+
cmd = ["uv", "run", "cdd-python", "from_openapi", "to_sdk_cli", "-i", input_path, "-o", tmp_dir]
22+
23+
try:
24+
print(f"Running petstore test against {input_path} -> {tmp_dir}")
25+
subprocess.run(cmd, check=True)
26+
finally:
27+
if os.path.exists(tmp_dir):
28+
shutil.rmtree(tmp_dir)
29+
30+
if __name__ == "__main__":
31+
main()

‎src/openapi_client/cli.py‎

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,21 @@ def scaffold_package(out_dir: Path):
175175
)
176176

177177

178-
def scaffold_github_actions(out_dir: Path):
178+
def scaffold_github_actions(out_dir: Path, tests: bool = False):
179179
"""Scaffold GitHub actions CI file."""
180180
workflows_dir = out_dir / ".github" / "workflows"
181181
workflows_dir.mkdir(parents=True, exist_ok=True)
182182

183183
ci_yml = workflows_dir / "ci.yml"
184184
if not ci_yml.exists():
185+
test_step = ""
186+
if tests:
187+
test_step = """
188+
- name: Run tests
189+
run: pytest test/"""
190+
185191
ci_yml.write_text(
186-
"""name: CI
192+
f"""name: CI
187193
on: [push, pull_request]
188194
189195
jobs:
@@ -196,9 +202,7 @@ def scaffold_github_actions(out_dir: Path):
196202
with:
197203
python-version: '3.11'
198204
- name: Install dependencies
199-
run: pip install -e .[dev]
200-
- name: Run tests
201-
run: pytest test/
205+
run: pip install -e .[dev]{test_step}
202206
""",
203207
encoding="utf-8",
204208
)
@@ -259,18 +263,18 @@ def process_from_openapi(
259263
emit_openapi_json(spec, indent=2), encoding="utf-8"
260264
)
261265

262-
# Always emit tests for to_sdk
263-
test_dir = out_dir / "test"
264-
test_dir.mkdir(parents=True, exist_ok=True)
265-
(test_dir / "__init__.py").touch()
266-
(test_dir / "test_client.py").write_text(
267-
emit_tests(spec, composable=True).code, encoding="utf-8"
268-
)
269-
from openapi_client.mocks.emit import emit_mock_server
266+
if tests:
267+
test_dir = out_dir / "test"
268+
test_dir.mkdir(parents=True, exist_ok=True)
269+
(test_dir / "__init__.py").touch()
270+
(test_dir / "test_client.py").write_text(
271+
emit_tests(spec, composable=True).code, encoding="utf-8"
272+
)
273+
from openapi_client.mocks.emit import emit_mock_server
270274

271-
(test_dir / "mock_server.py").write_text(
272-
emit_mock_server(spec).code, encoding="utf-8"
273-
)
275+
(test_dir / "mock_server.py").write_text(
276+
emit_mock_server(spec).code, encoding="utf-8"
277+
)
274278
elif subcommand == "to_sdk_cli":
275279
from openapi_client.classes.emit import emit_models_module
276280

@@ -292,6 +296,19 @@ def process_from_openapi(
292296
from openapi_client.cli_sdk_cdd.emit import emit_cli_sdk
293297

294298
(src_dir / "cli_main.py").write_text(emit_cli_sdk(spec), encoding="utf-8")
299+
300+
if tests:
301+
test_dir = out_dir / "test"
302+
test_dir.mkdir(parents=True, exist_ok=True)
303+
(test_dir / "__init__.py").touch()
304+
(test_dir / "test_client.py").write_text(
305+
emit_tests(spec, composable=True).code, encoding="utf-8"
306+
)
307+
from openapi_client.mocks.emit import emit_mock_server
308+
309+
(test_dir / "mock_server.py").write_text(
310+
emit_mock_server(spec).code, encoding="utf-8"
311+
)
295312
elif subcommand == "to_server":
296313
from openapi_client.fastapi.emit import emit_fastapi
297314
from openapi_client.sqlalchemy_cdd.emit import emit_sqlalchemy
@@ -311,7 +328,7 @@ def process_from_openapi(
311328
scaffold_package(out_dir)
312329

313330
if not no_github_actions:
314-
scaffold_github_actions(out_dir)
331+
scaffold_github_actions(out_dir, tests=tests)
315332

316333
print(f"Successfully generated {subcommand} in {out_dir}")
317334

0 commit comments

Comments
 (0)