openapi-client-codegen 0.1.11__tar.gz → 0.1.12__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.
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/.github/workflows/release.yml +1 -1
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/AGENTS.md +5 -4
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/PKG-INFO +3 -1
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/pyproject.toml +11 -2
- openapi_client_codegen-0.1.12/release-devkit.json +10 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/cli.py +3 -3
- openapi_client_codegen-0.1.12/src/openapi_client_codegen/orchestrator.py +61 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/tests/test_cli.py +5 -3
- openapi_client_codegen-0.1.12/tests/test_config.py +114 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/tests/test_orchestrate.py +7 -4
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/uv.lock +100 -0
- openapi_client_codegen-0.1.11/release-devkit.json +0 -13
- openapi_client_codegen-0.1.11/src/openapi_client_codegen/orchestrator.py +0 -37
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/.gitattributes +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/.github/workflows/ci.yml +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/.gitignore +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/.python-version +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/CLAUDE.md +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/LICENSE +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/NOTICE +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/README.md +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/ruff.base.toml +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/ruff.toml +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/__init__.py +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/configs/csharp.json +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/configs/python.json +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/openapi-generator-ignore +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/templates-patches/csharp/0001-csharp-remove-errant-comma.patch +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/templates-patches/csharp/0002-csharp-models-required-only-constructors.patch +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/templates-patches/csharp/0003-csharp-httpclient-use-defaultT.patch +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/templates-patches/csharp/0004-csharp-support-hybrid-multipart-payloads.patch +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/templates-patches/csharp/0006-csharp-streaming-download-response.patch +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/templates-patches/csharp/0007-csharp-model-default-initializers.patch +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/_data/templates-patches/csharp/0008-csharp-redirect-documentation-file.patch +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/client.py +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/downgrade.py +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/py.typed +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/resources.py +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/templates.py +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/unity.py +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/tests/test_downgrade.py +0 -0
- {openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/tests/test_unity.py +0 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
`openapi-client-codegen` wraps [OpenAPI Generator](https://openapi-generator.tech/) to turn an OpenAPI schema into typed client packages — a Python (`httpx`) client and a Unity-consumable C# (`httpclient`) client. It owns every step that is generic across consumers: the project orchestration loop, downgrading 3.1→3.0, the committed-spec unchanged skip, authoring and patching the C# templates, running the generator, and writing the Unity package metadata. The caller owns what is inherently project-specific: **producing the OpenAPI spec** (a command string in the consumer's config, run by the library's `SpecProducer`), the project→client mapping, the naming root, the npm scope, license, repository URL, and the generated output root — all as fields of the `ProjectsConfig` model.
|
|
6
6
|
|
|
7
|
-
The package is `openapi_client_codegen` (src-layout under `src/openapi_client_codegen/`), renamed from `openapi-clientgen` before the first publish (operator, 2026-09-20 — no artifact carries the old name). Its Python dependencies are `bashrun` (the guardrailed subprocess wrapper), `pydantic` (the config schema), and `typer` (the thin CLI), all from PyPI — git-source pins only in scratch branches testing unreleased changes. At **runtime** it also needs **Java (JDK 11+)** and **`uvx`** on PATH — the generator itself runs as `uvx --from 'openapi-generator-cli[jdk4py]==<pin>' ...`.
|
|
7
|
+
The package is `openapi_client_codegen` (src-layout under `src/openapi_client_codegen/`), renamed from `openapi-clientgen` before the first publish (operator, 2026-09-20 — no artifact carries the old name). Its Python dependencies are `bashrun` (the guardrailed subprocess wrapper), `packaging` (PEP 440 specifier parsing for `requires`), `pydantic` (the config schema), `strictyaml` (config loading), and `typer` (the thin CLI), all from PyPI — git-source pins only in scratch branches testing unreleased changes. At **runtime** it also needs **Java (JDK 11+)** and **`uvx`** on PATH — the generator itself runs as `uvx --from 'openapi-generator-cli[jdk4py]==<pin>' ...`.
|
|
8
8
|
|
|
9
9
|
## Release flow
|
|
10
10
|
|
|
@@ -12,14 +12,15 @@ Publishing rides `release.yml`, triggered by a successful CI run on a `main` pus
|
|
|
12
12
|
|
|
13
13
|
## Public API
|
|
14
14
|
|
|
15
|
-
The package init is empty (RUF067 strict mode — the canonical ruff config bans any content in `__init__.py`); import each symbol from its defining module: `client` (`generate_client`), `cli` (`app`), `downgrade` (`downgrade_openapi_3_1_to_3_0`, `JsonDict`), `orchestrator` (`ProjectsConfig`, `ClientNaming`, `SpecProducer`), `templates` (`regenerate_templates`), `unity` (`write_unity_package_metadata`).
|
|
15
|
+
The package init is empty (RUF067 strict mode — the canonical ruff config bans any content in `__init__.py`); import each symbol from its defining module: `client` (`generate_client`), `cli` (`app`), `downgrade` (`downgrade_openapi_3_1_to_3_0`, `JsonDict`), `orchestrator` (`ProjectsConfig`, `ClientNaming`, `SpecProducer`, `load_config`), `templates` (`regenerate_templates`), `unity` (`write_unity_package_metadata`).
|
|
16
16
|
|
|
17
17
|
| Symbol | Role |
|
|
18
18
|
|---|---|
|
|
19
19
|
| `downgrade_openapi_3_1_to_3_0(schema)` | In-place 3.1.0→3.0.3 fixup (openapi-generator rejects 3.1). Pure function. |
|
|
20
|
-
| `ProjectsConfig` | The pydantic schema of a consumer's client-generation config (`extra="forbid"`): required `projects`, `root_name`, `generated_root`, `spec_command`; optional `spec_env`, `npm_scope`, `license_spdx`, `repository_url`. The single source of identity — the CLI validates the `--config` file into it and consumes it; nothing overrides it per invocation. |
|
|
20
|
+
| `ProjectsConfig` | The pydantic schema of a consumer's client-generation config (`extra="forbid"`): required `projects`, `root_name`, `generated_root`, `spec_command`, `requires`; optional `spec_env`, `npm_scope`, `license_spdx`, `repository_url`. `requires` is a PEP 440 specifier; `load_config` self-checks the installed version and refuses outside range; the `0.0.0.dev0` sentinel bypasses the *check*, not the field's presence (omission is a validation error; "no constraint" is explicit `requires: ">=0.0"`). The single source of identity — the CLI validates the `--config` file into it and consumes it; nothing overrides it per invocation. |
|
|
21
|
+
| `load_config(path)` | Parse the consumer's root YAML config into a `ProjectsConfig` (strictyaml, scalars as strings) and enforce the required `requires` version self-check. |
|
|
21
22
|
| `SpecProducer(command, env=None)` | Callable class wrapping any command that prints the spec to stdout, run with the project directory as cwd and an optional per-call env overlay; the CLI command builds it from the config's `spec_command` / `spec_env`, and programmatic consumers construct it directly. |
|
|
22
|
-
| `app` | The single-command CLI (invoked directly, no subcommand) behind the `openapi-client-codegen` console script and consumer `[project.scripts]` aliases (e.g. placeframe's `generate-clients`). It validates the `--config`
|
|
23
|
+
| `app` | The single-command CLI (invoked directly, no subcommand) behind the `openapi-client-codegen` console script and consumer `[project.scripts]` aliases (e.g. placeframe's `generate-clients`). It validates the `--config` YAML against the `ProjectsConfig` pydantic model (via `load_config`) (`extra="forbid"`: unknown keys rejected — a `ValidationError` propagates) and then runs the whole orchestration itself: per mapping entry (`projects` maps project paths to generator lists), produce the spec via `SpecProducer`, downgrade it, write `<project>/openapi.json` unless byte-identical to the committed spec (`no_cache` forces through), and `generate_client` per listed generator into `<generated_root>/<generator>/<names.base>`. The flags are invocation-scoped only (filters, `--no-cache`, `--root`; project paths resolve against `root`). Commands run shell-less (shlex-split, operators rejected), so env gating is the structured `spec_env`, never a `VAR=…` prefix. |
|
|
23
24
|
| `regenerate_templates(target_dir, extra_patches_dir=None)` | Author the C# templates into `target_dir/csharp` and apply the shipped (then optional extra) patches. |
|
|
24
25
|
| `generate_client(spec, generator, output_dir, names, templates_dir=None, extra_references=None, npm_scope=None, license_spdx=None, repository_url=None)` | Run the generator for one `(spec, generator)` and sync the result into `output_dir`. `templates_dir` is required for `csharp`. For csharp, `npm_scope` composes the UPM identity `{scope}.{base-minus-dashes}` (e.g. `org.outernet.placeframe.apiclient`); unset falls back to the legacy `org.nuget.{camel-lower}` identity. `license_spdx` / `repository_url` populate the manifest's `license` / `repository` fields when given. |
|
|
25
26
|
| `write_unity_package_metadata(package_dir, package_name, extra_references=None, npm_name=None, license_spdx=None, repository_url=None)` | Write `package.json` / `.asmdef` / `csc.rsp` / `Directory.Build.props`. Called by `generate_client` for csharp. |
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: openapi-client-codegen
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
4
4
|
Summary: OpenAPI client-generation wrapper: Litestar spec dump, 3.1->3.0 downgrade, patched openapi-generator templates, Unity package metadata
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
License-File: NOTICE
|
|
7
7
|
Requires-Python: >=3.13
|
|
8
8
|
Requires-Dist: bashrun>=0.1.0
|
|
9
|
+
Requires-Dist: packaging>=24.1
|
|
9
10
|
Requires-Dist: pydantic>=2.11.7
|
|
11
|
+
Requires-Dist: strictyaml>=1.7.3
|
|
10
12
|
Requires-Dist: typer>=0.17.4
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "openapi-client-codegen"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.12"
|
|
4
4
|
description = "OpenAPI client-generation wrapper: Litestar spec dump, 3.1->3.0 downgrade, patched openapi-generator templates, Unity package metadata"
|
|
5
5
|
requires-python = ">=3.13"
|
|
6
6
|
dependencies = [
|
|
7
7
|
"bashrun>=0.1.0",
|
|
8
|
+
"packaging>=24.1",
|
|
8
9
|
"pydantic>=2.11.7",
|
|
10
|
+
"strictyaml>=1.7.3",
|
|
9
11
|
"typer>=0.17.4",
|
|
10
12
|
]
|
|
11
13
|
|
|
12
14
|
[dependency-groups]
|
|
13
|
-
dev = [
|
|
15
|
+
dev = [
|
|
16
|
+
"basedpyright>=1.39.10",
|
|
17
|
+
"ruff>=0.14.11",
|
|
18
|
+
"pytest>=8.0.0",
|
|
19
|
+
"pyyaml>=6.0.3",
|
|
20
|
+
"types-pyyaml>=6.0.12.20260906",
|
|
21
|
+
"types-strictyaml>=1.7.3.3",
|
|
22
|
+
]
|
|
14
23
|
|
|
15
24
|
[build-system]
|
|
16
25
|
requires = ["hatchling"]
|
{openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/cli.py
RENAMED
|
@@ -7,7 +7,7 @@ from typer import Option, Typer
|
|
|
7
7
|
|
|
8
8
|
from .client import generate_client
|
|
9
9
|
from .downgrade import downgrade_openapi_3_1_to_3_0
|
|
10
|
-
from .orchestrator import ClientNaming,
|
|
10
|
+
from .orchestrator import ClientNaming, SpecProducer, load_config
|
|
11
11
|
from .templates import regenerate_templates
|
|
12
12
|
|
|
13
13
|
app = Typer(pretty_exceptions_show_locals=False)
|
|
@@ -16,7 +16,7 @@ app = Typer(pretty_exceptions_show_locals=False)
|
|
|
16
16
|
@app.command()
|
|
17
17
|
def generate_projects_command(
|
|
18
18
|
config: Annotated[
|
|
19
|
-
Path, Option(help="
|
|
19
|
+
Path, Option(help="YAML config carrying the projects mapping, the client identity, and the spec command")
|
|
20
20
|
],
|
|
21
21
|
project: Annotated[str | None, Option(help="Generate only this project, as keyed in the config")] = None,
|
|
22
22
|
client: Annotated[str | None, Option(help="Generate only this client generator")] = None,
|
|
@@ -25,7 +25,7 @@ def generate_projects_command(
|
|
|
25
25
|
] = False,
|
|
26
26
|
root: Annotated[Path, Option(help="Repository root the project paths resolve against")] = Path(),
|
|
27
27
|
) -> None:
|
|
28
|
-
settings =
|
|
28
|
+
settings = load_config(config)
|
|
29
29
|
root = root.resolve()
|
|
30
30
|
dump_spec = SpecProducer(settings.spec_command, env=settings.spec_env)
|
|
31
31
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import importlib.metadata
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from bashrun.bash import bash_output
|
|
8
|
+
from packaging.specifiers import SpecifierSet
|
|
9
|
+
from pydantic import BaseModel, ConfigDict, field_validator
|
|
10
|
+
from strictyaml import load as load_strict_yaml
|
|
11
|
+
|
|
12
|
+
DEV_SENTINEL = "0.0.0.dev0"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ProjectsConfig(BaseModel):
|
|
16
|
+
model_config = ConfigDict(extra="forbid")
|
|
17
|
+
|
|
18
|
+
projects: dict[str, list[str]]
|
|
19
|
+
root_name: str
|
|
20
|
+
generated_root: Path
|
|
21
|
+
spec_command: str
|
|
22
|
+
spec_env: dict[str, str] | None = None
|
|
23
|
+
npm_scope: str | None = None
|
|
24
|
+
license_spdx: str | None = None
|
|
25
|
+
repository_url: str | None = None
|
|
26
|
+
requires: str
|
|
27
|
+
|
|
28
|
+
@field_validator("requires")
|
|
29
|
+
@classmethod
|
|
30
|
+
def validate_requires(cls, value: str) -> str:
|
|
31
|
+
if not value:
|
|
32
|
+
raise ValueError("requires must be a non-empty PEP 440 specifier; use '>=0.0' for no constraint")
|
|
33
|
+
SpecifierSet(value)
|
|
34
|
+
return value
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(frozen=True)
|
|
38
|
+
class ClientNaming:
|
|
39
|
+
base: str
|
|
40
|
+
dashed: str
|
|
41
|
+
underscored: str
|
|
42
|
+
camel: str
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SpecProducer:
|
|
46
|
+
def __init__(self, command: str, env: dict[str, str] | None = None) -> None:
|
|
47
|
+
self.command = command
|
|
48
|
+
self.env = env
|
|
49
|
+
|
|
50
|
+
def __call__(self, project: Path) -> str:
|
|
51
|
+
return bash_output(self.command, cwd=project, env=self.env)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def load_config(path: Path) -> ProjectsConfig:
|
|
55
|
+
config = ProjectsConfig.model_validate(load_strict_yaml(path.read_text(encoding="utf-8")).data)
|
|
56
|
+
installed = importlib.metadata.version("openapi-client-codegen")
|
|
57
|
+
if installed == DEV_SENTINEL:
|
|
58
|
+
return config
|
|
59
|
+
if not SpecifierSet(config.requires).contains(installed, prereleases=True):
|
|
60
|
+
raise SystemExit(f"openapi-client-codegen {installed} does not satisfy requires={config.requires!r}")
|
|
61
|
+
return config
|
|
@@ -2,6 +2,7 @@ import json
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
|
|
4
4
|
import pytest
|
|
5
|
+
import yaml
|
|
5
6
|
from typer.testing import CliRunner
|
|
6
7
|
|
|
7
8
|
from openapi_client_codegen import cli, orchestrator
|
|
@@ -19,6 +20,7 @@ FULL_SETTINGS: dict[str, object] = {
|
|
|
19
20
|
"npm_scope": "org.example.placeframe",
|
|
20
21
|
"license_spdx": "Apache-2.0",
|
|
21
22
|
"repository_url": "https://github.com/org/repo.git",
|
|
23
|
+
"requires": ">=0.1",
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
|
|
@@ -57,8 +59,8 @@ def recorder(monkeypatch: pytest.MonkeyPatch) -> Recorder:
|
|
|
57
59
|
|
|
58
60
|
|
|
59
61
|
def write_config(directory: Path, settings: dict[str, object]) -> Path:
|
|
60
|
-
config = directory / "clients.
|
|
61
|
-
config.write_text(
|
|
62
|
+
config = directory / "clients.yaml"
|
|
63
|
+
config.write_text(yaml.safe_dump(settings, default_flow_style=False, sort_keys=False), encoding="utf-8")
|
|
62
64
|
return config
|
|
63
65
|
|
|
64
66
|
|
|
@@ -76,7 +78,7 @@ def test_filter_flags_restrict_generation(tmp_path: Path, recorder: Recorder) ->
|
|
|
76
78
|
|
|
77
79
|
|
|
78
80
|
def test_unknown_config_key_fails_loudly(tmp_path: Path, recorder: Recorder) -> None:
|
|
79
|
-
config = write_config(tmp_path, {"projects": {}, "rot_name": "placeframe"})
|
|
81
|
+
config = write_config(tmp_path, {"projects": {"docker/api": ["python"]}, "rot_name": "placeframe"})
|
|
80
82
|
|
|
81
83
|
result = runner.invoke(app, ["--config", str(config)])
|
|
82
84
|
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import importlib.metadata
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
import yaml
|
|
6
|
+
from pydantic import ValidationError
|
|
7
|
+
|
|
8
|
+
from openapi_client_codegen.orchestrator import DEV_SENTINEL, load_config
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def write_config(tmp_path: Path, payload: dict[str, object]) -> Path:
|
|
12
|
+
config_path = tmp_path / "openapi-client-codegen.yaml"
|
|
13
|
+
config_path.write_text(
|
|
14
|
+
yaml.safe_dump(payload, default_flow_style=False, sort_keys=False),
|
|
15
|
+
encoding="utf-8",
|
|
16
|
+
)
|
|
17
|
+
return config_path
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def base_payload() -> dict[str, object]:
|
|
21
|
+
return {
|
|
22
|
+
"projects": {"docker/api": ["python"]},
|
|
23
|
+
"root_name": "placeframe",
|
|
24
|
+
"generated_root": "packages/generated",
|
|
25
|
+
"spec_command": "uv run --project . python -m src.dump_openapi",
|
|
26
|
+
"requires": ">=0.1",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _version_dev_sentinel(_name: str) -> str:
|
|
31
|
+
return DEV_SENTINEL
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _version_0_1_18(_name: str) -> str:
|
|
35
|
+
return "0.1.18"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _version_0_1_19_dev5(_name: str) -> str:
|
|
39
|
+
return "0.1.19.dev5"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _version_0_1_17(_name: str) -> str:
|
|
43
|
+
return "0.1.17"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_load_config_parses_yaml(tmp_path: Path) -> None:
|
|
47
|
+
config = load_config(write_config(tmp_path, base_payload()))
|
|
48
|
+
|
|
49
|
+
assert config.projects == {"docker/api": ["python"]}
|
|
50
|
+
assert config.root_name == "placeframe"
|
|
51
|
+
assert config.requires == ">=0.1"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_requires_omitted_is_required(tmp_path: Path) -> None:
|
|
55
|
+
payload = base_payload()
|
|
56
|
+
del payload["requires"]
|
|
57
|
+
|
|
58
|
+
with pytest.raises(ValidationError, match="requires"):
|
|
59
|
+
load_config(write_config(tmp_path, payload))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_requires_empty_string_rejected(tmp_path: Path) -> None:
|
|
63
|
+
payload = base_payload()
|
|
64
|
+
payload["requires"] = ""
|
|
65
|
+
|
|
66
|
+
with pytest.raises(ValidationError, match="requires"):
|
|
67
|
+
load_config(write_config(tmp_path, payload))
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_requires_dev_sentinel_skips_check(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
71
|
+
monkeypatch.setattr(importlib.metadata, "version", _version_dev_sentinel)
|
|
72
|
+
payload = base_payload()
|
|
73
|
+
payload["requires"] = ">=0.1.18"
|
|
74
|
+
|
|
75
|
+
config = load_config(write_config(tmp_path, payload))
|
|
76
|
+
|
|
77
|
+
assert config.requires == ">=0.1.18"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_requires_in_range_loads(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
81
|
+
monkeypatch.setattr(importlib.metadata, "version", _version_0_1_18)
|
|
82
|
+
payload = base_payload()
|
|
83
|
+
payload["requires"] = ">=0.1.18"
|
|
84
|
+
|
|
85
|
+
config = load_config(write_config(tmp_path, payload))
|
|
86
|
+
|
|
87
|
+
assert config.requires == ">=0.1.18"
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_requires_dev_channel_prerelease_satisfies(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
91
|
+
monkeypatch.setattr(importlib.metadata, "version", _version_0_1_19_dev5)
|
|
92
|
+
payload = base_payload()
|
|
93
|
+
payload["requires"] = ">=0.1.18"
|
|
94
|
+
|
|
95
|
+
config = load_config(write_config(tmp_path, payload))
|
|
96
|
+
|
|
97
|
+
assert config.requires == ">=0.1.18"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_requires_out_of_range_refuses(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
101
|
+
monkeypatch.setattr(importlib.metadata, "version", _version_0_1_17)
|
|
102
|
+
payload = base_payload()
|
|
103
|
+
payload["requires"] = ">=0.1.18"
|
|
104
|
+
|
|
105
|
+
with pytest.raises(SystemExit, match="does not satisfy requires"):
|
|
106
|
+
load_config(write_config(tmp_path, payload))
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_requires_invalid_specifier_rejected(tmp_path: Path) -> None:
|
|
110
|
+
payload = base_payload()
|
|
111
|
+
payload["requires"] = "not-a-specifier"
|
|
112
|
+
|
|
113
|
+
with pytest.raises(ValidationError, match="requires"):
|
|
114
|
+
load_config(write_config(tmp_path, payload))
|
|
@@ -4,6 +4,7 @@ from collections.abc import Callable
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
|
+
import yaml
|
|
7
8
|
from typer.testing import CliRunner
|
|
8
9
|
|
|
9
10
|
from openapi_client_codegen import cli, orchestrator
|
|
@@ -64,9 +65,10 @@ def invoke(tmp_path: Path, projects: dict[str, list[str]], *args: str) -> None:
|
|
|
64
65
|
"root_name": "placeframe",
|
|
65
66
|
"generated_root": str(tmp_path / "generated"),
|
|
66
67
|
"spec_command": "dump-openapi",
|
|
68
|
+
"requires": ">=0.1",
|
|
67
69
|
}
|
|
68
|
-
config = tmp_path / "clients.
|
|
69
|
-
config.write_text(
|
|
70
|
+
config = tmp_path / "clients.yaml"
|
|
71
|
+
config.write_text(yaml.safe_dump(settings, default_flow_style=False, sort_keys=False), encoding="utf-8")
|
|
70
72
|
|
|
71
73
|
result = runner.invoke(app, ["--config", str(config), "--root", str(tmp_path), *args])
|
|
72
74
|
assert result.exit_code == 0
|
|
@@ -143,9 +145,10 @@ def test_spec_env_rides_the_spec_command(tmp_path: Path, recorder: Recorder) ->
|
|
|
143
145
|
"generated_root": str(tmp_path / "generated"),
|
|
144
146
|
"spec_command": "dump-openapi",
|
|
145
147
|
"spec_env": {"CODEGEN": "1"},
|
|
148
|
+
"requires": ">=0.1",
|
|
146
149
|
}
|
|
147
|
-
config = tmp_path / "clients.
|
|
148
|
-
config.write_text(
|
|
150
|
+
config = tmp_path / "clients.yaml"
|
|
151
|
+
config.write_text(yaml.safe_dump(settings, default_flow_style=False, sort_keys=False), encoding="utf-8")
|
|
149
152
|
result = runner.invoke(app, ["--config", str(config), "--root", str(tmp_path)])
|
|
150
153
|
assert result.exit_code == 0
|
|
151
154
|
|
|
@@ -102,7 +102,9 @@ version = "0.0.0.dev0"
|
|
|
102
102
|
source = { editable = "." }
|
|
103
103
|
dependencies = [
|
|
104
104
|
{ name = "bashrun" },
|
|
105
|
+
{ name = "packaging" },
|
|
105
106
|
{ name = "pydantic" },
|
|
107
|
+
{ name = "strictyaml" },
|
|
106
108
|
{ name = "typer" },
|
|
107
109
|
]
|
|
108
110
|
|
|
@@ -110,13 +112,18 @@ dependencies = [
|
|
|
110
112
|
dev = [
|
|
111
113
|
{ name = "basedpyright" },
|
|
112
114
|
{ name = "pytest" },
|
|
115
|
+
{ name = "pyyaml" },
|
|
113
116
|
{ name = "ruff" },
|
|
117
|
+
{ name = "types-pyyaml" },
|
|
118
|
+
{ name = "types-strictyaml" },
|
|
114
119
|
]
|
|
115
120
|
|
|
116
121
|
[package.metadata]
|
|
117
122
|
requires-dist = [
|
|
118
123
|
{ name = "bashrun", specifier = ">=0.1.0" },
|
|
124
|
+
{ name = "packaging", specifier = ">=24.1" },
|
|
119
125
|
{ name = "pydantic", specifier = ">=2.11.7" },
|
|
126
|
+
{ name = "strictyaml", specifier = ">=1.7.3" },
|
|
120
127
|
{ name = "typer", specifier = ">=0.17.4" },
|
|
121
128
|
]
|
|
122
129
|
|
|
@@ -124,7 +131,10 @@ requires-dist = [
|
|
|
124
131
|
dev = [
|
|
125
132
|
{ name = "basedpyright", specifier = ">=1.39.10" },
|
|
126
133
|
{ name = "pytest", specifier = ">=8.0.0" },
|
|
134
|
+
{ name = "pyyaml", specifier = ">=6.0.3" },
|
|
127
135
|
{ name = "ruff", specifier = ">=0.14.11" },
|
|
136
|
+
{ name = "types-pyyaml", specifier = ">=6.0.12.20260906" },
|
|
137
|
+
{ name = "types-strictyaml", specifier = ">=1.7.3.3" },
|
|
128
138
|
]
|
|
129
139
|
|
|
130
140
|
[[package]]
|
|
@@ -241,6 +251,54 @@ wheels = [
|
|
|
241
251
|
{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
|
|
242
252
|
]
|
|
243
253
|
|
|
254
|
+
[[package]]
|
|
255
|
+
name = "python-dateutil"
|
|
256
|
+
version = "2.9.0.post0"
|
|
257
|
+
source = { registry = "https://pypi.org/simple" }
|
|
258
|
+
dependencies = [
|
|
259
|
+
{ name = "six" },
|
|
260
|
+
]
|
|
261
|
+
sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
|
|
262
|
+
wheels = [
|
|
263
|
+
{ url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
[[package]]
|
|
267
|
+
name = "pyyaml"
|
|
268
|
+
version = "6.0.3"
|
|
269
|
+
source = { registry = "https://pypi.org/simple" }
|
|
270
|
+
sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" }
|
|
271
|
+
wheels = [
|
|
272
|
+
{ url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" },
|
|
273
|
+
{ url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" },
|
|
274
|
+
{ url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" },
|
|
275
|
+
{ url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" },
|
|
276
|
+
{ url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" },
|
|
277
|
+
{ url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" },
|
|
278
|
+
{ url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" },
|
|
279
|
+
{ url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" },
|
|
280
|
+
{ url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" },
|
|
281
|
+
{ url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" },
|
|
282
|
+
{ url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" },
|
|
283
|
+
{ url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" },
|
|
284
|
+
{ url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" },
|
|
285
|
+
{ url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" },
|
|
286
|
+
{ url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" },
|
|
287
|
+
{ url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" },
|
|
288
|
+
{ url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" },
|
|
289
|
+
{ url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" },
|
|
290
|
+
{ url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" },
|
|
291
|
+
{ url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" },
|
|
292
|
+
{ url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" },
|
|
293
|
+
{ url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" },
|
|
294
|
+
{ url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" },
|
|
295
|
+
{ url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" },
|
|
296
|
+
{ url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" },
|
|
297
|
+
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
|
|
298
|
+
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
|
|
299
|
+
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
|
|
300
|
+
]
|
|
301
|
+
|
|
244
302
|
[[package]]
|
|
245
303
|
name = "rich"
|
|
246
304
|
version = "15.0.0"
|
|
@@ -288,6 +346,27 @@ wheels = [
|
|
|
288
346
|
{ url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" },
|
|
289
347
|
]
|
|
290
348
|
|
|
349
|
+
[[package]]
|
|
350
|
+
name = "six"
|
|
351
|
+
version = "1.17.0"
|
|
352
|
+
source = { registry = "https://pypi.org/simple" }
|
|
353
|
+
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
|
|
354
|
+
wheels = [
|
|
355
|
+
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
|
|
356
|
+
]
|
|
357
|
+
|
|
358
|
+
[[package]]
|
|
359
|
+
name = "strictyaml"
|
|
360
|
+
version = "1.7.3"
|
|
361
|
+
source = { registry = "https://pypi.org/simple" }
|
|
362
|
+
dependencies = [
|
|
363
|
+
{ name = "python-dateutil" },
|
|
364
|
+
]
|
|
365
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b3/08/efd28d49162ce89c2ad61a88bd80e11fb77bc9f6c145402589112d38f8af/strictyaml-1.7.3.tar.gz", hash = "sha256:22f854a5fcab42b5ddba8030a0e4be51ca89af0267961c8d6cfa86395586c407", size = 115206, upload-time = "2023-03-10T12:50:27.062Z" }
|
|
366
|
+
wheels = [
|
|
367
|
+
{ url = "https://files.pythonhosted.org/packages/96/7c/a81ef5ef10978dd073a854e0fa93b5d8021d0594b639cc8f6453c3c78a1d/strictyaml-1.7.3-py3-none-any.whl", hash = "sha256:fb5c8a4edb43bebb765959e420f9b3978d7f1af88c80606c03fb420888f5d1c7", size = 123917, upload-time = "2023-03-10T12:50:17.242Z" },
|
|
368
|
+
]
|
|
369
|
+
|
|
291
370
|
[[package]]
|
|
292
371
|
name = "typer"
|
|
293
372
|
version = "0.26.8"
|
|
@@ -303,6 +382,27 @@ wheels = [
|
|
|
303
382
|
{ url = "https://files.pythonhosted.org/packages/80/87/b9fd69c92c6102a066e1b86a35243f53e70bd4c709f2a26d9f4fee4f4dc0/typer-0.26.8-py3-none-any.whl", hash = "sha256:3512ca79ac5c11113414b36e80281b872884477722440691c89d1112e321a49c", size = 122564, upload-time = "2026-06-26T09:22:44.72Z" },
|
|
304
383
|
]
|
|
305
384
|
|
|
385
|
+
[[package]]
|
|
386
|
+
name = "types-pyyaml"
|
|
387
|
+
version = "6.0.12.20260906"
|
|
388
|
+
source = { registry = "https://pypi.org/simple" }
|
|
389
|
+
sdist = { url = "https://files.pythonhosted.org/packages/90/6e/abec85b9013db5b934b0280a6dd104904d84f7bcbaab2e2f3def87ac7463/types_pyyaml-6.0.12.20260906.tar.gz", hash = "sha256:f59c1cc05010b833d2d72287bbaa72610106b28d42d89a907313117faba85212", size = 18649, upload-time = "2026-09-06T06:35:35.362Z" }
|
|
390
|
+
wheels = [
|
|
391
|
+
{ url = "https://files.pythonhosted.org/packages/15/c0/fc0644b7ddcfb969e95845837143cb5173ddd6e06ee4ba5fc493cd9329b7/types_pyyaml-6.0.12.20260906-py3-none-any.whl", hash = "sha256:bca893ff0d51df5c9053137d5d0e6ccd36e939a196356f1d5c16372422f5137b", size = 21282, upload-time = "2026-09-06T06:35:34.372Z" },
|
|
392
|
+
]
|
|
393
|
+
|
|
394
|
+
[[package]]
|
|
395
|
+
name = "types-strictyaml"
|
|
396
|
+
version = "1.7.3.3"
|
|
397
|
+
source = { registry = "https://pypi.org/simple" }
|
|
398
|
+
dependencies = [
|
|
399
|
+
{ name = "strictyaml" },
|
|
400
|
+
]
|
|
401
|
+
sdist = { url = "https://files.pythonhosted.org/packages/2b/81/50a74541bb5526033909fda5f343b3fc57c88b7a07fd7ff1eaa9eda98c65/types_strictyaml-1.7.3.3.tar.gz", hash = "sha256:61aeb8a13f44fd15cc348e34fac002f5a9b6189f258d2c7acfe79abccc22d57d", size = 46683, upload-time = "2026-09-12T14:57:49.605Z" }
|
|
402
|
+
wheels = [
|
|
403
|
+
{ url = "https://files.pythonhosted.org/packages/7b/ef/c3b4a95c43b615f8f61a1f6c3b4ca23a1cade47e15c209b2e9a3c9a863db/types_strictyaml-1.7.3.3-py3-none-any.whl", hash = "sha256:21f5eefb69dd274a72bc1946c51ceeb2f73031dcc2495072dc88f645a0d9888b", size = 67467, upload-time = "2026-09-12T14:57:48.123Z" },
|
|
404
|
+
]
|
|
405
|
+
|
|
306
406
|
[[package]]
|
|
307
407
|
name = "typing-extensions"
|
|
308
408
|
version = "4.16.0"
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from dataclasses import dataclass
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
|
|
6
|
-
from bashrun.bash import bash_output
|
|
7
|
-
from pydantic import BaseModel, ConfigDict
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class ProjectsConfig(BaseModel):
|
|
11
|
-
model_config = ConfigDict(extra="forbid")
|
|
12
|
-
|
|
13
|
-
projects: dict[str, list[str]]
|
|
14
|
-
root_name: str
|
|
15
|
-
generated_root: Path
|
|
16
|
-
spec_command: str
|
|
17
|
-
spec_env: dict[str, str] | None = None
|
|
18
|
-
npm_scope: str | None = None
|
|
19
|
-
license_spdx: str | None = None
|
|
20
|
-
repository_url: str | None = None
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@dataclass(frozen=True)
|
|
24
|
-
class ClientNaming:
|
|
25
|
-
base: str
|
|
26
|
-
dashed: str
|
|
27
|
-
underscored: str
|
|
28
|
-
camel: str
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class SpecProducer:
|
|
32
|
-
def __init__(self, command: str, env: dict[str, str] | None = None) -> None:
|
|
33
|
-
self.command = command
|
|
34
|
-
self.env = env
|
|
35
|
-
|
|
36
|
-
def __call__(self, project: Path) -> str:
|
|
37
|
-
return bash_output(self.command, cwd=project, env=self.env)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/client.py
RENAMED
|
File without changes
|
|
File without changes
|
{openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openapi_client_codegen-0.1.11 → openapi_client_codegen-0.1.12}/src/openapi_client_codegen/unity.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|