msra-codegen 0.1.0__py3-none-any.whl
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.
- msra_codegen/README.md +23 -0
- msra_codegen/__init__.py +6 -0
- msra_codegen/__main__.py +5 -0
- msra_codegen/bridge.py +29 -0
- msra_codegen/cli.py +105 -0
- msra_codegen/codegen_context.py +1690 -0
- msra_codegen/config.toml +164 -0
- msra_codegen/core_naming.py +155 -0
- msra_codegen/docs_generator.py +346 -0
- msra_codegen/file_utils.py +8 -0
- msra_codegen/funcresult.py +156 -0
- msra_codegen/generator.py +6 -0
- msra_codegen/generator_config.py +35 -0
- msra_codegen/github_workflows.py +129 -0
- msra_codegen/gitignore.py +31 -0
- msra_codegen/issue_templates.py +100 -0
- msra_codegen/logo_assets.py +99 -0
- msra_codegen/msra_serializer.py +205 -0
- msra_codegen/node_export.js +296 -0
- msra_codegen/package_metadata.py +306 -0
- msra_codegen/package_writer.py +175 -0
- msra_codegen/project_model.py +490 -0
- msra_codegen/python_formatting.py +88 -0
- msra_codegen/python_render.py +242 -0
- msra_codegen/readme_pipeline.py +519 -0
- msra_codegen/requirements.txt +5 -0
- msra_codegen/template_engine.py +26 -0
- msra_codegen/templates/Makefile.tpl +44 -0
- msra_codegen/templates/README.md.tpl +55 -0
- msra_codegen/templates/abstraction/__init__.py.tpl +188 -0
- msra_codegen/templates/abstraction/regexes.py.tpl +25 -0
- msra_codegen/templates/docs/requirements.txt.tpl +3 -0
- msra_codegen/templates/docs/source/Makefile.tpl +20 -0
- msra_codegen/templates/docs/source/api.rst.tpl +9 -0
- msra_codegen/templates/docs/source/conf.py.tpl +88 -0
- msra_codegen/templates/docs/source/index.rst.tpl +14 -0
- msra_codegen/templates/docs/source/module.rst.tpl +34 -0
- msra_codegen/templates/docs/source/quick_start.rst.tpl +19 -0
- msra_codegen/templates/endpoints_init.py.tpl +15 -0
- msra_codegen/templates/example.py.tpl +1 -0
- msra_codegen/templates/function.py.tpl +364 -0
- msra_codegen/templates/github/issue_templates/bug_report.yml.tpl +55 -0
- msra_codegen/templates/github/issue_templates/config.yml.tpl +8 -0
- msra_codegen/templates/github/issue_templates/documentation_issue.yml.tpl +33 -0
- msra_codegen/templates/github/issue_templates/feature_request.yml.tpl +36 -0
- msra_codegen/templates/github/workflows/publish.yml.tpl +100 -0
- msra_codegen/templates/github/workflows/source-sync.yml.tpl +177 -0
- msra_codegen/templates/github/workflows/tests.yml.tpl +69 -0
- msra_codegen/templates/gitignore.tpl +3 -0
- msra_codegen/templates/group.py.tpl +56 -0
- msra_codegen/templates/group_init.py.tpl +14 -0
- msra_codegen/templates/init.py.tpl +4 -0
- msra_codegen/templates/licenses/GPL-3.0-or-later.txt.tpl +674 -0
- msra_codegen/templates/licenses/MIT.txt.tpl +21 -0
- msra_codegen/templates/manager.py.tpl +257 -0
- msra_codegen/templates/pyproject.toml.tpl +38 -0
- msra_codegen/templates/tests/api_test.py.tpl +49 -0
- msra_codegen/templates/tests/conftest.py.tpl +21 -0
- msra_codegen/templates/variable.py.tpl +54 -0
- msra_codegen/tests_generator.py +988 -0
- msra_codegen/typespec.py +275 -0
- msra_codegen/validation.py +118 -0
- msra_codegen-0.1.0.dist-info/METADATA +47 -0
- msra_codegen-0.1.0.dist-info/RECORD +68 -0
- msra_codegen-0.1.0.dist-info/WHEEL +5 -0
- msra_codegen-0.1.0.dist-info/entry_points.txt +2 -0
- msra_codegen-0.1.0.dist-info/licenses/LICENSE +674 -0
- msra_codegen-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
name: {{ source_sync.name }}
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: source-sync-{{ source_sync.repository_expr }}-{{ source_sync.target_branch }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
source-sync:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Check out generator repository
|
|
19
|
+
uses: {{ source_sync.checkout_action }}
|
|
20
|
+
with:
|
|
21
|
+
repository: {{ source_sync.logic_repository | tojson }}
|
|
22
|
+
ref: {{ source_sync.logic_ref | tojson }}
|
|
23
|
+
path: logic
|
|
24
|
+
token: {{ source_sync.repo_token_expr }}
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
|
|
27
|
+
- name: Set up Python
|
|
28
|
+
uses: {{ source_sync.setup_python_action }}
|
|
29
|
+
with:
|
|
30
|
+
python-version: {{ source_sync.python_version | tojson }}
|
|
31
|
+
|
|
32
|
+
- name: Install generator dependencies
|
|
33
|
+
working-directory: logic
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade pip
|
|
36
|
+
python -m pip install -r "{{ source_sync.generator_requirements_path }}"
|
|
37
|
+
|
|
38
|
+
- name: Check out source branch
|
|
39
|
+
uses: {{ source_sync.checkout_action }}
|
|
40
|
+
with:
|
|
41
|
+
repository: {{ source_sync.repository_expr }}
|
|
42
|
+
ref: {{ source_sync.source_branch | tojson }}
|
|
43
|
+
path: source
|
|
44
|
+
token: {{ source_sync.repo_token_expr }}
|
|
45
|
+
fetch-depth: 0
|
|
46
|
+
|
|
47
|
+
- name: Check out target branch
|
|
48
|
+
uses: {{ source_sync.checkout_action }}
|
|
49
|
+
with:
|
|
50
|
+
repository: {{ source_sync.repository_expr }}
|
|
51
|
+
ref: {{ source_sync.target_branch | tojson }}
|
|
52
|
+
path: target
|
|
53
|
+
token: {{ source_sync.repo_token_expr }}
|
|
54
|
+
fetch-depth: 0
|
|
55
|
+
|
|
56
|
+
- name: Generate artifact into a staging tree
|
|
57
|
+
working-directory: logic
|
|
58
|
+
run: |
|
|
59
|
+
source_msra_path={{ source_sync.source_msra_path | tojson }}
|
|
60
|
+
python -m msra_codegen generate "../source/$source_msra_path" -o ../generated
|
|
61
|
+
|
|
62
|
+
- name: Replace target tree contents
|
|
63
|
+
run: |
|
|
64
|
+
python - <<'PY'
|
|
65
|
+
from fnmatch import fnmatch
|
|
66
|
+
from pathlib import Path
|
|
67
|
+
import shutil
|
|
68
|
+
|
|
69
|
+
target = Path("target")
|
|
70
|
+
generated = Path("generated")
|
|
71
|
+
preserved_root = Path("preserved")
|
|
72
|
+
preserve_paths = {{ source_sync.preserved_target_paths | tojson }}
|
|
73
|
+
ignored_patterns = {{ source_sync.ignored_generated_patterns | tojson }}
|
|
74
|
+
|
|
75
|
+
def is_ignored(relative_path: Path) -> bool:
|
|
76
|
+
relative_text = relative_path.as_posix()
|
|
77
|
+
return any(fnmatch(relative_text, pattern) for pattern in ignored_patterns)
|
|
78
|
+
|
|
79
|
+
def copy_tree(source_root: Path, destination_root: Path) -> None:
|
|
80
|
+
for item in source_root.iterdir():
|
|
81
|
+
relative_path = item.relative_to(source_root)
|
|
82
|
+
if is_ignored(relative_path):
|
|
83
|
+
continue
|
|
84
|
+
destination_path = destination_root / relative_path
|
|
85
|
+
if item.is_dir():
|
|
86
|
+
destination_path.mkdir(parents=True, exist_ok=True)
|
|
87
|
+
copy_tree(item, destination_path)
|
|
88
|
+
else:
|
|
89
|
+
destination_path.parent.mkdir(parents=True, exist_ok=True)
|
|
90
|
+
shutil.copy2(item, destination_path)
|
|
91
|
+
|
|
92
|
+
for relative_path in preserve_paths:
|
|
93
|
+
source_path = target / relative_path
|
|
94
|
+
if not source_path.exists():
|
|
95
|
+
raise RuntimeError(f'Preserved target path "{relative_path}" does not exist.')
|
|
96
|
+
destination_path = preserved_root / relative_path
|
|
97
|
+
destination_path.parent.mkdir(parents=True, exist_ok=True)
|
|
98
|
+
if source_path.is_dir():
|
|
99
|
+
shutil.copytree(source_path, destination_path)
|
|
100
|
+
else:
|
|
101
|
+
shutil.copy2(source_path, destination_path)
|
|
102
|
+
|
|
103
|
+
for child in list(target.iterdir()):
|
|
104
|
+
if child.name == ".git":
|
|
105
|
+
continue
|
|
106
|
+
if child.is_dir():
|
|
107
|
+
shutil.rmtree(child)
|
|
108
|
+
else:
|
|
109
|
+
child.unlink()
|
|
110
|
+
|
|
111
|
+
copy_tree(generated, target)
|
|
112
|
+
PY
|
|
113
|
+
|
|
114
|
+
- name: Install target project dependencies
|
|
115
|
+
working-directory: target
|
|
116
|
+
run: |
|
|
117
|
+
python -m pip install --upgrade pip
|
|
118
|
+
python -m pip install -r requirements-dev.txt
|
|
119
|
+
|
|
120
|
+
- name: Validate generated project
|
|
121
|
+
working-directory: logic
|
|
122
|
+
run: |
|
|
123
|
+
python -m msra_codegen validate ../target
|
|
124
|
+
|
|
125
|
+
- name: Restore preserved artifacts and remove generated noise
|
|
126
|
+
run: |
|
|
127
|
+
python - <<'PY'
|
|
128
|
+
from fnmatch import fnmatch
|
|
129
|
+
from pathlib import Path
|
|
130
|
+
import shutil
|
|
131
|
+
|
|
132
|
+
target = Path("target")
|
|
133
|
+
preserved_root = Path("preserved")
|
|
134
|
+
preserve_paths = {{ source_sync.preserved_target_paths | tojson }}
|
|
135
|
+
ignored_patterns = {{ source_sync.ignored_generated_patterns | tojson }}
|
|
136
|
+
|
|
137
|
+
def is_ignored(relative_path: Path) -> bool:
|
|
138
|
+
relative_text = relative_path.as_posix()
|
|
139
|
+
return any(fnmatch(relative_text, pattern) for pattern in ignored_patterns)
|
|
140
|
+
|
|
141
|
+
def remove_ignored(root: Path) -> None:
|
|
142
|
+
ignored_paths = sorted(
|
|
143
|
+
[path for path in root.rglob("*") if is_ignored(path.relative_to(root))],
|
|
144
|
+
key=lambda path: len(path.parts),
|
|
145
|
+
reverse=True,
|
|
146
|
+
)
|
|
147
|
+
for path in ignored_paths:
|
|
148
|
+
if path.is_dir():
|
|
149
|
+
shutil.rmtree(path)
|
|
150
|
+
else:
|
|
151
|
+
path.unlink()
|
|
152
|
+
|
|
153
|
+
for relative_path in preserve_paths:
|
|
154
|
+
source_path = preserved_root / relative_path
|
|
155
|
+
destination_path = target / relative_path
|
|
156
|
+
if source_path.is_dir():
|
|
157
|
+
shutil.copytree(source_path, destination_path, dirs_exist_ok=True)
|
|
158
|
+
else:
|
|
159
|
+
destination_path.parent.mkdir(parents=True, exist_ok=True)
|
|
160
|
+
shutil.copy2(source_path, destination_path)
|
|
161
|
+
|
|
162
|
+
remove_ignored(target)
|
|
163
|
+
shutil.rmtree(preserved_root, ignore_errors=True)
|
|
164
|
+
PY
|
|
165
|
+
|
|
166
|
+
- name: Commit and push
|
|
167
|
+
working-directory: target
|
|
168
|
+
run: |
|
|
169
|
+
git config user.name "{{ source_sync.commit_user_name }}"
|
|
170
|
+
git config user.email "{{ source_sync.commit_user_email }}"
|
|
171
|
+
git add -A
|
|
172
|
+
if git diff --cached --quiet; then
|
|
173
|
+
echo "No generated changes to commit."
|
|
174
|
+
exit 0
|
|
175
|
+
fi
|
|
176
|
+
git commit -m "Regenerate artifact from source"
|
|
177
|
+
git push origin HEAD:{{ source_sync.target_branch }}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: {{ tests.name }}
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: "{{ tests.schedule_cron }}" # daily at 03:17 UTC
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
workflow_call:
|
|
9
|
+
inputs:
|
|
10
|
+
python-version:
|
|
11
|
+
required: false
|
|
12
|
+
type: string
|
|
13
|
+
default: "{{ tests.python_version }}"
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write
|
|
17
|
+
issues: write
|
|
18
|
+
pull-requests: write
|
|
19
|
+
|
|
20
|
+
concurrency:
|
|
21
|
+
group: {{ tests.concurrency_group }}
|
|
22
|
+
cancel-in-progress: true
|
|
23
|
+
|
|
24
|
+
jobs:
|
|
25
|
+
tests:
|
|
26
|
+
runs-on: {{ tests.runner | tojson }}
|
|
27
|
+
|
|
28
|
+
steps:
|
|
29
|
+
- name: Check out repository
|
|
30
|
+
uses: {{ tests.checkout_action }}
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
uses: {{ tests.setup_python_action }}
|
|
34
|
+
with:
|
|
35
|
+
python-version: {{ tests.python_version_expr }}
|
|
36
|
+
|
|
37
|
+
- name: Install project (venv)
|
|
38
|
+
run: |
|
|
39
|
+
{% for line in tests.install_commands %}
|
|
40
|
+
{{ line }}
|
|
41
|
+
{% endfor %}
|
|
42
|
+
|
|
43
|
+
- name: Run tests (venv)
|
|
44
|
+
env:
|
|
45
|
+
MSRA_RUN_COMMANDS: |
|
|
46
|
+
{% for line in tests.run_commands %}
|
|
47
|
+
{{ line }}
|
|
48
|
+
{% endfor %}
|
|
49
|
+
run: |
|
|
50
|
+
{% if tests.requires_xvfb %}
|
|
51
|
+
{{ tests.headed_run_command_shell }} "$MSRA_RUN_COMMANDS"
|
|
52
|
+
{% else %}
|
|
53
|
+
{{ tests.run_command_shell }} "$MSRA_RUN_COMMANDS"
|
|
54
|
+
{% endif %}
|
|
55
|
+
|
|
56
|
+
- name: report playwright failure
|
|
57
|
+
if: failure()
|
|
58
|
+
uses: {{ tests.report_playwright_failure_action }}
|
|
59
|
+
with:
|
|
60
|
+
github_token: {{ tests.github_token_expr }}
|
|
61
|
+
log_path: {{ tests.log_path }}
|
|
62
|
+
screenshot_path: {{ tests.screenshot_path }}
|
|
63
|
+
|
|
64
|
+
- name: auto PR schema
|
|
65
|
+
# отмена джобы исключается (поэтому и не always)
|
|
66
|
+
if: success() || failure()
|
|
67
|
+
uses: {{ tests.report_schema_action }}
|
|
68
|
+
with:
|
|
69
|
+
github_token: {{ tests.github_token_expr }}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
{% if has_autotests %}
|
|
6
|
+
from human_requests import autotest
|
|
7
|
+
{% endif %}
|
|
8
|
+
{% if imports.literal %}
|
|
9
|
+
from typing import Literal
|
|
10
|
+
{% endif %}
|
|
11
|
+
{% if imports.overload %}
|
|
12
|
+
from typing import overload
|
|
13
|
+
{% endif %}
|
|
14
|
+
{% if imports.json %}
|
|
15
|
+
import json
|
|
16
|
+
{% endif %}
|
|
17
|
+
{% if imports.path %}
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
{% endif %}
|
|
20
|
+
{% if imports.re %}
|
|
21
|
+
import re
|
|
22
|
+
{% endif %}
|
|
23
|
+
{% if imports.urlencode %}
|
|
24
|
+
from urllib.parse import urlencode
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% if imports.http_method %}
|
|
27
|
+
from human_requests.abstraction import HttpMethod
|
|
28
|
+
{% endif %}
|
|
29
|
+
{% if imports.method_pipeline_error %}
|
|
30
|
+
from human_requests.abstraction import MethodPipelineError
|
|
31
|
+
{% endif %}
|
|
32
|
+
|
|
33
|
+
from {{ root_import_prefix }} import abstraction
|
|
34
|
+
{% for child in child_imports %}
|
|
35
|
+
from .{{ child.package_name }} import {{ child.class_name }}
|
|
36
|
+
{% endfor %}
|
|
37
|
+
|
|
38
|
+
if TYPE_CHECKING:
|
|
39
|
+
from {{ root_import_prefix }}manager import {{ root_client_name }}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class {{ class_name }}:
|
|
43
|
+
{% if description %}
|
|
44
|
+
"""{{ description }}"""
|
|
45
|
+
{% endif %}
|
|
46
|
+
|
|
47
|
+
def __init__(self, parent: {{ root_client_name }}):
|
|
48
|
+
self._parent = parent
|
|
49
|
+
{% for child in children %}
|
|
50
|
+
self.{{ child.field_name }}: {{ child.class_name }} = {{ child.class_name }}(parent)
|
|
51
|
+
{% endfor %}
|
|
52
|
+
|
|
53
|
+
{% for func in functions %}
|
|
54
|
+
{{ func.code }}
|
|
55
|
+
|
|
56
|
+
{% endfor %}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from . import {{ module_stem }} as _{{ module_stem }}
|
|
2
|
+
{% for child in child_imports %}
|
|
3
|
+
from . import {{ child.package_name }} as _{{ child.package_name }}
|
|
4
|
+
{% endfor %}
|
|
5
|
+
|
|
6
|
+
{{ class_name }} = _{{ module_stem }}.{{ class_name }}
|
|
7
|
+
{% for child in child_imports %}
|
|
8
|
+
{{ child.class_name }} = _{{ child.package_name }}.{{ child.class_name }}
|
|
9
|
+
{% endfor %}
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"{{ class_name }}"{% for child in child_imports %},
|
|
13
|
+
"{{ child.class_name }}"{% endfor %}
|
|
14
|
+
]
|