omdev 0.0.0.dev99__py3-none-any.whl → 0.0.0.dev100__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 +12 -12
- omdev/amalg/amalg.py +8 -5
- omdev/cexts/cmake.py +4 -4
- omdev/cexts/magic.py +4 -4
- omdev/cexts/scan.py +3 -3
- omdev/magic/__init__.py +28 -0
- omdev/magic/find.py +268 -0
- omdev/magic/magic.py +17 -0
- omdev/magic/prepare.py +27 -0
- omdev/magic/styles.py +33 -0
- omdev/manifests/build.py +6 -6
- omdev/precheck/lite.py +4 -4
- omdev/precheck/scripts.py +5 -6
- omdev/pyproject/pkg.py +4 -4
- omdev/scripts/pyproject.py +319 -81
- {omdev-0.0.0.dev99.dist-info → omdev-0.0.0.dev100.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev99.dist-info → omdev-0.0.0.dev100.dist-info}/RECORD +21 -17
- omdev/findmagic.py +0 -91
- {omdev-0.0.0.dev99.dist-info → omdev-0.0.0.dev100.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev99.dist-info → omdev-0.0.0.dev100.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev99.dist-info → omdev-0.0.0.dev100.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev99.dist-info → omdev-0.0.0.dev100.dist-info}/top_level.txt +0 -0
omdev/.manifests.json
CHANGED
|
@@ -71,18 +71,6 @@
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
-
{
|
|
75
|
-
"module": ".findmagic",
|
|
76
|
-
"attr": "_CLI_MODULE",
|
|
77
|
-
"file": "omdev/findmagic.py",
|
|
78
|
-
"line": 65,
|
|
79
|
-
"value": {
|
|
80
|
-
"$.cli.types.CliModule": {
|
|
81
|
-
"cmd_name": "py/findmagic",
|
|
82
|
-
"mod_name": "omdev.findmagic"
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
74
|
{
|
|
87
75
|
"module": ".imgur",
|
|
88
76
|
"attr": "_FOO_CLI_MODULE",
|
|
@@ -107,6 +95,18 @@
|
|
|
107
95
|
}
|
|
108
96
|
}
|
|
109
97
|
},
|
|
98
|
+
{
|
|
99
|
+
"module": ".magic.find",
|
|
100
|
+
"attr": "_CLI_MODULE",
|
|
101
|
+
"file": "omdev/magic/find.py",
|
|
102
|
+
"line": 230,
|
|
103
|
+
"value": {
|
|
104
|
+
"$.cli.types.CliModule": {
|
|
105
|
+
"cmd_name": "py/findmagic",
|
|
106
|
+
"mod_name": "omdev.magic.find"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
110
|
{
|
|
111
111
|
"module": ".precheck.__main__",
|
|
112
112
|
"attr": "_CLI_MODULE",
|
omdev/amalg/amalg.py
CHANGED
|
@@ -41,7 +41,7 @@ from omlish import lang
|
|
|
41
41
|
from omlish import logs
|
|
42
42
|
from omlish.lite.runtime import REQUIRED_PYTHON_VERSION
|
|
43
43
|
|
|
44
|
-
from .. import
|
|
44
|
+
from .. import magic
|
|
45
45
|
from .. import tokens as tks
|
|
46
46
|
|
|
47
47
|
|
|
@@ -94,11 +94,14 @@ def strip_main_lines(cls: ta.Sequence[Tokens]) -> list[Tokens]:
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
STRIPPED_HEADER_MAGICS = [
|
|
97
|
-
'
|
|
98
|
-
'
|
|
97
|
+
'@omlish-lite',
|
|
98
|
+
'@omlish-script',
|
|
99
99
|
]
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
STRIPPED_HEADER_PAT = magic.compile_magic_style_pat(
|
|
102
|
+
magic.PY_MAGIC_STYLE,
|
|
103
|
+
keys=STRIPPED_HEADER_MAGICS,
|
|
104
|
+
)
|
|
102
105
|
|
|
103
106
|
|
|
104
107
|
def strip_header_lines(hls: ta.Sequence[Tokens]) -> list[Tokens]:
|
|
@@ -107,7 +110,7 @@ def strip_header_lines(hls: ta.Sequence[Tokens]) -> list[Tokens]:
|
|
|
107
110
|
out = []
|
|
108
111
|
for l in hls:
|
|
109
112
|
ls = tks.join_toks(l)
|
|
110
|
-
if not
|
|
113
|
+
if not STRIPPED_HEADER_PAT.fullmatch(ls):
|
|
111
114
|
out.append(l)
|
|
112
115
|
return out
|
|
113
116
|
|
omdev/cexts/cmake.py
CHANGED
|
@@ -37,7 +37,7 @@ from omlish import lang
|
|
|
37
37
|
from omlish import logs
|
|
38
38
|
|
|
39
39
|
from .. import cmake
|
|
40
|
-
from .. import
|
|
40
|
+
from .. import magic
|
|
41
41
|
from ..cli import CliModule
|
|
42
42
|
from .magic import CextMagic
|
|
43
43
|
|
|
@@ -137,10 +137,10 @@ class CmakeProjectGen:
|
|
|
137
137
|
out.append(e)
|
|
138
138
|
elif os.path.isdir(e):
|
|
139
139
|
out.extend(
|
|
140
|
-
|
|
140
|
+
magic.find_magic_files(
|
|
141
|
+
CextMagic.STYLE,
|
|
141
142
|
[e],
|
|
142
|
-
[CextMagic.
|
|
143
|
-
CextMagic.FILE_EXTENSIONS,
|
|
143
|
+
keys=[CextMagic.KEY],
|
|
144
144
|
),
|
|
145
145
|
)
|
|
146
146
|
else:
|
omdev/cexts/magic.py
CHANGED
omdev/cexts/scan.py
CHANGED
|
@@ -15,7 +15,7 @@ def scan_one(
|
|
|
15
15
|
input_path: str,
|
|
16
16
|
**kwargs: ta.Any,
|
|
17
17
|
) -> None:
|
|
18
|
-
if not any(input_path.endswith('.' + fx) for fx in CextMagic.
|
|
18
|
+
if not any(input_path.endswith('.' + fx) for fx in CextMagic.STYLE.exts):
|
|
19
19
|
return
|
|
20
20
|
|
|
21
21
|
with open(input_path, 'rb') as f:
|
|
@@ -26,9 +26,9 @@ def scan_one(
|
|
|
26
26
|
except UnicodeDecodeError:
|
|
27
27
|
return
|
|
28
28
|
|
|
29
|
-
sls = [l for l in src.splitlines() if l.startswith(CextMagic.
|
|
29
|
+
sls = [l for l in src.splitlines() if l.startswith('// ' + CextMagic.KEY)] # FIXME
|
|
30
30
|
for sl in sls:
|
|
31
|
-
sas = sl[len(CextMagic.
|
|
31
|
+
sas = sl[len(CextMagic.KEY) + 3:].split() # noqa
|
|
32
32
|
|
|
33
33
|
log.info('Found ext: %s', input_path)
|
|
34
34
|
|
omdev/magic/__init__.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# @omlish-lite
|
|
2
|
+
|
|
3
|
+
from .find import ( # noqa
|
|
4
|
+
chop_magic_block,
|
|
5
|
+
chop_magic_lines,
|
|
6
|
+
compile_magic_style_pat,
|
|
7
|
+
find_magic,
|
|
8
|
+
find_magic_files,
|
|
9
|
+
find_magic_py_modules,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from .magic import ( # noqa
|
|
13
|
+
Magic,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from .prepare import ( # noqa
|
|
17
|
+
MagicPrepareError,
|
|
18
|
+
json_magic_preparer,
|
|
19
|
+
py_compile_magic_preparer,
|
|
20
|
+
py_eval_magic_preparer,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
from .styles import ( # noqa
|
|
24
|
+
C_MAGIC_STYLE,
|
|
25
|
+
MAGIC_KEY_PREFIX,
|
|
26
|
+
MagicStyle,
|
|
27
|
+
PY_MAGIC_STYLE,
|
|
28
|
+
)
|
omdev/magic/find.py
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
|
2
|
+
import functools
|
|
3
|
+
import os.path
|
|
4
|
+
import re
|
|
5
|
+
import typing as ta
|
|
6
|
+
|
|
7
|
+
from .magic import Magic
|
|
8
|
+
from .prepare import MagicPrepareError
|
|
9
|
+
from .prepare import py_compile_magic_preparer
|
|
10
|
+
from .styles import C_MAGIC_STYLE
|
|
11
|
+
from .styles import PY_MAGIC_STYLE
|
|
12
|
+
from .styles import MagicStyle
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def compile_magic_style_pat(
|
|
19
|
+
style: MagicStyle,
|
|
20
|
+
*,
|
|
21
|
+
keys: ta.Optional[ta.Iterable[str]] = None,
|
|
22
|
+
) -> re.Pattern:
|
|
23
|
+
ps: ta.List[str] = []
|
|
24
|
+
if style.line_prefix is not None:
|
|
25
|
+
ps.append(style.line_prefix)
|
|
26
|
+
if style.block_prefix_suffix is not None:
|
|
27
|
+
ps.append(style.block_prefix_suffix[0])
|
|
28
|
+
if not ps:
|
|
29
|
+
raise Exception('No prefixes')
|
|
30
|
+
|
|
31
|
+
ms: ta.List[str] = []
|
|
32
|
+
if keys is not None:
|
|
33
|
+
if isinstance(keys, str):
|
|
34
|
+
raise TypeError(keys)
|
|
35
|
+
for k in keys:
|
|
36
|
+
if not k.startswith(style.key_prefix):
|
|
37
|
+
raise Exception(f'Key does not start with prefix: {k!r} {style.key_prefix!r}')
|
|
38
|
+
ms.extend([re.escape(p + k) for p in ps])
|
|
39
|
+
else:
|
|
40
|
+
ms = [re.escape(p + style.key_prefix) + r'\S*' for p in ps]
|
|
41
|
+
if not ms:
|
|
42
|
+
raise Exception('No matchers')
|
|
43
|
+
|
|
44
|
+
b = '|'.join(f'({m})' for m in ms)
|
|
45
|
+
s = '^(' + b + r')($|(\s.*))'
|
|
46
|
+
return re.compile(s)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
##
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def chop_magic_lines(
|
|
53
|
+
magic_key: str,
|
|
54
|
+
prefix: str,
|
|
55
|
+
lines: ta.Iterable[str],
|
|
56
|
+
) -> ta.Optional[ta.List[str]]:
|
|
57
|
+
out: ta.List[str] = []
|
|
58
|
+
for i, line in enumerate(lines):
|
|
59
|
+
if not i:
|
|
60
|
+
if not line.startswith(prefix + magic_key):
|
|
61
|
+
return None
|
|
62
|
+
out.append(line[len(prefix) + len(magic_key) + 1:])
|
|
63
|
+
else:
|
|
64
|
+
if not line.startswith(prefix):
|
|
65
|
+
return None
|
|
66
|
+
out.append(line[len(prefix):])
|
|
67
|
+
return out
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def chop_magic_block(
|
|
71
|
+
magic_key: str,
|
|
72
|
+
prefix: str,
|
|
73
|
+
suffix: str,
|
|
74
|
+
lines: ta.Iterable[str],
|
|
75
|
+
) -> ta.Optional[ta.List[str]]:
|
|
76
|
+
out: ta.List[str] = []
|
|
77
|
+
for i, line in enumerate(lines):
|
|
78
|
+
if not i:
|
|
79
|
+
if not line.startswith(prefix + magic_key):
|
|
80
|
+
return None
|
|
81
|
+
s = line[len(prefix) + len(magic_key) + 1:]
|
|
82
|
+
if s.rstrip().endswith(suffix):
|
|
83
|
+
out.append(s.rstrip()[:-len(suffix)])
|
|
84
|
+
break
|
|
85
|
+
out.append(s)
|
|
86
|
+
elif line.rstrip().endswith(suffix):
|
|
87
|
+
out.append(line.rstrip()[:-len(suffix)])
|
|
88
|
+
break
|
|
89
|
+
else:
|
|
90
|
+
out.append(line)
|
|
91
|
+
return out
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
##
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def find_magic(
|
|
98
|
+
style: MagicStyle,
|
|
99
|
+
lines: ta.Sequence[str],
|
|
100
|
+
*,
|
|
101
|
+
file: ta.Optional[str] = None,
|
|
102
|
+
preparer: ta.Callable[[str], ta.Any] = py_compile_magic_preparer,
|
|
103
|
+
) -> ta.List[Magic]:
|
|
104
|
+
out: ta.List[Magic] = []
|
|
105
|
+
|
|
106
|
+
start = 0
|
|
107
|
+
while start < len(lines):
|
|
108
|
+
start_line = lines[start]
|
|
109
|
+
|
|
110
|
+
chopper: ta.Callable[[ta.Iterable[str]], ta.Optional[ta.List[str]]]
|
|
111
|
+
if (
|
|
112
|
+
style.line_prefix is not None and
|
|
113
|
+
start_line.startswith(style.line_prefix + style.key_prefix)
|
|
114
|
+
):
|
|
115
|
+
key = start_line[len(style.line_prefix):].split()[0]
|
|
116
|
+
chopper = functools.partial(
|
|
117
|
+
chop_magic_lines,
|
|
118
|
+
key,
|
|
119
|
+
style.line_prefix,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
elif (
|
|
123
|
+
style.block_prefix_suffix is not None and
|
|
124
|
+
start_line.startswith(style.block_prefix_suffix[0] + style.key_prefix)
|
|
125
|
+
):
|
|
126
|
+
key = start_line[len(style.block_prefix_suffix[0]):].split()[0]
|
|
127
|
+
chopper = functools.partial(
|
|
128
|
+
chop_magic_block,
|
|
129
|
+
key,
|
|
130
|
+
*style.block_prefix_suffix,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
else:
|
|
134
|
+
start += 1
|
|
135
|
+
continue
|
|
136
|
+
|
|
137
|
+
end = start
|
|
138
|
+
magic: ta.Optional[Magic] = None
|
|
139
|
+
while end < len(lines):
|
|
140
|
+
block_lines = chopper(lines[start:end + 1])
|
|
141
|
+
if block_lines is None:
|
|
142
|
+
raise Exception(f'Failed to find magic block terminator : {file=} {start=} {end=}')
|
|
143
|
+
|
|
144
|
+
block_src = ''.join(block_lines)
|
|
145
|
+
if not block_src:
|
|
146
|
+
prepared = None
|
|
147
|
+
else:
|
|
148
|
+
try:
|
|
149
|
+
prepared = preparer(block_src)
|
|
150
|
+
except MagicPrepareError:
|
|
151
|
+
end += 1
|
|
152
|
+
continue
|
|
153
|
+
|
|
154
|
+
magic = Magic(
|
|
155
|
+
key=key,
|
|
156
|
+
file=file,
|
|
157
|
+
start_line=start + 1,
|
|
158
|
+
end_line=end + 1,
|
|
159
|
+
body=block_src,
|
|
160
|
+
prepared=prepared,
|
|
161
|
+
)
|
|
162
|
+
break
|
|
163
|
+
|
|
164
|
+
if magic is None:
|
|
165
|
+
raise Exception(f'Failed to find magic block terminator : {file=} {start=} {end=}')
|
|
166
|
+
|
|
167
|
+
out.append(magic)
|
|
168
|
+
start = end + 1
|
|
169
|
+
|
|
170
|
+
return out
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
##
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def find_magic_files(
|
|
177
|
+
style: MagicStyle,
|
|
178
|
+
roots: ta.Sequence[str],
|
|
179
|
+
*,
|
|
180
|
+
keys: ta.Optional[ta.Iterable[str]] = None,
|
|
181
|
+
) -> ta.Iterator[str]:
|
|
182
|
+
if isinstance(roots, str):
|
|
183
|
+
raise TypeError(roots)
|
|
184
|
+
|
|
185
|
+
pat = compile_magic_style_pat(
|
|
186
|
+
style,
|
|
187
|
+
keys=keys,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
for root in roots:
|
|
191
|
+
for dp, dns, fns in os.walk(root): # noqa
|
|
192
|
+
for fn in fns:
|
|
193
|
+
if not any(fn.endswith(f'.{x}') for x in style.exts):
|
|
194
|
+
continue
|
|
195
|
+
|
|
196
|
+
fp = os.path.join(dp, fn)
|
|
197
|
+
try:
|
|
198
|
+
with open(fp) as f:
|
|
199
|
+
src = f.read()
|
|
200
|
+
except UnicodeDecodeError:
|
|
201
|
+
continue
|
|
202
|
+
|
|
203
|
+
if not any(pat.fullmatch(l) for l in src.splitlines()):
|
|
204
|
+
continue
|
|
205
|
+
|
|
206
|
+
yield fp
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def find_magic_py_modules(
|
|
210
|
+
roots: ta.Sequence[str],
|
|
211
|
+
*,
|
|
212
|
+
style: MagicStyle = PY_MAGIC_STYLE,
|
|
213
|
+
**kwargs: ta.Any,
|
|
214
|
+
) -> ta.Iterator[str]:
|
|
215
|
+
for fp in find_magic_files(style, roots, **kwargs):
|
|
216
|
+
dp = os.path.dirname(fp)
|
|
217
|
+
fn = os.path.basename(fp)
|
|
218
|
+
|
|
219
|
+
if fn == '__init__.py':
|
|
220
|
+
yield dp.replace(os.sep, '.')
|
|
221
|
+
elif fn.endswith('.py'):
|
|
222
|
+
yield fp[:-3].replace(os.sep, '.')
|
|
223
|
+
else:
|
|
224
|
+
yield fp
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
##
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
# @omlish-manifest
|
|
231
|
+
_CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
|
232
|
+
'cmd_name': 'py/findmagic',
|
|
233
|
+
'mod_name': __name__,
|
|
234
|
+
}}
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
if __name__ == '__main__':
|
|
238
|
+
def _main(argv=None) -> None:
|
|
239
|
+
import argparse
|
|
240
|
+
|
|
241
|
+
arg_parser = argparse.ArgumentParser()
|
|
242
|
+
arg_parser.add_argument('--style', '-s', default='py')
|
|
243
|
+
arg_parser.add_argument('--key', '-k', dest='keys', action='append')
|
|
244
|
+
arg_parser.add_argument('--modules', action='store_true')
|
|
245
|
+
arg_parser.add_argument('roots', nargs='*')
|
|
246
|
+
args = arg_parser.parse_args(argv)
|
|
247
|
+
|
|
248
|
+
style = {
|
|
249
|
+
'py': PY_MAGIC_STYLE,
|
|
250
|
+
'c': C_MAGIC_STYLE,
|
|
251
|
+
}[args.style]
|
|
252
|
+
|
|
253
|
+
kw: dict = dict(
|
|
254
|
+
roots=args.roots,
|
|
255
|
+
style=style,
|
|
256
|
+
keys=args.keys,
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
fn: ta.Callable
|
|
260
|
+
if args.modules:
|
|
261
|
+
fn = find_magic_py_modules
|
|
262
|
+
else:
|
|
263
|
+
fn = find_magic_files
|
|
264
|
+
|
|
265
|
+
for out in fn(**kw):
|
|
266
|
+
print(out)
|
|
267
|
+
|
|
268
|
+
_main()
|
omdev/magic/magic.py
ADDED
omdev/magic/prepare.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MagicPrepareError(Exception):
|
|
6
|
+
pass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def py_compile_magic_preparer(src: str) -> ta.Any:
|
|
10
|
+
try:
|
|
11
|
+
prepared = compile(f'({src})', '<magic>', 'eval')
|
|
12
|
+
except SyntaxError:
|
|
13
|
+
raise MagicPrepareError # noqa
|
|
14
|
+
return prepared
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def py_eval_magic_preparer(src: str) -> ta.Any:
|
|
18
|
+
code = py_compile_magic_preparer(src)
|
|
19
|
+
return eval(code) # noqa
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def json_magic_preparer(src: str) -> ta.Any:
|
|
23
|
+
try:
|
|
24
|
+
prepared = json.loads(src)
|
|
25
|
+
except json.JSONDecodeError:
|
|
26
|
+
raise MagicPrepareError # noqa
|
|
27
|
+
return prepared
|
omdev/magic/styles.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
|
2
|
+
import dataclasses as dc
|
|
3
|
+
import typing as ta
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
MAGIC_KEY_PREFIX = '@omlish-'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dc.dataclass(frozen=True)
|
|
10
|
+
class MagicStyle:
|
|
11
|
+
name: str
|
|
12
|
+
|
|
13
|
+
exts: ta.FrozenSet[str] = frozenset()
|
|
14
|
+
|
|
15
|
+
key_prefix: str = MAGIC_KEY_PREFIX
|
|
16
|
+
|
|
17
|
+
line_prefix: ta.Optional[str] = None
|
|
18
|
+
block_prefix_suffix: ta.Optional[ta.Tuple[str, str]] = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
PY_MAGIC_STYLE = MagicStyle(
|
|
22
|
+
name='py',
|
|
23
|
+
exts=frozenset(['py']),
|
|
24
|
+
line_prefix='# ',
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
C_MAGIC_STYLE = MagicStyle(
|
|
29
|
+
name='c',
|
|
30
|
+
exts=frozenset(['c', 'cc', 'cpp']),
|
|
31
|
+
line_prefix='// ',
|
|
32
|
+
block_prefix_suffix=('/* ', '*/'),
|
|
33
|
+
)
|
omdev/manifests/build.py
CHANGED
|
@@ -32,7 +32,7 @@ from omlish.lite.json import json_dumps_pretty
|
|
|
32
32
|
from omlish.lite.logs import configure_standard_logging
|
|
33
33
|
from omlish.lite.logs import log
|
|
34
34
|
|
|
35
|
-
from .. import
|
|
35
|
+
from .. import magic
|
|
36
36
|
from .load import ManifestLoader
|
|
37
37
|
from .types import Manifest
|
|
38
38
|
from .types import ManifestOrigin
|
|
@@ -44,7 +44,7 @@ T = ta.TypeVar('T')
|
|
|
44
44
|
##
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
MANIFEST_MAGIC_KEY = '@omlish-manifest'
|
|
48
48
|
|
|
49
49
|
_MANIFEST_GLOBAL_PAT = re.compile(r'^(?P<name>[A-Za-z_][A-Za-z0-9_]*)\s*=.*')
|
|
50
50
|
|
|
@@ -148,7 +148,7 @@ class ManifestBuilder:
|
|
|
148
148
|
origins: ta.List[ManifestOrigin] = []
|
|
149
149
|
lines = src.splitlines(keepends=True)
|
|
150
150
|
for i, l in enumerate(lines):
|
|
151
|
-
if l.startswith(
|
|
151
|
+
if l.startswith('# ' + MANIFEST_MAGIC_KEY):
|
|
152
152
|
if (m := _MANIFEST_GLOBAL_PAT.match(nl := lines[i + 1])) is None:
|
|
153
153
|
raise Exception(nl)
|
|
154
154
|
|
|
@@ -235,10 +235,10 @@ class ManifestBuilder:
|
|
|
235
235
|
if not os.path.isdir(pkg_dir) or not os.path.isfile(os.path.join(pkg_dir, '__init__.py')):
|
|
236
236
|
raise Exception(pkg_dir)
|
|
237
237
|
|
|
238
|
-
files = sorted(
|
|
238
|
+
files = sorted(magic.find_magic_files(
|
|
239
|
+
magic.PY_MAGIC_STYLE,
|
|
239
240
|
[pkg_dir],
|
|
240
|
-
[
|
|
241
|
-
['py'],
|
|
241
|
+
keys=[MANIFEST_MAGIC_KEY],
|
|
242
242
|
))
|
|
243
243
|
manifests: ta.List[Manifest] = list(itertools.chain.from_iterable(await asyncio.gather(*[
|
|
244
244
|
self._spawn(
|
omdev/precheck/lite.py
CHANGED
|
@@ -8,10 +8,10 @@ import subprocess
|
|
|
8
8
|
import textwrap
|
|
9
9
|
import typing as ta
|
|
10
10
|
|
|
11
|
-
from omdev import findmagic
|
|
12
11
|
from omlish import cached
|
|
13
12
|
from omlish.lite.subprocesses import subprocess_maybe_shell_wrap_exec
|
|
14
13
|
|
|
14
|
+
from .. import magic
|
|
15
15
|
from .base import Precheck
|
|
16
16
|
from .base import PrecheckContext
|
|
17
17
|
|
|
@@ -121,10 +121,10 @@ class LitePython8Precheck(Precheck['LitePython8Precheck.Config']):
|
|
|
121
121
|
return vs
|
|
122
122
|
|
|
123
123
|
async def run(self) -> ta.AsyncGenerator[Precheck.Violation, None]:
|
|
124
|
-
for fp in
|
|
124
|
+
for fp in magic.find_magic_files(
|
|
125
|
+
magic.PY_MAGIC_STYLE,
|
|
125
126
|
self._context.src_roots,
|
|
126
|
-
['
|
|
127
|
-
['py'],
|
|
127
|
+
keys=['@omlish-lite'],
|
|
128
128
|
):
|
|
129
129
|
with open(fp) as f: # noqa # FIXME
|
|
130
130
|
src = f.read()
|
omdev/precheck/scripts.py
CHANGED
|
@@ -3,9 +3,8 @@ import os
|
|
|
3
3
|
import stat
|
|
4
4
|
import typing as ta
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
from
|
|
8
|
-
|
|
6
|
+
from .. import findimports
|
|
7
|
+
from .. import magic
|
|
9
8
|
from .base import Precheck
|
|
10
9
|
from .base import PrecheckContext
|
|
11
10
|
|
|
@@ -22,10 +21,10 @@ class ScriptDepsPrecheck(Precheck['ScriptDepsPrecheck.Config']):
|
|
|
22
21
|
super().__init__(context, config)
|
|
23
22
|
|
|
24
23
|
async def run(self) -> ta.AsyncGenerator[Precheck.Violation, None]:
|
|
25
|
-
for fp in
|
|
24
|
+
for fp in magic.find_magic_files(
|
|
25
|
+
magic.PY_MAGIC_STYLE,
|
|
26
26
|
self._context.src_roots,
|
|
27
|
-
['
|
|
28
|
-
['py'],
|
|
27
|
+
keys=['@omlish-script'],
|
|
29
28
|
):
|
|
30
29
|
if not (stat.S_IXUSR & os.stat(fp).st_mode):
|
|
31
30
|
yield Precheck.Violation(self, f'script {fp} is not executable')
|
omdev/pyproject/pkg.py
CHANGED
|
@@ -40,7 +40,7 @@ from omlish.lite.logs import log
|
|
|
40
40
|
from omlish.lite.subprocesses import subprocess_check_call
|
|
41
41
|
|
|
42
42
|
from ..cexts.magic import CextMagic
|
|
43
|
-
from ..
|
|
43
|
+
from ..magic.find import find_magic_files
|
|
44
44
|
from ..revisions import GitRevisionAdder
|
|
45
45
|
from ..toml.writer import TomlWriter
|
|
46
46
|
|
|
@@ -403,10 +403,10 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
403
403
|
|
|
404
404
|
@cached_nullary
|
|
405
405
|
def find_cext_srcs(self) -> ta.Sequence[str]:
|
|
406
|
-
return sorted(
|
|
406
|
+
return sorted(find_magic_files(
|
|
407
|
+
CextMagic.STYLE,
|
|
407
408
|
[self._dir_name],
|
|
408
|
-
[CextMagic.
|
|
409
|
-
CextMagic.FILE_EXTENSIONS,
|
|
409
|
+
keys=[CextMagic.KEY],
|
|
410
410
|
))
|
|
411
411
|
|
|
412
412
|
#
|
omdev/scripts/pyproject.py
CHANGED
|
@@ -99,84 +99,6 @@ UnparsedVersionVar = ta.TypeVar('UnparsedVersionVar', bound=UnparsedVersion)
|
|
|
99
99
|
CallableVersionOperator = ta.Callable[['Version', str], bool]
|
|
100
100
|
|
|
101
101
|
|
|
102
|
-
########################################
|
|
103
|
-
# ../../cexts/magic.py
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
class CextMagic:
|
|
107
|
-
MAGIC = '@omlish-cext'
|
|
108
|
-
MAGIC_COMMENT = f'// {MAGIC}'
|
|
109
|
-
|
|
110
|
-
FILE_EXTENSIONS = ('c', 'cc', 'cpp')
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
########################################
|
|
114
|
-
# ../../findmagic.py
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def compile_magic_pat(m: str) -> re.Pattern:
|
|
118
|
-
return re.compile('^' + re.escape(m) + r'($|(\s.*))')
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
def find_magic(
|
|
122
|
-
roots: ta.Sequence[str],
|
|
123
|
-
magics: ta.Sequence[str],
|
|
124
|
-
exts: ta.Sequence[str],
|
|
125
|
-
*,
|
|
126
|
-
py: bool = False,
|
|
127
|
-
) -> ta.Iterator[str]:
|
|
128
|
-
if isinstance(roots, str):
|
|
129
|
-
raise TypeError(roots)
|
|
130
|
-
if isinstance(magics, str):
|
|
131
|
-
raise TypeError(magics)
|
|
132
|
-
if isinstance(exts, str):
|
|
133
|
-
raise TypeError(exts)
|
|
134
|
-
|
|
135
|
-
if not magics:
|
|
136
|
-
raise Exception('Must specify magics')
|
|
137
|
-
if not exts:
|
|
138
|
-
raise Exception('Must specify extensions')
|
|
139
|
-
|
|
140
|
-
pats = [compile_magic_pat(m) for m in magics]
|
|
141
|
-
|
|
142
|
-
for root in roots:
|
|
143
|
-
for dp, dns, fns in os.walk(root): # noqa
|
|
144
|
-
for fn in fns:
|
|
145
|
-
if not any(fn.endswith(f'.{x}') for x in exts):
|
|
146
|
-
continue
|
|
147
|
-
|
|
148
|
-
fp = os.path.join(dp, fn)
|
|
149
|
-
try:
|
|
150
|
-
with open(fp) as f:
|
|
151
|
-
src = f.read()
|
|
152
|
-
except UnicodeDecodeError:
|
|
153
|
-
continue
|
|
154
|
-
|
|
155
|
-
if not any(
|
|
156
|
-
any(pat.fullmatch(l) for pat in pats)
|
|
157
|
-
for l in src.splitlines()
|
|
158
|
-
):
|
|
159
|
-
continue
|
|
160
|
-
|
|
161
|
-
if py:
|
|
162
|
-
if fn == '__init__.py':
|
|
163
|
-
out = dp.replace(os.sep, '.')
|
|
164
|
-
elif fn.endswith('.py'):
|
|
165
|
-
out = fp[:-3].replace(os.sep, '.')
|
|
166
|
-
else:
|
|
167
|
-
out = fp
|
|
168
|
-
else:
|
|
169
|
-
out = fp
|
|
170
|
-
yield out
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
# # @omlish-manifest
|
|
174
|
-
# _CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
|
175
|
-
# 'cmd_name': 'py/findmagic',
|
|
176
|
-
# 'mod_name': __name__,
|
|
177
|
-
# }}
|
|
178
|
-
|
|
179
|
-
|
|
180
102
|
########################################
|
|
181
103
|
# ../../git.py
|
|
182
104
|
|
|
@@ -280,6 +202,87 @@ def get_git_revision(
|
|
|
280
202
|
return dirty_rev + ('-untracked' if has_untracked else '')
|
|
281
203
|
|
|
282
204
|
|
|
205
|
+
########################################
|
|
206
|
+
# ../../magic/magic.py
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
@dc.dataclass(frozen=True)
|
|
210
|
+
class Magic:
|
|
211
|
+
key: str
|
|
212
|
+
|
|
213
|
+
file: ta.Optional[str]
|
|
214
|
+
|
|
215
|
+
start_line: int
|
|
216
|
+
end_line: int
|
|
217
|
+
|
|
218
|
+
body: str
|
|
219
|
+
|
|
220
|
+
prepared: ta.Any
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
########################################
|
|
224
|
+
# ../../magic/prepare.py
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class MagicPrepareError(Exception):
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def py_compile_magic_preparer(src: str) -> ta.Any:
|
|
232
|
+
try:
|
|
233
|
+
prepared = compile(f'({src})', '<magic>', 'eval')
|
|
234
|
+
except SyntaxError:
|
|
235
|
+
raise MagicPrepareError # noqa
|
|
236
|
+
return prepared
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def py_eval_magic_preparer(src: str) -> ta.Any:
|
|
240
|
+
code = py_compile_magic_preparer(src)
|
|
241
|
+
return eval(code) # noqa
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def json_magic_preparer(src: str) -> ta.Any:
|
|
245
|
+
try:
|
|
246
|
+
prepared = json.loads(src)
|
|
247
|
+
except json.JSONDecodeError:
|
|
248
|
+
raise MagicPrepareError # noqa
|
|
249
|
+
return prepared
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
########################################
|
|
253
|
+
# ../../magic/styles.py
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
MAGIC_KEY_PREFIX = '@omlish-'
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
@dc.dataclass(frozen=True)
|
|
260
|
+
class MagicStyle:
|
|
261
|
+
name: str
|
|
262
|
+
|
|
263
|
+
exts: ta.FrozenSet[str] = frozenset()
|
|
264
|
+
|
|
265
|
+
key_prefix: str = MAGIC_KEY_PREFIX
|
|
266
|
+
|
|
267
|
+
line_prefix: ta.Optional[str] = None
|
|
268
|
+
block_prefix_suffix: ta.Optional[ta.Tuple[str, str]] = None
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
PY_MAGIC_STYLE = MagicStyle(
|
|
272
|
+
name='py',
|
|
273
|
+
exts=frozenset(['py']),
|
|
274
|
+
line_prefix='# ',
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
C_MAGIC_STYLE = MagicStyle(
|
|
279
|
+
name='c',
|
|
280
|
+
exts=frozenset(['c', 'cc', 'cpp']),
|
|
281
|
+
line_prefix='// ',
|
|
282
|
+
block_prefix_suffix=('/* ', '*/'),
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
|
|
283
286
|
########################################
|
|
284
287
|
# ../../packaging/versions.py
|
|
285
288
|
# Copyright (c) Donald Stufft and individual contributors.
|
|
@@ -2077,6 +2080,241 @@ def format_num_bytes(num_bytes: int) -> str:
|
|
|
2077
2080
|
return f'{num_bytes / 1024 ** (len(FORMAT_NUM_BYTES_SUFFIXES) - 1):.2f}{FORMAT_NUM_BYTES_SUFFIXES[-1]}'
|
|
2078
2081
|
|
|
2079
2082
|
|
|
2083
|
+
########################################
|
|
2084
|
+
# ../../cexts/magic.py
|
|
2085
|
+
|
|
2086
|
+
|
|
2087
|
+
class CextMagic:
|
|
2088
|
+
KEY = '@omlish-cext'
|
|
2089
|
+
STYLE = C_MAGIC_STYLE
|
|
2090
|
+
|
|
2091
|
+
|
|
2092
|
+
########################################
|
|
2093
|
+
# ../../magic/find.py
|
|
2094
|
+
|
|
2095
|
+
|
|
2096
|
+
##
|
|
2097
|
+
|
|
2098
|
+
|
|
2099
|
+
def compile_magic_style_pat(
|
|
2100
|
+
style: MagicStyle,
|
|
2101
|
+
*,
|
|
2102
|
+
keys: ta.Optional[ta.Iterable[str]] = None,
|
|
2103
|
+
) -> re.Pattern:
|
|
2104
|
+
ps: ta.List[str] = []
|
|
2105
|
+
if style.line_prefix is not None:
|
|
2106
|
+
ps.append(style.line_prefix)
|
|
2107
|
+
if style.block_prefix_suffix is not None:
|
|
2108
|
+
ps.append(style.block_prefix_suffix[0])
|
|
2109
|
+
if not ps:
|
|
2110
|
+
raise Exception('No prefixes')
|
|
2111
|
+
|
|
2112
|
+
ms: ta.List[str] = []
|
|
2113
|
+
if keys is not None:
|
|
2114
|
+
if isinstance(keys, str):
|
|
2115
|
+
raise TypeError(keys)
|
|
2116
|
+
for k in keys:
|
|
2117
|
+
if not k.startswith(style.key_prefix):
|
|
2118
|
+
raise Exception(f'Key does not start with prefix: {k!r} {style.key_prefix!r}')
|
|
2119
|
+
ms.extend([re.escape(p + k) for p in ps])
|
|
2120
|
+
else:
|
|
2121
|
+
ms = [re.escape(p + style.key_prefix) + r'\S*' for p in ps]
|
|
2122
|
+
if not ms:
|
|
2123
|
+
raise Exception('No matchers')
|
|
2124
|
+
|
|
2125
|
+
b = '|'.join(f'({m})' for m in ms)
|
|
2126
|
+
s = '^(' + b + r')($|(\s.*))'
|
|
2127
|
+
return re.compile(s)
|
|
2128
|
+
|
|
2129
|
+
|
|
2130
|
+
##
|
|
2131
|
+
|
|
2132
|
+
|
|
2133
|
+
def chop_magic_lines(
|
|
2134
|
+
magic_key: str,
|
|
2135
|
+
prefix: str,
|
|
2136
|
+
lines: ta.Iterable[str],
|
|
2137
|
+
) -> ta.Optional[ta.List[str]]:
|
|
2138
|
+
out: ta.List[str] = []
|
|
2139
|
+
for i, line in enumerate(lines):
|
|
2140
|
+
if not i:
|
|
2141
|
+
if not line.startswith(prefix + magic_key):
|
|
2142
|
+
return None
|
|
2143
|
+
out.append(line[len(prefix) + len(magic_key) + 1:])
|
|
2144
|
+
else:
|
|
2145
|
+
if not line.startswith(prefix):
|
|
2146
|
+
return None
|
|
2147
|
+
out.append(line[len(prefix):])
|
|
2148
|
+
return out
|
|
2149
|
+
|
|
2150
|
+
|
|
2151
|
+
def chop_magic_block(
|
|
2152
|
+
magic_key: str,
|
|
2153
|
+
prefix: str,
|
|
2154
|
+
suffix: str,
|
|
2155
|
+
lines: ta.Iterable[str],
|
|
2156
|
+
) -> ta.Optional[ta.List[str]]:
|
|
2157
|
+
out: ta.List[str] = []
|
|
2158
|
+
for i, line in enumerate(lines):
|
|
2159
|
+
if not i:
|
|
2160
|
+
if not line.startswith(prefix + magic_key):
|
|
2161
|
+
return None
|
|
2162
|
+
s = line[len(prefix) + len(magic_key) + 1:]
|
|
2163
|
+
if s.rstrip().endswith(suffix):
|
|
2164
|
+
out.append(s.rstrip()[:-len(suffix)])
|
|
2165
|
+
break
|
|
2166
|
+
out.append(s)
|
|
2167
|
+
elif line.rstrip().endswith(suffix):
|
|
2168
|
+
out.append(line.rstrip()[:-len(suffix)])
|
|
2169
|
+
break
|
|
2170
|
+
else:
|
|
2171
|
+
out.append(line)
|
|
2172
|
+
return out
|
|
2173
|
+
|
|
2174
|
+
|
|
2175
|
+
##
|
|
2176
|
+
|
|
2177
|
+
|
|
2178
|
+
def find_magic(
|
|
2179
|
+
style: MagicStyle,
|
|
2180
|
+
lines: ta.Sequence[str],
|
|
2181
|
+
*,
|
|
2182
|
+
file: ta.Optional[str] = None,
|
|
2183
|
+
preparer: ta.Callable[[str], ta.Any] = py_compile_magic_preparer,
|
|
2184
|
+
) -> ta.List[Magic]:
|
|
2185
|
+
out: ta.List[Magic] = []
|
|
2186
|
+
|
|
2187
|
+
start = 0
|
|
2188
|
+
while start < len(lines):
|
|
2189
|
+
start_line = lines[start]
|
|
2190
|
+
|
|
2191
|
+
chopper: ta.Callable[[ta.Iterable[str]], ta.Optional[ta.List[str]]]
|
|
2192
|
+
if (
|
|
2193
|
+
style.line_prefix is not None and
|
|
2194
|
+
start_line.startswith(style.line_prefix + style.key_prefix)
|
|
2195
|
+
):
|
|
2196
|
+
key = start_line[len(style.line_prefix):].split()[0]
|
|
2197
|
+
chopper = functools.partial(
|
|
2198
|
+
chop_magic_lines,
|
|
2199
|
+
key,
|
|
2200
|
+
style.line_prefix,
|
|
2201
|
+
)
|
|
2202
|
+
|
|
2203
|
+
elif (
|
|
2204
|
+
style.block_prefix_suffix is not None and
|
|
2205
|
+
start_line.startswith(style.block_prefix_suffix[0] + style.key_prefix)
|
|
2206
|
+
):
|
|
2207
|
+
key = start_line[len(style.block_prefix_suffix[0]):].split()[0]
|
|
2208
|
+
chopper = functools.partial(
|
|
2209
|
+
chop_magic_block,
|
|
2210
|
+
key,
|
|
2211
|
+
*style.block_prefix_suffix,
|
|
2212
|
+
)
|
|
2213
|
+
|
|
2214
|
+
else:
|
|
2215
|
+
start += 1
|
|
2216
|
+
continue
|
|
2217
|
+
|
|
2218
|
+
end = start
|
|
2219
|
+
magic: ta.Optional[Magic] = None
|
|
2220
|
+
while end < len(lines):
|
|
2221
|
+
block_lines = chopper(lines[start:end + 1])
|
|
2222
|
+
if block_lines is None:
|
|
2223
|
+
raise Exception(f'Failed to find magic block terminator : {file=} {start=} {end=}')
|
|
2224
|
+
|
|
2225
|
+
block_src = ''.join(block_lines)
|
|
2226
|
+
if not block_src:
|
|
2227
|
+
prepared = None
|
|
2228
|
+
else:
|
|
2229
|
+
try:
|
|
2230
|
+
prepared = preparer(block_src)
|
|
2231
|
+
except MagicPrepareError:
|
|
2232
|
+
end += 1
|
|
2233
|
+
continue
|
|
2234
|
+
|
|
2235
|
+
magic = Magic(
|
|
2236
|
+
key=key,
|
|
2237
|
+
file=file,
|
|
2238
|
+
start_line=start + 1,
|
|
2239
|
+
end_line=end + 1,
|
|
2240
|
+
body=block_src,
|
|
2241
|
+
prepared=prepared,
|
|
2242
|
+
)
|
|
2243
|
+
break
|
|
2244
|
+
|
|
2245
|
+
if magic is None:
|
|
2246
|
+
raise Exception(f'Failed to find magic block terminator : {file=} {start=} {end=}')
|
|
2247
|
+
|
|
2248
|
+
out.append(magic)
|
|
2249
|
+
start = end + 1
|
|
2250
|
+
|
|
2251
|
+
return out
|
|
2252
|
+
|
|
2253
|
+
|
|
2254
|
+
##
|
|
2255
|
+
|
|
2256
|
+
|
|
2257
|
+
def find_magic_files(
|
|
2258
|
+
style: MagicStyle,
|
|
2259
|
+
roots: ta.Sequence[str],
|
|
2260
|
+
*,
|
|
2261
|
+
keys: ta.Optional[ta.Iterable[str]] = None,
|
|
2262
|
+
) -> ta.Iterator[str]:
|
|
2263
|
+
if isinstance(roots, str):
|
|
2264
|
+
raise TypeError(roots)
|
|
2265
|
+
|
|
2266
|
+
pat = compile_magic_style_pat(
|
|
2267
|
+
style,
|
|
2268
|
+
keys=keys,
|
|
2269
|
+
)
|
|
2270
|
+
|
|
2271
|
+
for root in roots:
|
|
2272
|
+
for dp, dns, fns in os.walk(root): # noqa
|
|
2273
|
+
for fn in fns:
|
|
2274
|
+
if not any(fn.endswith(f'.{x}') for x in style.exts):
|
|
2275
|
+
continue
|
|
2276
|
+
|
|
2277
|
+
fp = os.path.join(dp, fn)
|
|
2278
|
+
try:
|
|
2279
|
+
with open(fp) as f:
|
|
2280
|
+
src = f.read()
|
|
2281
|
+
except UnicodeDecodeError:
|
|
2282
|
+
continue
|
|
2283
|
+
|
|
2284
|
+
if not any(pat.fullmatch(l) for l in src.splitlines()):
|
|
2285
|
+
continue
|
|
2286
|
+
|
|
2287
|
+
yield fp
|
|
2288
|
+
|
|
2289
|
+
|
|
2290
|
+
def find_magic_py_modules(
|
|
2291
|
+
roots: ta.Sequence[str],
|
|
2292
|
+
*,
|
|
2293
|
+
style: MagicStyle = PY_MAGIC_STYLE,
|
|
2294
|
+
**kwargs: ta.Any,
|
|
2295
|
+
) -> ta.Iterator[str]:
|
|
2296
|
+
for fp in find_magic_files(style, roots, **kwargs):
|
|
2297
|
+
dp = os.path.dirname(fp)
|
|
2298
|
+
fn = os.path.basename(fp)
|
|
2299
|
+
|
|
2300
|
+
if fn == '__init__.py':
|
|
2301
|
+
yield dp.replace(os.sep, '.')
|
|
2302
|
+
elif fn.endswith('.py'):
|
|
2303
|
+
yield fp[:-3].replace(os.sep, '.')
|
|
2304
|
+
else:
|
|
2305
|
+
yield fp
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
##
|
|
2309
|
+
|
|
2310
|
+
|
|
2311
|
+
# # @omlish-manifest
|
|
2312
|
+
# _CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
|
2313
|
+
# 'cmd_name': 'py/findmagic',
|
|
2314
|
+
# 'mod_name': __name__,
|
|
2315
|
+
# }}
|
|
2316
|
+
|
|
2317
|
+
|
|
2080
2318
|
########################################
|
|
2081
2319
|
# ../../packaging/specifiers.py
|
|
2082
2320
|
# Copyright (c) Donald Stufft and individual contributors.
|
|
@@ -4162,10 +4400,10 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
4162
4400
|
|
|
4163
4401
|
@cached_nullary
|
|
4164
4402
|
def find_cext_srcs(self) -> ta.Sequence[str]:
|
|
4165
|
-
return sorted(
|
|
4403
|
+
return sorted(find_magic_files(
|
|
4404
|
+
CextMagic.STYLE,
|
|
4166
4405
|
[self._dir_name],
|
|
4167
|
-
[CextMagic.
|
|
4168
|
-
CextMagic.FILE_EXTENSIONS,
|
|
4406
|
+
keys=[CextMagic.KEY],
|
|
4169
4407
|
))
|
|
4170
4408
|
|
|
4171
4409
|
#
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev100
|
|
4
4
|
Summary: omdev
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -12,7 +12,7 @@ Classifier: Operating System :: OS Independent
|
|
|
12
12
|
Classifier: Operating System :: POSIX
|
|
13
13
|
Requires-Python: >=3.12
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: omlish ==0.0.0.
|
|
15
|
+
Requires-Dist: omlish ==0.0.0.dev100
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: black ~=24.10 ; extra == 'all'
|
|
18
18
|
Requires-Dist: pycparser ~=2.22 ; extra == 'all'
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
omdev/.manifests.json,sha256=
|
|
1
|
+
omdev/.manifests.json,sha256=nBS0fk7qpXG5VCITHxGUgJgh8Ghd3LyckoYCcfwb8Qc,6713
|
|
2
2
|
omdev/__about__.py,sha256=ON7EnhbxbwLsMj60wkd9OEYPloXZ7jmnMMzeLg44LXY,1225
|
|
3
3
|
omdev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
omdev/bracepy.py,sha256=I8EdqtDvxzAi3I8TuMEW-RBfwXfqKbwp06CfOdj3L1o,2743
|
|
5
5
|
omdev/classdot.py,sha256=YOvgy6x295I_8NKBbBlRVd3AN7Osirm_Lqt4Wj0j9rY,1631
|
|
6
6
|
omdev/cmake.py,sha256=Diy2ry65806dQP125DAstD3w46z_wszMH7PwC2-6iik,4578
|
|
7
7
|
omdev/findimports.py,sha256=2t8QP852saEEJFeXySEzhi_nxRSxghlkXz2jVdvy08M,2392
|
|
8
|
-
omdev/findmagic.py,sha256=XoKPGjSM0qn1PCiiBPwfTHkpqJYQJmLW8v_4QFJ16Mk,2486
|
|
9
8
|
omdev/git.py,sha256=riM2KqSpQPC3N89uipd7Vm3kVgv4EYYDBU9tV1Z8juM,2208
|
|
10
9
|
omdev/imgur.py,sha256=il12R3t19tALolteYCZywvcdQUEOcgvPyUYgWtKiqt4,2993
|
|
11
10
|
omdev/revisions.py,sha256=U657hf4zeEN32y3g4CzqCAodx_HlfkHj2cIIKALNFDo,5009
|
|
@@ -14,7 +13,7 @@ omdev/tokens.py,sha256=GusxQ1Cd_eiScuR8XTTtc9QFhOgYviYGBZmFnn3Hj7s,756
|
|
|
14
13
|
omdev/wheelfile.py,sha256=yfupGcGkbFlmzGzKU64k_vmOKpaKnUlDWxeGn2KdekU,10005
|
|
15
14
|
omdev/amalg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
15
|
omdev/amalg/__main__.py,sha256=h94M-VqZ3AFBU2a8zOsjeKK7RF6uINhTHl6OiGbVMgw,163
|
|
17
|
-
omdev/amalg/amalg.py,sha256=
|
|
16
|
+
omdev/amalg/amalg.py,sha256=b5lo2EZno62_5HbQV-TSMcsLe5ztm4vz3QrJ1-h_ppo,15140
|
|
18
17
|
omdev/antlr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
18
|
omdev/antlr/consts.py,sha256=8pR6r0m0P3hAiyiAoJZ-nptd2GYbZ98mxwPL9cpaRuw,279
|
|
20
19
|
omdev/antlr/gen.py,sha256=QnPyVWUrJYqHoOc3XsXA8fJdoiwAj6pyUwdG-DVrIeA,2953
|
|
@@ -38,10 +37,10 @@ omdev/cache/data/specs.py,sha256=0a9NPJ76Wz69s94KlNbr1Xma3UQ0z2oCAQN7s6uXe4w,249
|
|
|
38
37
|
omdev/cexts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
38
|
omdev/cexts/_boilerplate.cc,sha256=sbpXEgdFrkdzZXgaNWFFNN27fL9TZu6VrwvMY4-nnFM,1726
|
|
40
39
|
omdev/cexts/build.py,sha256=F3z1-CjDlEM-Gzi5IunKUBO52qdH_pMsFylobTdGJnI,2654
|
|
41
|
-
omdev/cexts/cmake.py,sha256=
|
|
40
|
+
omdev/cexts/cmake.py,sha256=m7Md-mZP252EMa05TZVHRjy8vzhS9tw0nhO1GVQtkQU,9816
|
|
42
41
|
omdev/cexts/importhook.py,sha256=ko0KRxah_ZHhLVcCigYIIDvNHCfHpJ8qhmmuHKbCOt4,3546
|
|
43
|
-
omdev/cexts/magic.py,sha256=
|
|
44
|
-
omdev/cexts/scan.py,sha256=
|
|
42
|
+
omdev/cexts/magic.py,sha256=MPmdhGANFVRaA3351BSTBrXm214dWXro1RMRHaJ2_O0,126
|
|
43
|
+
omdev/cexts/scan.py,sha256=fTDy4DKgGQHdyf2Pp80Z_Ra5o984jFF9LeKfJm39IyM,1665
|
|
45
44
|
omdev/cexts/_distutils/LICENSE,sha256=22p14FIRp3F4Cb7Mj_GK33PKr25issFGHC2JN6dg9vc,1023
|
|
46
45
|
omdev/cexts/_distutils/__init__.py,sha256=c1zImtnPh3uY8BUTV4RLKtGKqTPx3c_pBbhA6tPtNsE,297
|
|
47
46
|
omdev/cexts/_distutils/build_ext.py,sha256=STHl9Rq2KeWJ3dQ8j8LwIQ-vFc4-3XsYWQ8Qc5_VByU,13833
|
|
@@ -79,8 +78,13 @@ omdev/interp/resolvers.py,sha256=tpzlmqGp1C4QKdA6TfcPmtmaygu7mb6WK2RPSbyNQ6s,302
|
|
|
79
78
|
omdev/interp/standalone.py,sha256=XcltiL7ypcfV89C82_3knQ3Kx7aW4wnnxf2056ZXC3A,7731
|
|
80
79
|
omdev/interp/system.py,sha256=bI-JhX4GVJqW7wMxnIa-DGJWnCLmFcIsnl9pc1RGY2g,3513
|
|
81
80
|
omdev/interp/types.py,sha256=EMN3StEMkFoQAMUIZd7JYL4uUWqzFGY-2hTL8EBznYM,2437
|
|
81
|
+
omdev/magic/__init__.py,sha256=CBzRB71RLyylkrj8dph6JUEddA8KSMJvDgriHqFfJGU,478
|
|
82
|
+
omdev/magic/find.py,sha256=tTmpWXAleaXG3_kNOsRF7s8D0CpYMXbdz6-HbCNBW90,7070
|
|
83
|
+
omdev/magic/magic.py,sha256=h1nxoW6CV1MRCiHjDt3sO4kmG0qTtTRbkDNiPLGo2BE,224
|
|
84
|
+
omdev/magic/prepare.py,sha256=V5jYT2AeFmazzPwk9sNismSouLwFXEoik6FwKcWCNUY,589
|
|
85
|
+
omdev/magic/styles.py,sha256=YZrLend-O5-7TKrIu4Ukxk1q0I2yaQtxwa6tn7TRbJM,599
|
|
82
86
|
omdev/manifests/__init__.py,sha256=P2B0dpT8D7l5lJwRGPA92IcQj6oeXfd90X5-q9BJrKg,51
|
|
83
|
-
omdev/manifests/build.py,sha256=
|
|
87
|
+
omdev/manifests/build.py,sha256=E7BelbrJEJes-BEbAUZCVLVs79sYuC0fbthgXAoxaOk,10865
|
|
84
88
|
omdev/manifests/load.py,sha256=LtEsluDdd8CkNGj0QGBxee3twBn095Fru0xz2mtr7uk,4788
|
|
85
89
|
omdev/manifests/types.py,sha256=Jv6PAdVLPb9Hh4y6vDhPlWuMNBBViin1bC_u83jfsH4,234
|
|
86
90
|
omdev/mypy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -94,10 +98,10 @@ omdev/precheck/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
94
98
|
omdev/precheck/__main__.py,sha256=UEuS4z5-heIrwTtB-ONe1KeXJdqj8tYXMqWMpuO10so,165
|
|
95
99
|
omdev/precheck/base.py,sha256=a_lGoFM-QhL8u8XDUYFhb-feEyfPbP4j8lcmNO51sHY,732
|
|
96
100
|
omdev/precheck/git.py,sha256=APC5Ln7x0zDrQiGPRWPsBcVJK3vWhbU-brqR5M63JQA,849
|
|
97
|
-
omdev/precheck/lite.py,sha256=
|
|
101
|
+
omdev/precheck/lite.py,sha256=z99pgTO4SAmLEqSj6qaKd4hcs0WpwixYkQZn75lZRX8,3883
|
|
98
102
|
omdev/precheck/main.py,sha256=2YizDZSDhMeQaZKVH83s99pBmtOUL9B-8dXwIcw6fQQ,2674
|
|
99
103
|
omdev/precheck/manifests.py,sha256=YfXqt6u0hlFXY0QkBMec6V_6Y9T4eCVAmrJDkQkB13U,774
|
|
100
|
-
omdev/precheck/scripts.py,sha256=
|
|
104
|
+
omdev/precheck/scripts.py,sha256=Xw9kkQzlDd_2V9av9qlaNpNZG9jZdy3TTo7x60MeR2I,1273
|
|
101
105
|
omdev/ptk/__init__.py,sha256=StAwXQ96e8Xkkg7ciR9oBBhcSgqHT76vhoZML82BuY0,447
|
|
102
106
|
omdev/ptk/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
107
|
omdev/ptk/apps/ncdu.py,sha256=ov6AEjne2NyVE45XiAtteq5SmbxXHQkUsybuu5KSwRQ,4479
|
|
@@ -106,7 +110,7 @@ omdev/pyproject/__main__.py,sha256=gn3Rl1aYPYdiTtEqa9ifi0t-e4ZwPY0vhJ4UXvYdJDY,1
|
|
|
106
110
|
omdev/pyproject/cexts.py,sha256=x13piOOnNrYbA17qZLDVuR0p1sqhgEwpk4FtImX-klM,4281
|
|
107
111
|
omdev/pyproject/cli.py,sha256=kw0Jyzywwt6QOc6QHDevWW9p85aXT7jvVFFb8Sb_EAU,11365
|
|
108
112
|
omdev/pyproject/configs.py,sha256=K9H5cGwVLgHi8wKwtYvlXHZ9ThtmnI4jo8JAb-t1-70,2859
|
|
109
|
-
omdev/pyproject/pkg.py,sha256=
|
|
113
|
+
omdev/pyproject/pkg.py,sha256=WB9k3zEpHSAR24H09kikgAnLMWUz-bk9f0aB-2L_ITw,14560
|
|
110
114
|
omdev/pyproject/reqs.py,sha256=8feZ71YnGzwKbLK4zO28CDQeNcZIIuq6cnkBhs6M-7E,2406
|
|
111
115
|
omdev/scripts/__init__.py,sha256=MKCvUAEQwsIvwLixwtPlpBqmkMXLCnjjXyAXvVpDwVk,91
|
|
112
116
|
omdev/scripts/bumpversion.py,sha256=Kn7fo73Hs8uJh3Hi3EIyLOlzLPWAC6dwuD_lZ3cIzuY,1064
|
|
@@ -114,7 +118,7 @@ omdev/scripts/execrss.py,sha256=hJTWBig_-XqKIj1DphYTfeVDtdQTM1XUl-Hvzs2x9iY,451
|
|
|
114
118
|
omdev/scripts/exectime.py,sha256=dBdn3KV2jR6tCrzGvb9dTl2uGe2vNpLxmHMtExmnaiM,410
|
|
115
119
|
omdev/scripts/importtrace.py,sha256=Jbo3Yk2RAbE8_tJ97iTcVNpoxCJxrRb2tl1W_CV3NG0,14067
|
|
116
120
|
omdev/scripts/interp.py,sha256=ls04OE3g_TpiK5_inRfOzUvBGUtBgSt5vnkqC3eZhTM,72076
|
|
117
|
-
omdev/scripts/pyproject.py,sha256=
|
|
121
|
+
omdev/scripts/pyproject.py,sha256=0etqlpe2wL2lRLKgRo6X5llzpvM-I7AHbu1oWqdV-6M,164318
|
|
118
122
|
omdev/scripts/slowcat.py,sha256=lssv4yrgJHiWfOiHkUut2p8E8Tq32zB-ujXESQxFFHY,2728
|
|
119
123
|
omdev/toml/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
120
124
|
omdev/toml/parser.py,sha256=84bn09uhYHwQGyfww6Rw6y1RxPAE_HDltODOSakcqDM,29186
|
|
@@ -132,9 +136,9 @@ omdev/tools/sqlrepl.py,sha256=tmFZh80-xsGM62dyQ7_UGLebChrj7IHbIPYBWDJMgVk,5741
|
|
|
132
136
|
omdev/tools/pawk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
133
137
|
omdev/tools/pawk/__main__.py,sha256=VCqeRVnqT1RPEoIrqHFSu4PXVMg4YEgF4qCQm90-eRI,66
|
|
134
138
|
omdev/tools/pawk/pawk.py,sha256=Eckymn22GfychCQcQi96BFqRo_LmiJ-EPhC8TTUJdB4,11446
|
|
135
|
-
omdev-0.0.0.
|
|
136
|
-
omdev-0.0.0.
|
|
137
|
-
omdev-0.0.0.
|
|
138
|
-
omdev-0.0.0.
|
|
139
|
-
omdev-0.0.0.
|
|
140
|
-
omdev-0.0.0.
|
|
139
|
+
omdev-0.0.0.dev100.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
|
140
|
+
omdev-0.0.0.dev100.dist-info/METADATA,sha256=jBN-gpjo8p3RwVShev6g75Sg2bNhC4oAAfL5Nj-Pqm0,1704
|
|
141
|
+
omdev-0.0.0.dev100.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
142
|
+
omdev-0.0.0.dev100.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
|
|
143
|
+
omdev-0.0.0.dev100.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
|
144
|
+
omdev-0.0.0.dev100.dist-info/RECORD,,
|
omdev/findmagic.py
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# @omlish-lite
|
|
3
|
-
# @omlish-script
|
|
4
|
-
import os.path
|
|
5
|
-
import re
|
|
6
|
-
import typing as ta
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def compile_magic_pat(m: str) -> re.Pattern:
|
|
10
|
-
return re.compile('^' + re.escape(m) + r'($|(\s.*))')
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def find_magic(
|
|
14
|
-
roots: ta.Sequence[str],
|
|
15
|
-
magics: ta.Sequence[str],
|
|
16
|
-
exts: ta.Sequence[str],
|
|
17
|
-
*,
|
|
18
|
-
py: bool = False,
|
|
19
|
-
) -> ta.Iterator[str]:
|
|
20
|
-
if isinstance(roots, str):
|
|
21
|
-
raise TypeError(roots)
|
|
22
|
-
if isinstance(magics, str):
|
|
23
|
-
raise TypeError(magics)
|
|
24
|
-
if isinstance(exts, str):
|
|
25
|
-
raise TypeError(exts)
|
|
26
|
-
|
|
27
|
-
if not magics:
|
|
28
|
-
raise Exception('Must specify magics')
|
|
29
|
-
if not exts:
|
|
30
|
-
raise Exception('Must specify extensions')
|
|
31
|
-
|
|
32
|
-
pats = [compile_magic_pat(m) for m in magics]
|
|
33
|
-
|
|
34
|
-
for root in roots:
|
|
35
|
-
for dp, dns, fns in os.walk(root): # noqa
|
|
36
|
-
for fn in fns:
|
|
37
|
-
if not any(fn.endswith(f'.{x}') for x in exts):
|
|
38
|
-
continue
|
|
39
|
-
|
|
40
|
-
fp = os.path.join(dp, fn)
|
|
41
|
-
try:
|
|
42
|
-
with open(fp) as f:
|
|
43
|
-
src = f.read()
|
|
44
|
-
except UnicodeDecodeError:
|
|
45
|
-
continue
|
|
46
|
-
|
|
47
|
-
if not any(
|
|
48
|
-
any(pat.fullmatch(l) for pat in pats)
|
|
49
|
-
for l in src.splitlines()
|
|
50
|
-
):
|
|
51
|
-
continue
|
|
52
|
-
|
|
53
|
-
if py:
|
|
54
|
-
if fn == '__init__.py':
|
|
55
|
-
out = dp.replace(os.sep, '.')
|
|
56
|
-
elif fn.endswith('.py'):
|
|
57
|
-
out = fp[:-3].replace(os.sep, '.')
|
|
58
|
-
else:
|
|
59
|
-
out = fp
|
|
60
|
-
else:
|
|
61
|
-
out = fp
|
|
62
|
-
yield out
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
# @omlish-manifest
|
|
66
|
-
_CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
|
67
|
-
'cmd_name': 'py/findmagic',
|
|
68
|
-
'mod_name': __name__,
|
|
69
|
-
}}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if __name__ == '__main__':
|
|
73
|
-
def _main(argv=None) -> None:
|
|
74
|
-
import argparse
|
|
75
|
-
|
|
76
|
-
arg_parser = argparse.ArgumentParser()
|
|
77
|
-
arg_parser.add_argument('--ext', '-x', dest='exts', action='append')
|
|
78
|
-
arg_parser.add_argument('--magic', '-m', dest='magics', action='append')
|
|
79
|
-
arg_parser.add_argument('--py', action='store_true')
|
|
80
|
-
arg_parser.add_argument('roots', nargs='*')
|
|
81
|
-
args = arg_parser.parse_args(argv)
|
|
82
|
-
|
|
83
|
-
for out in find_magic(
|
|
84
|
-
roots=args.roots,
|
|
85
|
-
magics=args.magics,
|
|
86
|
-
exts=args.exts,
|
|
87
|
-
py=args.py,
|
|
88
|
-
):
|
|
89
|
-
print(out)
|
|
90
|
-
|
|
91
|
-
_main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|