omdev 0.0.0.dev211__py3-none-any.whl → 0.0.0.dev213__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- omdev/.manifests.json +15 -1
- omdev/__about__.py +0 -4
- omdev/amalg/gen.py +2 -3
- omdev/amalg/imports.py +4 -5
- omdev/amalg/manifests.py +7 -10
- omdev/amalg/resources.py +24 -27
- omdev/amalg/srcfiles.py +7 -10
- omdev/amalg/strip.py +4 -5
- omdev/amalg/types.py +1 -1
- omdev/amalg/typing.py +9 -8
- omdev/cc/cdeps.py +34 -1
- omdev/cc/cdeps.toml +19 -2
- omdev/cc/cli.py +13 -1
- omdev/ci/ci.py +71 -48
- omdev/ci/cli.py +22 -10
- omdev/ci/compose.py +30 -56
- omdev/ci/docker.py +35 -16
- omdev/ci/github/cache.py +153 -184
- omdev/ci/github/cacheapi.py +1 -1
- omdev/ci/github/cli.py +2 -2
- omdev/ci/github/curl.py +209 -0
- omdev/ci/requirements.py +2 -2
- omdev/git/shallow.py +1 -1
- omdev/scripts/ci.py +948 -451
- omdev/scripts/interp.py +23 -0
- omdev/scripts/pyproject.py +23 -0
- omdev/tokens/__init__.py +0 -0
- omdev/tokens/all.py +35 -0
- omdev/tokens/tokenizert.py +215 -0
- omdev/{tokens.py → tokens/utils.py} +6 -12
- omdev/tools/mkenv.py +131 -0
- omdev/tools/mkrelimp.py +4 -6
- {omdev-0.0.0.dev211.dist-info → omdev-0.0.0.dev213.dist-info}/METADATA +2 -5
- {omdev-0.0.0.dev211.dist-info → omdev-0.0.0.dev213.dist-info}/RECORD +38 -33
- {omdev-0.0.0.dev211.dist-info → omdev-0.0.0.dev213.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev211.dist-info → omdev-0.0.0.dev213.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev211.dist-info → omdev-0.0.0.dev213.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev211.dist-info → omdev-0.0.0.dev213.dist-info}/top_level.txt +0 -0
omdev/scripts/interp.py
CHANGED
@@ -606,6 +606,17 @@ class Checks:
|
|
606
606
|
|
607
607
|
#
|
608
608
|
|
609
|
+
def register_on_raise_breakpoint_if_env_var_set(self, key: str) -> None:
|
610
|
+
import os
|
611
|
+
|
612
|
+
def on_raise(exc: Exception) -> None: # noqa
|
613
|
+
if key in os.environ:
|
614
|
+
breakpoint() # noqa
|
615
|
+
|
616
|
+
self.register_on_raise(on_raise)
|
617
|
+
|
618
|
+
#
|
619
|
+
|
609
620
|
def set_exception_factory(self, factory: CheckExceptionFactory) -> None:
|
610
621
|
self._exception_factory = factory
|
611
622
|
|
@@ -921,6 +932,18 @@ class Checks:
|
|
921
932
|
|
922
933
|
return v
|
923
934
|
|
935
|
+
def not_equal(self, v: T, o: ta.Any, msg: CheckMessage = None) -> T:
|
936
|
+
if o == v:
|
937
|
+
self._raise(
|
938
|
+
ValueError,
|
939
|
+
'Must not be equal',
|
940
|
+
msg,
|
941
|
+
Checks._ArgsKwargs(v, o),
|
942
|
+
render_fmt='%s == %s',
|
943
|
+
)
|
944
|
+
|
945
|
+
return v
|
946
|
+
|
924
947
|
def is_(self, v: T, o: ta.Any, msg: CheckMessage = None) -> T:
|
925
948
|
if o is not v:
|
926
949
|
self._raise(
|
omdev/scripts/pyproject.py
CHANGED
@@ -1907,6 +1907,17 @@ class Checks:
|
|
1907
1907
|
|
1908
1908
|
#
|
1909
1909
|
|
1910
|
+
def register_on_raise_breakpoint_if_env_var_set(self, key: str) -> None:
|
1911
|
+
import os
|
1912
|
+
|
1913
|
+
def on_raise(exc: Exception) -> None: # noqa
|
1914
|
+
if key in os.environ:
|
1915
|
+
breakpoint() # noqa
|
1916
|
+
|
1917
|
+
self.register_on_raise(on_raise)
|
1918
|
+
|
1919
|
+
#
|
1920
|
+
|
1910
1921
|
def set_exception_factory(self, factory: CheckExceptionFactory) -> None:
|
1911
1922
|
self._exception_factory = factory
|
1912
1923
|
|
@@ -2222,6 +2233,18 @@ class Checks:
|
|
2222
2233
|
|
2223
2234
|
return v
|
2224
2235
|
|
2236
|
+
def not_equal(self, v: T, o: ta.Any, msg: CheckMessage = None) -> T:
|
2237
|
+
if o == v:
|
2238
|
+
self._raise(
|
2239
|
+
ValueError,
|
2240
|
+
'Must not be equal',
|
2241
|
+
msg,
|
2242
|
+
Checks._ArgsKwargs(v, o),
|
2243
|
+
render_fmt='%s == %s',
|
2244
|
+
)
|
2245
|
+
|
2246
|
+
return v
|
2247
|
+
|
2225
2248
|
def is_(self, v: T, o: ta.Any, msg: CheckMessage = None) -> T:
|
2226
2249
|
if o is not v:
|
2227
2250
|
self._raise(
|
omdev/tokens/__init__.py
ADDED
File without changes
|
omdev/tokens/all.py
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
from .tokenizert import ( # noqa
|
2
|
+
TokenNames,
|
3
|
+
Token,
|
4
|
+
TokenOffset,
|
5
|
+
|
6
|
+
Tokenization,
|
7
|
+
)
|
8
|
+
|
9
|
+
from .utils import ( # noqa
|
10
|
+
Tokens,
|
11
|
+
|
12
|
+
WS_NAMES,
|
13
|
+
is_ws,
|
14
|
+
ignore_ws,
|
15
|
+
|
16
|
+
split_lines,
|
17
|
+
join_toks,
|
18
|
+
join_lines,
|
19
|
+
|
20
|
+
match_toks,
|
21
|
+
)
|
22
|
+
|
23
|
+
|
24
|
+
##
|
25
|
+
|
26
|
+
|
27
|
+
ESCAPED_NL = TokenNames.ESCAPED_NL # noqa
|
28
|
+
UNIMPORTANT_WS = TokenNames.UNIMPORTANT_WS # noqa
|
29
|
+
NON_CODING_TOKENS = TokenNames.NON_CODING_TOKENS # noqa
|
30
|
+
|
31
|
+
curly_escape = Tokenization.curly_escape # noqa
|
32
|
+
src_to_tokens = Tokenization.src_to_tokens # noqa
|
33
|
+
parse_string_literal = Tokenization.parse_string_literal # noqa
|
34
|
+
tokens_to_src = Tokenization.tokens_to_src # noqa
|
35
|
+
rfind_string_parts = Tokenization.rfind_string_parts # noqa
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# @omlish-lite
|
2
|
+
# ruff: noqa: UP006 UP007
|
3
|
+
# Copyright (c) 2017 Anthony Sottile
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
6
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
7
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
11
|
+
# Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
14
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
16
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
# https://github.com/asottile/tokenize-rt/blob/413692b7c1ad8a873caec39dd4f427d55ee538ea/tokenize_rt.py
|
18
|
+
import argparse
|
19
|
+
import io
|
20
|
+
import keyword
|
21
|
+
import re
|
22
|
+
import tokenize
|
23
|
+
import typing as ta
|
24
|
+
|
25
|
+
from omlish.lite.check import check
|
26
|
+
|
27
|
+
|
28
|
+
##
|
29
|
+
|
30
|
+
|
31
|
+
class TokenNames:
|
32
|
+
def __new__(cls, *args, **kwargs): # noqa
|
33
|
+
raise TypeError
|
34
|
+
|
35
|
+
ESCAPED_NL = 'ESCAPED_NL'
|
36
|
+
UNIMPORTANT_WS = 'UNIMPORTANT_WS'
|
37
|
+
NON_CODING_TOKENS = frozenset(('COMMENT', ESCAPED_NL, 'NL', UNIMPORTANT_WS))
|
38
|
+
|
39
|
+
|
40
|
+
class TokenOffset(ta.NamedTuple):
|
41
|
+
line: ta.Optional[int] = None
|
42
|
+
utf8_byte_offset: ta.Optional[int] = None
|
43
|
+
|
44
|
+
|
45
|
+
class Token(ta.NamedTuple):
|
46
|
+
name: str
|
47
|
+
src: str
|
48
|
+
line: ta.Optional[int] = None
|
49
|
+
utf8_byte_offset: ta.Optional[int] = None
|
50
|
+
|
51
|
+
@property
|
52
|
+
def offset(self) -> TokenOffset:
|
53
|
+
return TokenOffset(self.line, self.utf8_byte_offset)
|
54
|
+
|
55
|
+
def matches(self, *, name: str, src: str) -> bool:
|
56
|
+
return self.name == name and self.src == src
|
57
|
+
|
58
|
+
|
59
|
+
##
|
60
|
+
|
61
|
+
|
62
|
+
class Tokenization:
|
63
|
+
_STRING_RE = re.compile('^([^\'"]*)(.*)$', re.DOTALL)
|
64
|
+
_ESCAPED_NL_RE = re.compile(r'\\(\n|\r\n|\r)')
|
65
|
+
|
66
|
+
_NAMED_UNICODE_RE = re.compile(r'(?<!\\)(?:\\\\)*(\\N\{[^}]+\})')
|
67
|
+
|
68
|
+
@classmethod
|
69
|
+
def curly_escape(cls, s: str) -> str:
|
70
|
+
parts = cls._NAMED_UNICODE_RE.split(s)
|
71
|
+
return ''.join(
|
72
|
+
part.replace('{', '{{').replace('}', '}}') if i % 2 == 0 else part
|
73
|
+
for i, part in enumerate(parts)
|
74
|
+
)
|
75
|
+
|
76
|
+
@classmethod
|
77
|
+
def _re_partition(cls, regex: ta.Pattern[str], s: str) -> ta.Tuple[str, str, str]:
|
78
|
+
match = regex.search(s)
|
79
|
+
if match:
|
80
|
+
return s[:match.start()], s[slice(*match.span())], s[match.end():]
|
81
|
+
else:
|
82
|
+
return (s, '', '')
|
83
|
+
|
84
|
+
@classmethod
|
85
|
+
def src_to_tokens(cls, src: str) -> ta.List[Token]:
|
86
|
+
tokenize_target = io.StringIO(src)
|
87
|
+
lines = ('', *tokenize_target)
|
88
|
+
|
89
|
+
tokenize_target.seek(0)
|
90
|
+
|
91
|
+
tokens = []
|
92
|
+
last_line = 1
|
93
|
+
last_col = 0
|
94
|
+
end_offset = 0
|
95
|
+
|
96
|
+
gen = tokenize.generate_tokens(tokenize_target.readline)
|
97
|
+
for tok_type, tok_text, (sline, scol), (eline, ecol), line in gen:
|
98
|
+
if sline > last_line:
|
99
|
+
newtok = lines[last_line][last_col:]
|
100
|
+
for lineno in range(last_line + 1, sline):
|
101
|
+
newtok += lines[lineno]
|
102
|
+
if scol > 0:
|
103
|
+
newtok += lines[sline][:scol]
|
104
|
+
|
105
|
+
# a multiline unimportant whitespace may contain escaped newlines
|
106
|
+
while cls._ESCAPED_NL_RE.search(newtok):
|
107
|
+
ws, nl, newtok = cls._re_partition(cls._ESCAPED_NL_RE, newtok)
|
108
|
+
if ws:
|
109
|
+
tokens.append(Token(TokenNames.UNIMPORTANT_WS, ws, last_line, end_offset))
|
110
|
+
end_offset += len(ws.encode())
|
111
|
+
tokens.append(Token(TokenNames.ESCAPED_NL, nl, last_line, end_offset))
|
112
|
+
end_offset = 0
|
113
|
+
last_line += 1
|
114
|
+
if newtok:
|
115
|
+
tokens.append(Token(TokenNames.UNIMPORTANT_WS, newtok, sline, 0))
|
116
|
+
end_offset = len(newtok.encode())
|
117
|
+
else:
|
118
|
+
end_offset = 0
|
119
|
+
|
120
|
+
elif scol > last_col:
|
121
|
+
newtok = line[last_col:scol]
|
122
|
+
tokens.append(Token(TokenNames.UNIMPORTANT_WS, newtok, sline, end_offset))
|
123
|
+
end_offset += len(newtok.encode())
|
124
|
+
|
125
|
+
tok_name = tokenize.tok_name[tok_type]
|
126
|
+
|
127
|
+
if tok_name == 'FSTRING_MIDDLE': # pragma: >=3.12 cover
|
128
|
+
if '{' in tok_text or '}' in tok_text:
|
129
|
+
new_tok_text = cls.curly_escape(tok_text)
|
130
|
+
ecol += len(new_tok_text) - len(tok_text)
|
131
|
+
tok_text = new_tok_text
|
132
|
+
|
133
|
+
tokens.append(Token(tok_name, tok_text, sline, end_offset))
|
134
|
+
last_line, last_col = eline, ecol
|
135
|
+
if sline != eline:
|
136
|
+
end_offset = len(lines[last_line][:last_col].encode())
|
137
|
+
else:
|
138
|
+
end_offset += len(tok_text.encode())
|
139
|
+
|
140
|
+
return tokens
|
141
|
+
|
142
|
+
@classmethod
|
143
|
+
def parse_string_literal(cls, src: str) -> ta.Tuple[str, str]:
|
144
|
+
"""parse a string literal's source into (prefix, string)"""
|
145
|
+
match = check.not_none(cls._STRING_RE.match(src))
|
146
|
+
return match.group(1), match.group(2)
|
147
|
+
|
148
|
+
@classmethod
|
149
|
+
def tokens_to_src(cls, tokens: ta.Iterable[Token]) -> str:
|
150
|
+
return ''.join(tok.src for tok in tokens)
|
151
|
+
|
152
|
+
@classmethod
|
153
|
+
def rfind_string_parts(cls, tokens: ta.Sequence[Token], start: int) -> ta.Tuple[int, ...]:
|
154
|
+
"""
|
155
|
+
Find the indicies of the string parts of a (joined) string literal.
|
156
|
+
|
157
|
+
- `i` should start at the end of the string literal
|
158
|
+
- returns `()` (an empty tuple) for things which are not string literals
|
159
|
+
"""
|
160
|
+
|
161
|
+
ret = []
|
162
|
+
depth = 0
|
163
|
+
for i in range(start, -1, -1):
|
164
|
+
token = tokens[i]
|
165
|
+
if token.name == 'STRING':
|
166
|
+
ret.append(i)
|
167
|
+
elif token.name in TokenNames.NON_CODING_TOKENS:
|
168
|
+
pass
|
169
|
+
elif token.src == ')':
|
170
|
+
depth += 1
|
171
|
+
elif depth and token.src == '(':
|
172
|
+
depth -= 1
|
173
|
+
# if we closed the paren(s) make sure it was a parenthesized string
|
174
|
+
# and not actually a call
|
175
|
+
if depth == 0:
|
176
|
+
for j in range(i - 1, -1, -1):
|
177
|
+
tok = tokens[j]
|
178
|
+
if tok.name in TokenNames.NON_CODING_TOKENS:
|
179
|
+
pass
|
180
|
+
# this was actually a call and not a parenthesized string
|
181
|
+
elif (
|
182
|
+
tok.src in {']', ')'} or (
|
183
|
+
tok.name == 'NAME' and
|
184
|
+
tok.src not in keyword.kwlist
|
185
|
+
)
|
186
|
+
):
|
187
|
+
return ()
|
188
|
+
else:
|
189
|
+
break
|
190
|
+
break
|
191
|
+
elif depth: # it looked like a string but wasn't
|
192
|
+
return ()
|
193
|
+
else:
|
194
|
+
break
|
195
|
+
return tuple(reversed(ret))
|
196
|
+
|
197
|
+
|
198
|
+
##
|
199
|
+
|
200
|
+
|
201
|
+
if __name__ == '__main__':
|
202
|
+
def main(argv: ta.Optional[ta.Sequence[str]] = None) -> int:
|
203
|
+
parser = argparse.ArgumentParser()
|
204
|
+
parser.add_argument('filename')
|
205
|
+
args = parser.parse_args(argv)
|
206
|
+
with open(args.filename) as f:
|
207
|
+
tokens = Tokenization.src_to_tokens(f.read())
|
208
|
+
|
209
|
+
for token in tokens:
|
210
|
+
line, col = str(token.line), str(token.utf8_byte_offset)
|
211
|
+
print(f'{line}:{col} {token.name} {token.src!r}')
|
212
|
+
|
213
|
+
return 0
|
214
|
+
|
215
|
+
raise SystemExit(main())
|
@@ -1,16 +1,10 @@
|
|
1
1
|
import itertools
|
2
2
|
import typing as ta
|
3
3
|
|
4
|
-
from
|
4
|
+
from .tokenizert import Token
|
5
5
|
|
6
6
|
|
7
|
-
|
8
|
-
import tokenize_rt as trt
|
9
|
-
else:
|
10
|
-
trt = lang.proxy_import('tokenize_rt')
|
11
|
-
|
12
|
-
|
13
|
-
Tokens: ta.TypeAlias = ta.Sequence['trt.Token']
|
7
|
+
Tokens: ta.TypeAlias = ta.Sequence[Token]
|
14
8
|
|
15
9
|
|
16
10
|
##
|
@@ -25,15 +19,15 @@ WS_NAMES = (
|
|
25
19
|
)
|
26
20
|
|
27
21
|
|
28
|
-
def is_ws(tok:
|
22
|
+
def is_ws(tok: Token) -> bool:
|
29
23
|
return tok.name in WS_NAMES
|
30
24
|
|
31
25
|
|
32
26
|
def ignore_ws(
|
33
|
-
toks: ta.Iterable[
|
27
|
+
toks: ta.Iterable[Token],
|
34
28
|
*,
|
35
29
|
keep: ta.Container[str] = (),
|
36
|
-
) -> ta.Iterable[
|
30
|
+
) -> ta.Iterable[Token]:
|
37
31
|
return (
|
38
32
|
t
|
39
33
|
for t in toks
|
@@ -60,7 +54,7 @@ def join_lines(ls: ta.Iterable[Tokens]) -> str:
|
|
60
54
|
|
61
55
|
|
62
56
|
def match_toks(
|
63
|
-
ts: ta.Iterable[
|
57
|
+
ts: ta.Iterable[Token],
|
64
58
|
pat: ta.Sequence[tuple[str | None, str | tuple[str, ...] | None]],
|
65
59
|
) -> bool:
|
66
60
|
it = iter(ts)
|
omdev/tools/mkenv.py
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- detect file extension
|
4
|
+
|
5
|
+
==
|
6
|
+
|
7
|
+
export $(./python mkenv.py secrets.yml foo_access_token | xargs)
|
8
|
+
eval $(om mkenv -e secrets.yml foo_access_token)
|
9
|
+
"""
|
10
|
+
import argparse
|
11
|
+
import json
|
12
|
+
import shlex
|
13
|
+
import sys
|
14
|
+
import typing as ta
|
15
|
+
|
16
|
+
from omlish import check
|
17
|
+
from omlish.configs.formats import DEFAULT_CONFIG_FILE_LOADER
|
18
|
+
from omlish.specs import jmespath
|
19
|
+
|
20
|
+
|
21
|
+
##
|
22
|
+
|
23
|
+
|
24
|
+
VALUE_TYPES: tuple[type, ...] = (
|
25
|
+
str,
|
26
|
+
int,
|
27
|
+
float,
|
28
|
+
bool,
|
29
|
+
)
|
30
|
+
|
31
|
+
|
32
|
+
def extract_item(
|
33
|
+
obj: ta.Any,
|
34
|
+
item: str,
|
35
|
+
*,
|
36
|
+
uppercase_keys: bool = False,
|
37
|
+
) -> tuple[str, str]:
|
38
|
+
if '=' not in item:
|
39
|
+
k = item
|
40
|
+
v = obj[k]
|
41
|
+
if uppercase_keys:
|
42
|
+
k = k.upper()
|
43
|
+
|
44
|
+
else:
|
45
|
+
k, p = item.split('=')
|
46
|
+
v = jmespath.search(p, obj)
|
47
|
+
|
48
|
+
#
|
49
|
+
|
50
|
+
if isinstance(v, str):
|
51
|
+
s = v
|
52
|
+
|
53
|
+
elif isinstance(v, bool):
|
54
|
+
s = 'true' if v else 'false'
|
55
|
+
|
56
|
+
else:
|
57
|
+
check.isinstance(v, VALUE_TYPES)
|
58
|
+
s = str(v)
|
59
|
+
|
60
|
+
#
|
61
|
+
|
62
|
+
check.equal(s.strip(), s)
|
63
|
+
for c in '\t\n':
|
64
|
+
check.not_in(c, s)
|
65
|
+
|
66
|
+
#
|
67
|
+
|
68
|
+
return (k, s)
|
69
|
+
|
70
|
+
|
71
|
+
def extract_items(
|
72
|
+
obj: ta.Any,
|
73
|
+
items: ta.Iterable[str],
|
74
|
+
**kwargs: ta.Any,
|
75
|
+
) -> dict[str, str]:
|
76
|
+
return dict(
|
77
|
+
extract_item(obj, item, **kwargs)
|
78
|
+
for item in items
|
79
|
+
)
|
80
|
+
|
81
|
+
|
82
|
+
def _main() -> None:
|
83
|
+
parser = argparse.ArgumentParser()
|
84
|
+
|
85
|
+
parser.add_argument('file')
|
86
|
+
parser.add_argument('-e', '--for-eval', action='store_true')
|
87
|
+
parser.add_argument('-u', '--uppercase', action='store_true')
|
88
|
+
parser.add_argument('item', nargs='*')
|
89
|
+
|
90
|
+
args = parser.parse_args()
|
91
|
+
|
92
|
+
#
|
93
|
+
|
94
|
+
if args.file == '-':
|
95
|
+
obj = json.loads(sys.stdin.read())
|
96
|
+
|
97
|
+
else:
|
98
|
+
data = DEFAULT_CONFIG_FILE_LOADER.load_file(args.file)
|
99
|
+
obj = data.as_map()
|
100
|
+
|
101
|
+
#
|
102
|
+
|
103
|
+
items = extract_items(
|
104
|
+
obj,
|
105
|
+
args.item,
|
106
|
+
uppercase_keys=args.uppercase,
|
107
|
+
)
|
108
|
+
|
109
|
+
#
|
110
|
+
|
111
|
+
if args.for_eval:
|
112
|
+
cmd = ' '.join([
|
113
|
+
'export',
|
114
|
+
*[f'{k}={qv if (qv := shlex.quote(v)) != v else v}' for k, v in items.items()],
|
115
|
+
])
|
116
|
+
print(cmd)
|
117
|
+
|
118
|
+
else:
|
119
|
+
for k, v in items.items():
|
120
|
+
print(f'{k}={v}')
|
121
|
+
|
122
|
+
|
123
|
+
# @omlish-manifest
|
124
|
+
_CLI_MODULE = {'$omdev.cli.types.CliModule': {
|
125
|
+
'cmd_name': ['mkenv'],
|
126
|
+
'mod_name': __name__,
|
127
|
+
}}
|
128
|
+
|
129
|
+
|
130
|
+
if __name__ == '__main__':
|
131
|
+
_main()
|
omdev/tools/mkrelimp.py
CHANGED
@@ -4,12 +4,10 @@ import logging
|
|
4
4
|
import os.path
|
5
5
|
import typing as ta
|
6
6
|
|
7
|
-
import tokenize_rt as trt
|
8
|
-
|
9
7
|
from omlish.logs import all as logs
|
10
8
|
|
11
|
-
from .. import tokens as tks
|
12
9
|
from ..cli import CliModule
|
10
|
+
from ..tokens import all as tks
|
13
11
|
|
14
12
|
|
15
13
|
T = ta.TypeVar('T')
|
@@ -91,8 +89,8 @@ class Processor:
|
|
91
89
|
##
|
92
90
|
|
93
91
|
new_tks = list(interleave(
|
94
|
-
|
95
|
-
[
|
92
|
+
tks.Token(name='OP', src='.'),
|
93
|
+
[tks.Token(name='NAME', src=p) for p in rel_imp_name_parts],
|
96
94
|
))
|
97
95
|
out_tks = [
|
98
96
|
*pfx,
|
@@ -111,7 +109,7 @@ class Processor:
|
|
111
109
|
with open(src_file) as f:
|
112
110
|
src = f.read()
|
113
111
|
|
114
|
-
ts =
|
112
|
+
ts = tks.src_to_tokens(src)
|
115
113
|
in_ls = tks.split_lines(ts)
|
116
114
|
out_ls = [
|
117
115
|
self.process_line_tks(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: omdev
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev213
|
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.dev213
|
16
16
|
Provides-Extra: all
|
17
17
|
Requires-Dist: black~=24.10; extra == "all"
|
18
18
|
Requires-Dist: pycparser~=2.22; extra == "all"
|
@@ -24,7 +24,6 @@ Requires-Dist: mypy~=1.11; extra == "all"
|
|
24
24
|
Requires-Dist: gprof2dot~=2024.6; extra == "all"
|
25
25
|
Requires-Dist: prompt-toolkit~=3.0; extra == "all"
|
26
26
|
Requires-Dist: segno~=1.6; extra == "all"
|
27
|
-
Requires-Dist: tokenize-rt~=6.1; extra == "all"
|
28
27
|
Requires-Dist: wheel~=0.44; extra == "all"
|
29
28
|
Provides-Extra: black
|
30
29
|
Requires-Dist: black~=24.10; extra == "black"
|
@@ -43,7 +42,5 @@ Provides-Extra: ptk
|
|
43
42
|
Requires-Dist: prompt-toolkit~=3.0; extra == "ptk"
|
44
43
|
Provides-Extra: qr
|
45
44
|
Requires-Dist: segno~=1.6; extra == "qr"
|
46
|
-
Provides-Extra: tokens
|
47
|
-
Requires-Dist: tokenize-rt~=6.1; extra == "tokens"
|
48
45
|
Provides-Extra: wheel
|
49
46
|
Requires-Dist: wheel~=0.44; extra == "wheel"
|