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.
Files changed (68) hide show
  1. msra_codegen/README.md +23 -0
  2. msra_codegen/__init__.py +6 -0
  3. msra_codegen/__main__.py +5 -0
  4. msra_codegen/bridge.py +29 -0
  5. msra_codegen/cli.py +105 -0
  6. msra_codegen/codegen_context.py +1690 -0
  7. msra_codegen/config.toml +164 -0
  8. msra_codegen/core_naming.py +155 -0
  9. msra_codegen/docs_generator.py +346 -0
  10. msra_codegen/file_utils.py +8 -0
  11. msra_codegen/funcresult.py +156 -0
  12. msra_codegen/generator.py +6 -0
  13. msra_codegen/generator_config.py +35 -0
  14. msra_codegen/github_workflows.py +129 -0
  15. msra_codegen/gitignore.py +31 -0
  16. msra_codegen/issue_templates.py +100 -0
  17. msra_codegen/logo_assets.py +99 -0
  18. msra_codegen/msra_serializer.py +205 -0
  19. msra_codegen/node_export.js +296 -0
  20. msra_codegen/package_metadata.py +306 -0
  21. msra_codegen/package_writer.py +175 -0
  22. msra_codegen/project_model.py +490 -0
  23. msra_codegen/python_formatting.py +88 -0
  24. msra_codegen/python_render.py +242 -0
  25. msra_codegen/readme_pipeline.py +519 -0
  26. msra_codegen/requirements.txt +5 -0
  27. msra_codegen/template_engine.py +26 -0
  28. msra_codegen/templates/Makefile.tpl +44 -0
  29. msra_codegen/templates/README.md.tpl +55 -0
  30. msra_codegen/templates/abstraction/__init__.py.tpl +188 -0
  31. msra_codegen/templates/abstraction/regexes.py.tpl +25 -0
  32. msra_codegen/templates/docs/requirements.txt.tpl +3 -0
  33. msra_codegen/templates/docs/source/Makefile.tpl +20 -0
  34. msra_codegen/templates/docs/source/api.rst.tpl +9 -0
  35. msra_codegen/templates/docs/source/conf.py.tpl +88 -0
  36. msra_codegen/templates/docs/source/index.rst.tpl +14 -0
  37. msra_codegen/templates/docs/source/module.rst.tpl +34 -0
  38. msra_codegen/templates/docs/source/quick_start.rst.tpl +19 -0
  39. msra_codegen/templates/endpoints_init.py.tpl +15 -0
  40. msra_codegen/templates/example.py.tpl +1 -0
  41. msra_codegen/templates/function.py.tpl +364 -0
  42. msra_codegen/templates/github/issue_templates/bug_report.yml.tpl +55 -0
  43. msra_codegen/templates/github/issue_templates/config.yml.tpl +8 -0
  44. msra_codegen/templates/github/issue_templates/documentation_issue.yml.tpl +33 -0
  45. msra_codegen/templates/github/issue_templates/feature_request.yml.tpl +36 -0
  46. msra_codegen/templates/github/workflows/publish.yml.tpl +100 -0
  47. msra_codegen/templates/github/workflows/source-sync.yml.tpl +177 -0
  48. msra_codegen/templates/github/workflows/tests.yml.tpl +69 -0
  49. msra_codegen/templates/gitignore.tpl +3 -0
  50. msra_codegen/templates/group.py.tpl +56 -0
  51. msra_codegen/templates/group_init.py.tpl +14 -0
  52. msra_codegen/templates/init.py.tpl +4 -0
  53. msra_codegen/templates/licenses/GPL-3.0-or-later.txt.tpl +674 -0
  54. msra_codegen/templates/licenses/MIT.txt.tpl +21 -0
  55. msra_codegen/templates/manager.py.tpl +257 -0
  56. msra_codegen/templates/pyproject.toml.tpl +38 -0
  57. msra_codegen/templates/tests/api_test.py.tpl +49 -0
  58. msra_codegen/templates/tests/conftest.py.tpl +21 -0
  59. msra_codegen/templates/variable.py.tpl +54 -0
  60. msra_codegen/tests_generator.py +988 -0
  61. msra_codegen/typespec.py +275 -0
  62. msra_codegen/validation.py +118 -0
  63. msra_codegen-0.1.0.dist-info/METADATA +47 -0
  64. msra_codegen-0.1.0.dist-info/RECORD +68 -0
  65. msra_codegen-0.1.0.dist-info/WHEEL +5 -0
  66. msra_codegen-0.1.0.dist-info/entry_points.txt +2 -0
  67. msra_codegen-0.1.0.dist-info/licenses/LICENSE +674 -0
  68. 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,3 @@
1
+ {% for pattern in patterns -%}
2
+ {{ pattern }}
3
+ {% endfor %}
@@ -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
+ ]
@@ -0,0 +1,4 @@
1
+ from .manager import {{ client_class_name }}
2
+
3
+ __all__ = ["{{ client_class_name }}"]
4
+ __version__ = "{{ version }}"