omdev 0.0.0.dev31__py3-none-any.whl → 0.0.0.dev33__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.
Potentially problematic release.
This version of omdev might be problematic. Click here for more details.
- omdev/.manifests.json +122 -1
- omdev/__about__.py +8 -0
- omdev/amalg/__main__.py +7 -0
- omdev/amalg/amalg.py +4 -4
- omdev/cexts/_boilerplate.cc +1 -1
- omdev/cexts/cmake.py +5 -0
- omdev/cexts/magic.py +1 -1
- omdev/classdot.py +6 -0
- omdev/cli/__init__.py +1 -0
- omdev/cli/__main__.py +4 -0
- omdev/cli/main.py +59 -0
- omdev/cli/types.py +7 -0
- omdev/interp/__main__.py +7 -0
- omdev/interp/cli.py +13 -5
- omdev/interp/pyenv.py +54 -12
- omdev/manifests/__init__.py +2 -0
- omdev/{manifests.py → manifests/build.py} +29 -60
- omdev/manifests/load.py +149 -0
- omdev/manifests/types.py +16 -0
- omdev/precheck/precheck.py +6 -0
- omdev/pyproject/__main__.py +7 -0
- omdev/pyproject/cli.py +1 -1
- omdev/pyproject/pkg.py +93 -2
- omdev/pyproject/reqs.py +1 -1
- omdev/scripts/interp.py +65 -17
- omdev/scripts/pyproject.py +157 -18
- omdev/toml/writer.py +8 -1
- omdev/tools/dockertools.py +6 -0
- omdev/tools/gittools.py +6 -0
- omdev/tools/piptools.py +6 -0
- omdev/tools/sqlrepl.py +6 -0
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev33.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev33.dist-info}/RECORD +37 -29
- omdev-0.0.0.dev33.dist-info/entry_points.txt +2 -0
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev33.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev33.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev33.dist-info}/top_level.txt +0 -0
omdev/.manifests.json
CHANGED
|
@@ -1 +1,122 @@
|
|
|
1
|
-
[
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"module": ".amalg.__main__",
|
|
4
|
+
"attr": "_CLI_MODULE",
|
|
5
|
+
"file": "omdev/amalg/__main__.py",
|
|
6
|
+
"line": 4,
|
|
7
|
+
"value": {
|
|
8
|
+
"$.cli.types.CliModule": {
|
|
9
|
+
"cmd_name": "amalg",
|
|
10
|
+
"mod_name": "omdev.amalg.__main__"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"module": ".cexts.cmake",
|
|
16
|
+
"attr": "_CLI_MODULE",
|
|
17
|
+
"file": "omdev/cexts/cmake.py",
|
|
18
|
+
"line": 323,
|
|
19
|
+
"value": {
|
|
20
|
+
"$.cli.types.CliModule": {
|
|
21
|
+
"cmd_name": "cmake",
|
|
22
|
+
"mod_name": "omdev.cexts.cmake"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"module": ".classdot",
|
|
28
|
+
"attr": "_CLI_MODULE",
|
|
29
|
+
"file": "omdev/classdot.py",
|
|
30
|
+
"line": 62,
|
|
31
|
+
"value": {
|
|
32
|
+
"$.cli.types.CliModule": {
|
|
33
|
+
"cmd_name": "classdot",
|
|
34
|
+
"mod_name": "omdev.classdot"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"module": ".interp.__main__",
|
|
40
|
+
"attr": "_CLI_MODULE",
|
|
41
|
+
"file": "omdev/interp/__main__.py",
|
|
42
|
+
"line": 4,
|
|
43
|
+
"value": {
|
|
44
|
+
"$.cli.types.CliModule": {
|
|
45
|
+
"cmd_name": "interp",
|
|
46
|
+
"mod_name": "omdev.interp.__main__"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"module": ".precheck.precheck",
|
|
52
|
+
"attr": "_CLI_MODULE",
|
|
53
|
+
"file": "omdev/precheck/precheck.py",
|
|
54
|
+
"line": 90,
|
|
55
|
+
"value": {
|
|
56
|
+
"$.cli.types.CliModule": {
|
|
57
|
+
"cmd_name": "precheck",
|
|
58
|
+
"mod_name": "omdev.precheck.precheck"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"module": ".pyproject.__main__",
|
|
64
|
+
"attr": "_CLI_MODULE",
|
|
65
|
+
"file": "omdev/pyproject/__main__.py",
|
|
66
|
+
"line": 4,
|
|
67
|
+
"value": {
|
|
68
|
+
"$.cli.types.CliModule": {
|
|
69
|
+
"cmd_name": "pyproject",
|
|
70
|
+
"mod_name": "omdev.pyproject.__main__"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"module": ".tools.dockertools",
|
|
76
|
+
"attr": "_CLI_MODULE",
|
|
77
|
+
"file": "omdev/tools/dockertools.py",
|
|
78
|
+
"line": 183,
|
|
79
|
+
"value": {
|
|
80
|
+
"$.cli.types.CliModule": {
|
|
81
|
+
"cmd_name": "docker",
|
|
82
|
+
"mod_name": "omdev.tools.dockertools"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"module": ".tools.gittools",
|
|
88
|
+
"attr": "_CLI_MODULE",
|
|
89
|
+
"file": "omdev/tools/gittools.py",
|
|
90
|
+
"line": 22,
|
|
91
|
+
"value": {
|
|
92
|
+
"$.cli.types.CliModule": {
|
|
93
|
+
"cmd_name": "git",
|
|
94
|
+
"mod_name": "omdev.tools.gittools"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"module": ".tools.piptools",
|
|
100
|
+
"attr": "_CLI_MODULE",
|
|
101
|
+
"file": "omdev/tools/piptools.py",
|
|
102
|
+
"line": 51,
|
|
103
|
+
"value": {
|
|
104
|
+
"$.cli.types.CliModule": {
|
|
105
|
+
"cmd_name": "pip",
|
|
106
|
+
"mod_name": "omdev.tools.piptools"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"module": ".tools.sqlrepl",
|
|
112
|
+
"attr": "_CLI_MODULE",
|
|
113
|
+
"file": "omdev/tools/sqlrepl.py",
|
|
114
|
+
"line": 193,
|
|
115
|
+
"value": {
|
|
116
|
+
"$.cli.types.CliModule": {
|
|
117
|
+
"cmd_name": "sqlrepl",
|
|
118
|
+
"mod_name": "omdev.tools.sqlrepl"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
]
|
omdev/__about__.py
CHANGED
omdev/amalg/__main__.py
CHANGED
omdev/amalg/amalg.py
CHANGED
|
@@ -4,9 +4,9 @@ Conventions:
|
|
|
4
4
|
- must import 'from' items for local modules
|
|
5
5
|
|
|
6
6
|
TODO:
|
|
7
|
-
-
|
|
7
|
+
- !! strip manifests? or relegate them to a separate tiny module ala __main__.py?
|
|
8
|
+
- # @omlish-no-amalg ? in cli.types? will strip stmt (more than 1 line) following @manifest, so shouldn't import
|
|
8
9
|
- more sanity checks lol
|
|
9
|
-
- flake8 / ruff mgmt
|
|
10
10
|
- typealias - support # noqa, other comments, and lamely support multiline by just stealing lines till it parses
|
|
11
11
|
- remove `if __name__ == '__main__':` blocks - thus, convention: no def _main() for these
|
|
12
12
|
|
|
@@ -339,8 +339,8 @@ RUFF_DISABLES: ta.AbstractSet[str] = {
|
|
|
339
339
|
'UP036', # outdated-version-block
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
-
OUTPUT_COMMENT = '# @
|
|
343
|
-
SCAN_COMMENT = '# @
|
|
342
|
+
OUTPUT_COMMENT = '# @omlish-amalg-output '
|
|
343
|
+
SCAN_COMMENT = '# @omlish-amalg '
|
|
344
344
|
|
|
345
345
|
|
|
346
346
|
def gen_amalg(
|
omdev/cexts/_boilerplate.cc
CHANGED
omdev/cexts/cmake.py
CHANGED
|
@@ -38,6 +38,7 @@ from omlish import logs
|
|
|
38
38
|
|
|
39
39
|
from .. import cmake
|
|
40
40
|
from .. import findmagic
|
|
41
|
+
from ..cli import CliModule
|
|
41
42
|
from .magic import CextMagic
|
|
42
43
|
|
|
43
44
|
|
|
@@ -319,6 +320,10 @@ def _gen_cmd(args) -> None:
|
|
|
319
320
|
cpg.run()
|
|
320
321
|
|
|
321
322
|
|
|
323
|
+
# @omlish-manifest
|
|
324
|
+
_CLI_MODULE = CliModule('cmake', __name__)
|
|
325
|
+
|
|
326
|
+
|
|
322
327
|
def _main(argv=None) -> None:
|
|
323
328
|
logs.configure_standard_logging('INFO')
|
|
324
329
|
|
omdev/cexts/magic.py
CHANGED
omdev/classdot.py
CHANGED
|
@@ -7,6 +7,8 @@ import typing as ta
|
|
|
7
7
|
|
|
8
8
|
from omlish.graphs import dot
|
|
9
9
|
|
|
10
|
+
from .cli import CliModule
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
def gen_class_dot(roots: ta.Iterable[type]) -> dot.Graph:
|
|
12
14
|
roots = set(roots)
|
|
@@ -57,5 +59,9 @@ def _main() -> None:
|
|
|
57
59
|
dot.open_dot(dot.render(scd), sleep_s=1.)
|
|
58
60
|
|
|
59
61
|
|
|
62
|
+
# @omlish-manifest
|
|
63
|
+
_CLI_MODULE = CliModule('classdot', __name__)
|
|
64
|
+
|
|
65
|
+
|
|
60
66
|
if __name__ == '__main__':
|
|
61
67
|
_main()
|
omdev/cli/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .types import CliModule # noqa
|
omdev/cli/__main__.py
ADDED
omdev/cli/main.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- allow manually specifying manifest packages
|
|
4
|
+
- omlish.bootstrap always
|
|
5
|
+
- https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#creating-executable-scripts
|
|
6
|
+
- https://packaging.python.org/en/latest/specifications/entry-points/#entry-points
|
|
7
|
+
"""
|
|
8
|
+
import argparse
|
|
9
|
+
import functools
|
|
10
|
+
import os
|
|
11
|
+
import runpy
|
|
12
|
+
import sys
|
|
13
|
+
|
|
14
|
+
from omlish import check
|
|
15
|
+
|
|
16
|
+
from ..manifests.load import ManifestLoader
|
|
17
|
+
from .types import CliModule
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _main() -> None:
|
|
21
|
+
cms: list[CliModule] = []
|
|
22
|
+
|
|
23
|
+
ldr = ManifestLoader.from_entry_point(globals())
|
|
24
|
+
|
|
25
|
+
pkgs = ldr.discover()
|
|
26
|
+
if not pkgs:
|
|
27
|
+
pkgs = []
|
|
28
|
+
for n in os.listdir(os.getcwd()):
|
|
29
|
+
if os.path.isdir(n) and os.path.exists(os.path.join(n, '__init__.py')):
|
|
30
|
+
pkgs.append(n)
|
|
31
|
+
|
|
32
|
+
for m in ldr.load(*pkgs, only=[CliModule]):
|
|
33
|
+
cms.append(check.isinstance(m.value, CliModule))
|
|
34
|
+
|
|
35
|
+
parser = argparse.ArgumentParser()
|
|
36
|
+
subparsers = parser.add_subparsers()
|
|
37
|
+
|
|
38
|
+
def run(cm: CliModule) -> None:
|
|
39
|
+
sys.argv = [cm.cmd_name, *(args.args or ())]
|
|
40
|
+
runpy._run_module_as_main(cm.mod_name) # type: ignore # noqa
|
|
41
|
+
|
|
42
|
+
seen: set[str] = set()
|
|
43
|
+
for cm in cms:
|
|
44
|
+
if cm.cmd_name in seen:
|
|
45
|
+
raise NameError(cm)
|
|
46
|
+
|
|
47
|
+
cmd_parser = subparsers.add_parser(cm.cmd_name)
|
|
48
|
+
cmd_parser.add_argument('args', nargs=argparse.REMAINDER)
|
|
49
|
+
cmd_parser.set_defaults(func=functools.partial(run, cm))
|
|
50
|
+
|
|
51
|
+
args = parser.parse_args()
|
|
52
|
+
if not getattr(args, 'func', None):
|
|
53
|
+
parser.print_help()
|
|
54
|
+
else:
|
|
55
|
+
args.func()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if __name__ == '__main__':
|
|
59
|
+
_main()
|
omdev/cli/types.py
ADDED
omdev/interp/__main__.py
CHANGED
omdev/interp/cli.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# @
|
|
2
|
+
# @omlish-amalg ../scripts/interp.py
|
|
3
3
|
# ruff: noqa: UP007
|
|
4
4
|
"""
|
|
5
5
|
TODO:
|
|
@@ -15,6 +15,8 @@ from omlish.lite.logs import configure_standard_logging
|
|
|
15
15
|
from omlish.lite.runtime import check_runtime_version
|
|
16
16
|
|
|
17
17
|
from .resolvers import DEFAULT_INTERP_RESOLVER
|
|
18
|
+
from .resolvers import INTERP_PROVIDER_TYPES_BY_NAME
|
|
19
|
+
from .resolvers import InterpResolver
|
|
18
20
|
from .types import InterpSpecifier
|
|
19
21
|
|
|
20
22
|
|
|
@@ -25,9 +27,13 @@ def _list_cmd(args) -> None:
|
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
def _resolve_cmd(args) -> None:
|
|
28
|
-
|
|
30
|
+
if args.provider:
|
|
31
|
+
p = INTERP_PROVIDER_TYPES_BY_NAME[args.provider]()
|
|
32
|
+
r = InterpResolver([(p.name, p)])
|
|
33
|
+
else:
|
|
34
|
+
r = DEFAULT_INTERP_RESOLVER
|
|
29
35
|
s = InterpSpecifier.parse(args.version)
|
|
30
|
-
print(check_not_none(r.resolve(s)).exe)
|
|
36
|
+
print(check_not_none(r.resolve(s, install=bool(args.install))).exe)
|
|
31
37
|
|
|
32
38
|
|
|
33
39
|
def _build_parser() -> argparse.ArgumentParser:
|
|
@@ -37,12 +43,14 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
37
43
|
|
|
38
44
|
parser_list = subparsers.add_parser('list')
|
|
39
45
|
parser_list.add_argument('version')
|
|
40
|
-
parser_list.add_argument('--debug', action='store_true')
|
|
46
|
+
parser_list.add_argument('-d', '--debug', action='store_true')
|
|
41
47
|
parser_list.set_defaults(func=_list_cmd)
|
|
42
48
|
|
|
43
49
|
parser_resolve = subparsers.add_parser('resolve')
|
|
44
50
|
parser_resolve.add_argument('version')
|
|
45
|
-
parser_resolve.add_argument('
|
|
51
|
+
parser_resolve.add_argument('-p', '--provider')
|
|
52
|
+
parser_resolve.add_argument('-d', '--debug', action='store_true')
|
|
53
|
+
parser_resolve.add_argument('-i', '--install', action='store_true')
|
|
46
54
|
parser_resolve.set_defaults(func=_resolve_cmd)
|
|
47
55
|
|
|
48
56
|
return parser
|
omdev/interp/pyenv.py
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
3
|
- custom tags
|
|
4
|
+
- 'aliases'
|
|
5
|
+
- https://github.com/pyenv/pyenv/pull/2966
|
|
6
|
+
- https://github.com/pyenv/pyenv/issues/218 (lol)
|
|
7
|
+
- probably need custom (temp?) definition file
|
|
8
|
+
- *or* python-build directly just into the versions dir?
|
|
4
9
|
- optionally install / upgrade pyenv itself
|
|
5
10
|
- new vers dont need these custom mac opts, only run on old vers
|
|
6
|
-
|
|
7
|
-
TODO opts:
|
|
8
|
-
- --enable-loadable-sqlite-extensions LDFLAGS="-L/opt/homebrew/opt/sqlite/lib" CPPFLAGS="-I/opt/homebrew/opt/sqlite/include"
|
|
9
|
-
- --enable-shared
|
|
10
|
-
- --enable-optimizations
|
|
11
|
-
- --enable-profiling ?
|
|
12
|
-
- --enable-ipv6 ?
|
|
13
|
-
""" # noqa
|
|
11
|
+
"""
|
|
14
12
|
# ruff: noqa: UP006 UP007
|
|
15
13
|
import abc
|
|
16
14
|
import dataclasses as dc
|
|
@@ -129,8 +127,33 @@ class PyenvInstallOpts:
|
|
|
129
127
|
)
|
|
130
128
|
|
|
131
129
|
|
|
132
|
-
|
|
130
|
+
# TODO: https://github.com/pyenv/pyenv/blob/master/plugins/python-build/README.md#building-for-maximum-performance
|
|
131
|
+
DEFAULT_PYENV_INSTALL_OPTS = PyenvInstallOpts(
|
|
132
|
+
opts=[
|
|
133
|
+
'-s',
|
|
134
|
+
'-v',
|
|
135
|
+
'-k',
|
|
136
|
+
],
|
|
137
|
+
conf_opts=[
|
|
138
|
+
'--enable-loadable-sqlite-extensions',
|
|
139
|
+
|
|
140
|
+
# '--enable-shared',
|
|
141
|
+
|
|
142
|
+
'--enable-optimizations',
|
|
143
|
+
'--with-lto',
|
|
144
|
+
|
|
145
|
+
# '--enable-profiling', # ?
|
|
146
|
+
|
|
147
|
+
# '--enable-ipv6', # ?
|
|
148
|
+
],
|
|
149
|
+
cflags=[
|
|
150
|
+
# '-march=native',
|
|
151
|
+
# '-mtune=native',
|
|
152
|
+
],
|
|
153
|
+
)
|
|
154
|
+
|
|
133
155
|
DEBUG_PYENV_INSTALL_OPTS = PyenvInstallOpts(opts=['-g'])
|
|
156
|
+
|
|
134
157
|
THREADED_PYENV_INSTALL_OPTS = PyenvInstallOpts(conf_opts=['--disable-gil'])
|
|
135
158
|
|
|
136
159
|
|
|
@@ -229,6 +252,7 @@ class PyenvVersionInstaller:
|
|
|
229
252
|
opts: ta.Optional[PyenvInstallOpts] = None,
|
|
230
253
|
interp_opts: InterpOpts = InterpOpts(),
|
|
231
254
|
*,
|
|
255
|
+
install_name: ta.Optional[str] = None,
|
|
232
256
|
no_default_opts: bool = False,
|
|
233
257
|
pyenv: Pyenv = Pyenv(),
|
|
234
258
|
) -> None:
|
|
@@ -249,6 +273,7 @@ class PyenvVersionInstaller:
|
|
|
249
273
|
self._version = version
|
|
250
274
|
self._opts = opts
|
|
251
275
|
self._interp_opts = interp_opts
|
|
276
|
+
self._given_install_name = install_name
|
|
252
277
|
|
|
253
278
|
self._no_default_opts = no_default_opts
|
|
254
279
|
self._pyenv = pyenv
|
|
@@ -263,6 +288,8 @@ class PyenvVersionInstaller:
|
|
|
263
288
|
|
|
264
289
|
@cached_nullary
|
|
265
290
|
def install_name(self) -> str:
|
|
291
|
+
if self._given_install_name is not None:
|
|
292
|
+
return self._given_install_name
|
|
266
293
|
return self._version + ('-debug' if self._interp_opts.debug else '')
|
|
267
294
|
|
|
268
295
|
@cached_nullary
|
|
@@ -282,11 +309,26 @@ class PyenvVersionInstaller:
|
|
|
282
309
|
v += ' ' + os.environ[k]
|
|
283
310
|
env[k] = v
|
|
284
311
|
|
|
285
|
-
|
|
286
|
-
self._pyenv.exe(),
|
|
287
|
-
'install',
|
|
312
|
+
conf_args = [
|
|
288
313
|
*self._opts.opts,
|
|
289
314
|
self._version,
|
|
315
|
+
]
|
|
316
|
+
|
|
317
|
+
if self._given_install_name is not None:
|
|
318
|
+
full_args = [
|
|
319
|
+
os.path.join(check_not_none(self._pyenv.root()), 'plugins', 'python-build', 'bin', 'python-build'),
|
|
320
|
+
*conf_args,
|
|
321
|
+
self.install_dir(),
|
|
322
|
+
]
|
|
323
|
+
else:
|
|
324
|
+
full_args = [
|
|
325
|
+
self._pyenv.exe(),
|
|
326
|
+
'install',
|
|
327
|
+
*conf_args,
|
|
328
|
+
]
|
|
329
|
+
|
|
330
|
+
subprocess_check_call(
|
|
331
|
+
*full_args,
|
|
290
332
|
env=env,
|
|
291
333
|
)
|
|
292
334
|
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
"""
|
|
2
2
|
TODO:
|
|
3
|
-
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
- separate build from cli
|
|
4
|
+
|
|
5
|
+
- See (entry_points):
|
|
6
|
+
- https://github.com/pytest-dev/pluggy/blob/main/src/pluggy/_manager.py#L405
|
|
7
|
+
- https://docs.pytest.org/en/7.1.x/how-to/writing_plugins.html#setuptools-entry-points
|
|
8
|
+
- https://packaging.python.org/en/latest/specifications/entry-points/
|
|
9
|
+
- https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/
|
|
10
|
+
- [project.entry-points.omlish-manifests] \n omdev = omdev
|
|
6
11
|
"""
|
|
7
12
|
# ruff: noqa: UP006 UP007
|
|
8
|
-
# @omlish-lite
|
|
9
13
|
import argparse
|
|
10
14
|
import collections
|
|
11
15
|
import dataclasses as dc
|
|
12
|
-
import importlib
|
|
13
16
|
import inspect
|
|
14
17
|
import json
|
|
15
18
|
import os.path
|
|
@@ -25,57 +28,10 @@ from omlish.lite.json import json_dumps_pretty
|
|
|
25
28
|
from omlish.lite.logs import configure_standard_logging
|
|
26
29
|
from omlish.lite.logs import log
|
|
27
30
|
|
|
28
|
-
from
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@dc.dataclass(frozen=True)
|
|
35
|
-
class ManifestOrigin:
|
|
36
|
-
module: str
|
|
37
|
-
attr: str
|
|
38
|
-
|
|
39
|
-
file: str
|
|
40
|
-
line: int
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
@dc.dataclass(frozen=True)
|
|
44
|
-
class Manifest(ManifestOrigin):
|
|
45
|
-
value: ta.Any
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def load_manifest_entry(
|
|
49
|
-
entry: ta.Mapping[str, ta.Any],
|
|
50
|
-
*,
|
|
51
|
-
raw_values: bool = False,
|
|
52
|
-
) -> Manifest:
|
|
53
|
-
manifest = Manifest(**entry)
|
|
54
|
-
|
|
55
|
-
[(key, value_dct)] = manifest.value.items()
|
|
56
|
-
if not key.startswith('$'):
|
|
57
|
-
raise Exception(f'Bad key: {key}')
|
|
58
|
-
|
|
59
|
-
if not raw_values:
|
|
60
|
-
parts = key[1:].split('.')
|
|
61
|
-
pos = next(i for i, p in enumerate(parts) if p[0].isupper())
|
|
62
|
-
mod_name = '.'.join(parts[:pos])
|
|
63
|
-
mod = importlib.import_module(mod_name)
|
|
64
|
-
|
|
65
|
-
obj: ta.Any = mod
|
|
66
|
-
for ca in parts[pos:]:
|
|
67
|
-
obj = getattr(obj, ca)
|
|
68
|
-
cls = obj
|
|
69
|
-
if not isinstance(cls, type):
|
|
70
|
-
raise TypeError(cls)
|
|
71
|
-
|
|
72
|
-
if not dc.is_dataclass(cls):
|
|
73
|
-
raise TypeError(cls)
|
|
74
|
-
obj = cls(**value_dct) # noqa
|
|
75
|
-
|
|
76
|
-
manifest = dc.replace(manifest, value=obj)
|
|
77
|
-
|
|
78
|
-
return manifest
|
|
31
|
+
from .. import findmagic
|
|
32
|
+
from .load import ManifestLoader
|
|
33
|
+
from .types import Manifest
|
|
34
|
+
from .types import ManifestOrigin
|
|
79
35
|
|
|
80
36
|
|
|
81
37
|
##
|
|
@@ -218,9 +174,16 @@ def build_module_manifests(
|
|
|
218
174
|
|
|
219
175
|
if not (
|
|
220
176
|
isinstance(value, ta.Mapping) and
|
|
177
|
+
len(value) == 1 and
|
|
221
178
|
all(isinstance(k, str) and k.startswith('$') and len(k) > 1 for k in value)
|
|
222
179
|
):
|
|
223
|
-
raise TypeError(f'Manifests must be
|
|
180
|
+
raise TypeError(f'Manifests must be mappings of strings starting with $: {value!r}')
|
|
181
|
+
|
|
182
|
+
[(key, value_dct)] = value.items()
|
|
183
|
+
kb, _, kr = key[1:].partition('.') # noqa
|
|
184
|
+
if kb == mod_base: # noqa
|
|
185
|
+
key = f'$.{kr}'
|
|
186
|
+
value = {key: value_dct}
|
|
224
187
|
|
|
225
188
|
out.append(Manifest(
|
|
226
189
|
**dc.asdict(o),
|
|
@@ -242,11 +205,11 @@ def build_package_manifests(
|
|
|
242
205
|
|
|
243
206
|
manifests: ta.List[Manifest] = []
|
|
244
207
|
|
|
245
|
-
for file in findmagic.find_magic(
|
|
208
|
+
for file in sorted(findmagic.find_magic(
|
|
246
209
|
[pkg_dir],
|
|
247
210
|
[MANIFEST_MAGIC],
|
|
248
211
|
['py'],
|
|
249
|
-
):
|
|
212
|
+
)):
|
|
250
213
|
manifests.extend(build_module_manifests(os.path.relpath(file, base), base))
|
|
251
214
|
|
|
252
215
|
if write:
|
|
@@ -275,8 +238,14 @@ def check_package_manifests(
|
|
|
275
238
|
with open(manifests_file) as f:
|
|
276
239
|
manifests_json = json.load(f)
|
|
277
240
|
|
|
241
|
+
ldr = ManifestLoader()
|
|
278
242
|
for entry in manifests_json:
|
|
279
|
-
|
|
243
|
+
manifest = Manifest(**entry)
|
|
244
|
+
[(key, value_dct)] = manifest.value.items()
|
|
245
|
+
if key.startswith('$.'):
|
|
246
|
+
key = f'${name}{key[1:]}'
|
|
247
|
+
cls = ldr.load_cls(key)
|
|
248
|
+
value = cls(**value_dct) # noqa
|
|
280
249
|
|
|
281
250
|
|
|
282
251
|
##
|