omdev 0.0.0.dev97__py3-none-any.whl → 0.0.0.dev98__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.
- omdev/.manifests.json +24 -12
- omdev/__about__.py +5 -2
- omdev/tools/doctools.py +108 -0
- omdev/tools/pawk/__init__.py +0 -0
- omdev/tools/pawk/__main__.py +4 -0
- omdev/tools/pawk/pawk.py +395 -0
- {omdev-0.0.0.dev97.dist-info → omdev-0.0.0.dev98.dist-info}/METADATA +8 -6
- {omdev-0.0.0.dev97.dist-info → omdev-0.0.0.dev98.dist-info}/RECORD +12 -9
- omdev/tools/rsttool.py +0 -60
- {omdev-0.0.0.dev97.dist-info → omdev-0.0.0.dev98.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev97.dist-info → omdev-0.0.0.dev98.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev97.dist-info → omdev-0.0.0.dev98.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev97.dist-info → omdev-0.0.0.dev98.dist-info}/top_level.txt +0 -0
omdev/.manifests.json
CHANGED
|
@@ -203,6 +203,18 @@
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
},
|
|
206
|
+
{
|
|
207
|
+
"module": ".tools.doctools",
|
|
208
|
+
"attr": "_CLI_MODULE",
|
|
209
|
+
"file": "omdev/tools/doctools.py",
|
|
210
|
+
"line": 103,
|
|
211
|
+
"value": {
|
|
212
|
+
"$.cli.types.CliModule": {
|
|
213
|
+
"cmd_name": "doc",
|
|
214
|
+
"mod_name": "omdev.tools.doctools"
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
},
|
|
206
218
|
{
|
|
207
219
|
"module": ".tools.gittools",
|
|
208
220
|
"attr": "_CLI_MODULE",
|
|
@@ -254,6 +266,18 @@
|
|
|
254
266
|
}
|
|
255
267
|
}
|
|
256
268
|
},
|
|
269
|
+
{
|
|
270
|
+
"module": ".tools.pawk.pawk",
|
|
271
|
+
"attr": "_CLI_MODULE",
|
|
272
|
+
"file": "omdev/tools/pawk/pawk.py",
|
|
273
|
+
"line": 390,
|
|
274
|
+
"value": {
|
|
275
|
+
"$.cli.types.CliModule": {
|
|
276
|
+
"cmd_name": "pawk",
|
|
277
|
+
"mod_name": "omdev.tools.pawk.pawk"
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
},
|
|
257
281
|
{
|
|
258
282
|
"module": ".tools.piptools",
|
|
259
283
|
"attr": "_CLI_MODULE",
|
|
@@ -278,18 +302,6 @@
|
|
|
278
302
|
}
|
|
279
303
|
}
|
|
280
304
|
},
|
|
281
|
-
{
|
|
282
|
-
"module": ".tools.rsttool",
|
|
283
|
-
"attr": "_CLI_MODULE",
|
|
284
|
-
"file": "omdev/tools/rsttool.py",
|
|
285
|
-
"line": 55,
|
|
286
|
-
"value": {
|
|
287
|
-
"$.cli.types.CliModule": {
|
|
288
|
-
"cmd_name": "rst",
|
|
289
|
-
"mod_name": "omdev.tools.rsttool"
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
},
|
|
293
305
|
{
|
|
294
306
|
"module": ".tools.sqlrepl",
|
|
295
307
|
"attr": "_CLI_MODULE",
|
omdev/__about__.py
CHANGED
omdev/tools/doctools.py
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- omdev/rst.py *and* rsttool.py, when we want extracted helpers
|
|
4
|
+
"""
|
|
5
|
+
import contextlib
|
|
6
|
+
import io
|
|
7
|
+
import os.path
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
import tempfile
|
|
11
|
+
import typing as ta
|
|
12
|
+
|
|
13
|
+
from omlish import argparse as ap
|
|
14
|
+
from omlish import check
|
|
15
|
+
from omlish import lang
|
|
16
|
+
|
|
17
|
+
from ..cli import CliModule
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
if ta.TYPE_CHECKING:
|
|
21
|
+
import docutils.core
|
|
22
|
+
import markdown
|
|
23
|
+
else:
|
|
24
|
+
docutils = lang.proxy_import('docutils', extras=['core'])
|
|
25
|
+
markdown = lang.proxy_import('markdown')
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def rst2html(rst, report_level=None):
|
|
29
|
+
kwargs = {
|
|
30
|
+
'writer_name': 'html',
|
|
31
|
+
'settings_overrides': {
|
|
32
|
+
'_disable_config': True,
|
|
33
|
+
'report_level': int(report_level) if report_level else 0,
|
|
34
|
+
},
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
target = io.StringIO()
|
|
38
|
+
with contextlib.redirect_stderr(target):
|
|
39
|
+
parts = docutils.core.publish_parts(rst, **kwargs) # type: ignore
|
|
40
|
+
html = parts['html_body']
|
|
41
|
+
warning = target.getvalue().strip()
|
|
42
|
+
return html, warning
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def open_html(src: str, name: str) -> None:
|
|
46
|
+
check.non_empty_str(name)
|
|
47
|
+
out_dir = tempfile.mkdtemp()
|
|
48
|
+
out_file = os.path.join(out_dir, name + '.html')
|
|
49
|
+
with open(out_file, 'w') as f:
|
|
50
|
+
f.write(src)
|
|
51
|
+
subprocess.check_call(['open', out_file])
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class Cli(ap.Cli):
|
|
55
|
+
def _read_file(self, input_file: str | None) -> tuple[str, str]:
|
|
56
|
+
if input_file is not None:
|
|
57
|
+
with open(input_file) as f:
|
|
58
|
+
src = f.read()
|
|
59
|
+
name = os.path.basename(input_file)
|
|
60
|
+
|
|
61
|
+
else:
|
|
62
|
+
src = sys.stdin.read()
|
|
63
|
+
name = 'stdin'
|
|
64
|
+
|
|
65
|
+
return src, name
|
|
66
|
+
|
|
67
|
+
@ap.command(
|
|
68
|
+
ap.arg('input-file', nargs='?'),
|
|
69
|
+
ap.arg('--report-level', type=int),
|
|
70
|
+
ap.arg('-O', '--open', action='store_true'),
|
|
71
|
+
)
|
|
72
|
+
def rst(self) -> None:
|
|
73
|
+
src, name = self._read_file(self.args.input_file)
|
|
74
|
+
|
|
75
|
+
html, warning = rst2html(
|
|
76
|
+
src,
|
|
77
|
+
report_level=self.args.report_level,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
if warning:
|
|
81
|
+
sys.stderr.write(warning)
|
|
82
|
+
|
|
83
|
+
if self.args.open:
|
|
84
|
+
open_html(html, name)
|
|
85
|
+
else:
|
|
86
|
+
print(html)
|
|
87
|
+
|
|
88
|
+
@ap.command(
|
|
89
|
+
ap.arg('input-file', nargs='?'),
|
|
90
|
+
ap.arg('-O', '--open', action='store_true'),
|
|
91
|
+
)
|
|
92
|
+
def md(self):
|
|
93
|
+
src, name = self._read_file(self.args.input_file)
|
|
94
|
+
|
|
95
|
+
html = markdown.markdown(src)
|
|
96
|
+
|
|
97
|
+
if self.args.open:
|
|
98
|
+
open_html(html, name)
|
|
99
|
+
else:
|
|
100
|
+
print(html)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# @omlish-manifest
|
|
104
|
+
_CLI_MODULE = CliModule('doc', __name__)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
if __name__ == '__main__':
|
|
108
|
+
Cli().call_and_exit()
|
|
File without changes
|
omdev/tools/pawk/pawk.py
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# Copyright (C) 2018 Alec Thomas
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
5
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
|
6
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
7
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
8
|
+
#
|
|
9
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
|
10
|
+
# Software.
|
|
11
|
+
#
|
|
12
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
13
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
14
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
15
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
16
|
+
# https://github.com/alecthomas/pawk/blob/d60f78399e8a01857ebd73415a00e7eb424043ab/pawk.py
|
|
17
|
+
"""cat input | pawk [<options>] <expr>
|
|
18
|
+
|
|
19
|
+
A Python line-processor (like awk).
|
|
20
|
+
|
|
21
|
+
See https://github.com/alecthomas/pawk for details. Based on
|
|
22
|
+
http://code.activestate.com/recipes/437932/.
|
|
23
|
+
"""
|
|
24
|
+
import argparse
|
|
25
|
+
import ast
|
|
26
|
+
import codecs
|
|
27
|
+
import contextlib
|
|
28
|
+
import inspect
|
|
29
|
+
import itertools
|
|
30
|
+
import os
|
|
31
|
+
import re
|
|
32
|
+
import sys
|
|
33
|
+
import types
|
|
34
|
+
import typing as ta
|
|
35
|
+
|
|
36
|
+
from omlish import check
|
|
37
|
+
|
|
38
|
+
from ...cli import CliModule
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
RESULT_VAR_NAME = '__result'
|
|
42
|
+
|
|
43
|
+
STRING_ESCAPE = 'unicode_escape'
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Store the last expression, if present, into variable var_name.
|
|
47
|
+
def save_last_expression(
|
|
48
|
+
tree: ast.Module,
|
|
49
|
+
var_name: str = RESULT_VAR_NAME,
|
|
50
|
+
) -> ast.Module:
|
|
51
|
+
body = tree.body
|
|
52
|
+
|
|
53
|
+
node: ast.AST | None = body[-1] if len(body) else None
|
|
54
|
+
|
|
55
|
+
body.insert(
|
|
56
|
+
0,
|
|
57
|
+
ast.Assign(
|
|
58
|
+
targets=[
|
|
59
|
+
ast.Name(
|
|
60
|
+
id=var_name,
|
|
61
|
+
ctx=ast.Store(),
|
|
62
|
+
),
|
|
63
|
+
],
|
|
64
|
+
value=ast.Constant(None),
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if node is not None and isinstance(node, ast.Expr):
|
|
69
|
+
body[-1] = ast.copy_location(
|
|
70
|
+
ast.Assign(
|
|
71
|
+
targets=[
|
|
72
|
+
ast.Name(
|
|
73
|
+
id=var_name,
|
|
74
|
+
ctx=ast.Store(),
|
|
75
|
+
),
|
|
76
|
+
],
|
|
77
|
+
value=node.value,
|
|
78
|
+
),
|
|
79
|
+
node, # noqa
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
return ast.fix_missing_locations(tree)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def compile_command(text: str) -> types.CodeType:
|
|
86
|
+
mod = check.isinstance(compile(text, 'EXPR', 'exec', flags=ast.PyCF_ONLY_AST), ast.Module)
|
|
87
|
+
tree = save_last_expression(mod)
|
|
88
|
+
return compile(tree, 'EXPR', 'exec')
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def eval_in_context(
|
|
92
|
+
codeobj: types.CodeType,
|
|
93
|
+
context: 'Context',
|
|
94
|
+
var_name: str = RESULT_VAR_NAME,
|
|
95
|
+
) -> ta.Any:
|
|
96
|
+
exec(codeobj, globals(), context)
|
|
97
|
+
return context.pop(var_name, None)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class Action:
|
|
101
|
+
"""Represents a single action to be applied to each line."""
|
|
102
|
+
|
|
103
|
+
def __init__(
|
|
104
|
+
self,
|
|
105
|
+
pattern: str | None = None,
|
|
106
|
+
cmd: str = 'l',
|
|
107
|
+
have_end_statement: bool = False,
|
|
108
|
+
negate: bool = False,
|
|
109
|
+
strict: bool = False,
|
|
110
|
+
) -> None:
|
|
111
|
+
super().__init__()
|
|
112
|
+
|
|
113
|
+
self.delim = None
|
|
114
|
+
self.odelim = ' '
|
|
115
|
+
self.negate = negate
|
|
116
|
+
self.pattern = None if pattern is None else re.compile(pattern)
|
|
117
|
+
self.cmd = cmd
|
|
118
|
+
self.strict = strict
|
|
119
|
+
self._compile(have_end_statement)
|
|
120
|
+
|
|
121
|
+
@classmethod
|
|
122
|
+
def from_options(cls, options: ta.Any, arg: str) -> 'Action':
|
|
123
|
+
negate, pattern, cmd = Action._parse_command(arg)
|
|
124
|
+
return cls(
|
|
125
|
+
pattern=pattern,
|
|
126
|
+
cmd=cmd,
|
|
127
|
+
have_end_statement=(options.end is not None),
|
|
128
|
+
negate=negate,
|
|
129
|
+
strict=options.strict,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def _compile(self, have_end_statement: bool) -> None:
|
|
133
|
+
if not self.cmd:
|
|
134
|
+
if have_end_statement:
|
|
135
|
+
self.cmd = 't += line'
|
|
136
|
+
else:
|
|
137
|
+
self.cmd = 'l'
|
|
138
|
+
self._codeobj = compile_command(self.cmd)
|
|
139
|
+
|
|
140
|
+
def apply(self, context: 'Context', line: str) -> ta.Any:
|
|
141
|
+
"""
|
|
142
|
+
Apply action to line.
|
|
143
|
+
|
|
144
|
+
:return: Line text or None.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
match = self._match(line)
|
|
148
|
+
if match is None:
|
|
149
|
+
return None
|
|
150
|
+
context['m'] = match
|
|
151
|
+
try:
|
|
152
|
+
return eval_in_context(self._codeobj, context)
|
|
153
|
+
except Exception: # noqa
|
|
154
|
+
if not self.strict:
|
|
155
|
+
return None
|
|
156
|
+
raise
|
|
157
|
+
|
|
158
|
+
def _match(self, line: str) -> ta.Any:
|
|
159
|
+
if self.pattern is None:
|
|
160
|
+
return self.negate
|
|
161
|
+
match = self.pattern.search(line)
|
|
162
|
+
if match is not None:
|
|
163
|
+
return None if self.negate else match.groups()
|
|
164
|
+
elif self.negate:
|
|
165
|
+
return ()
|
|
166
|
+
else:
|
|
167
|
+
return None
|
|
168
|
+
|
|
169
|
+
@staticmethod
|
|
170
|
+
def _parse_command(arg: str) -> tuple[bool, str | None, str]:
|
|
171
|
+
match = re.match(r'(?ms)(?:(!)?/((?:\\.|[^/])+)/)?(.*)', arg)
|
|
172
|
+
negate, pattern, cmd = check.not_none(match).groups()
|
|
173
|
+
cmd = cmd.strip()
|
|
174
|
+
negate = bool(negate)
|
|
175
|
+
return negate, pattern, cmd
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class Context(dict):
|
|
179
|
+
def apply(
|
|
180
|
+
self,
|
|
181
|
+
numz: int,
|
|
182
|
+
line: str,
|
|
183
|
+
headers: ta.Sequence[str] | None = None,
|
|
184
|
+
) -> None:
|
|
185
|
+
l = line.rstrip()
|
|
186
|
+
f = l.split(self.delim)
|
|
187
|
+
self.update(line=line, l=l, n=numz + 1, f=f, nf=len(f))
|
|
188
|
+
if headers:
|
|
189
|
+
self.update(itertools.zip_longest(headers, f))
|
|
190
|
+
|
|
191
|
+
delim: str | None
|
|
192
|
+
odelim: str
|
|
193
|
+
line_separator: str
|
|
194
|
+
|
|
195
|
+
@classmethod
|
|
196
|
+
def from_options(
|
|
197
|
+
cls,
|
|
198
|
+
options: ta.Any,
|
|
199
|
+
modules: ta.Sequence[str],
|
|
200
|
+
) -> 'Context':
|
|
201
|
+
self = cls()
|
|
202
|
+
self['t'] = ''
|
|
203
|
+
self['m'] = ()
|
|
204
|
+
if options.imports:
|
|
205
|
+
for imp in options.imports.split(','):
|
|
206
|
+
mod = __import__(imp.strip(), fromlist=['.'])
|
|
207
|
+
self.update((k, v) for k, v in inspect.getmembers(mod) if k[0] != '_')
|
|
208
|
+
|
|
209
|
+
self.delim = codecs.decode(options.delim, STRING_ESCAPE) if options.delim else None
|
|
210
|
+
self.odelim = codecs.decode(options.delim_out, STRING_ESCAPE)
|
|
211
|
+
self.line_separator = codecs.decode(options.line_separator, STRING_ESCAPE)
|
|
212
|
+
|
|
213
|
+
for m in modules:
|
|
214
|
+
try:
|
|
215
|
+
key = m.split('.')[0]
|
|
216
|
+
self[key] = __import__(m)
|
|
217
|
+
except Exception: # noqa
|
|
218
|
+
pass
|
|
219
|
+
return self
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def process(
|
|
223
|
+
context: Context,
|
|
224
|
+
input: ta.TextIO, # noqa
|
|
225
|
+
output: ta.TextIO,
|
|
226
|
+
begin_statement: str | None,
|
|
227
|
+
actions: ta.Sequence[Action],
|
|
228
|
+
end_statement: str | None,
|
|
229
|
+
strict: bool,
|
|
230
|
+
header: bool,
|
|
231
|
+
):
|
|
232
|
+
"""Process a stream."""
|
|
233
|
+
|
|
234
|
+
# Override "print"
|
|
235
|
+
old_stdout = sys.stdout
|
|
236
|
+
sys.stdout = output
|
|
237
|
+
write = output.write
|
|
238
|
+
|
|
239
|
+
def write_result(result, when_true=None):
|
|
240
|
+
if result is True:
|
|
241
|
+
result = when_true
|
|
242
|
+
elif isinstance(result, (list, tuple)):
|
|
243
|
+
result = context.odelim.join(map(str, result))
|
|
244
|
+
|
|
245
|
+
if result is not None and result is not False:
|
|
246
|
+
result = str(result)
|
|
247
|
+
if not result.endswith(context.line_separator):
|
|
248
|
+
result = result.rstrip('\n') + context.line_separator
|
|
249
|
+
write(result)
|
|
250
|
+
|
|
251
|
+
try:
|
|
252
|
+
headers = None
|
|
253
|
+
if header:
|
|
254
|
+
line = input.readline()
|
|
255
|
+
context.apply(-1, line)
|
|
256
|
+
headers = context['f']
|
|
257
|
+
|
|
258
|
+
if begin_statement:
|
|
259
|
+
write_result(eval_in_context(compile_command(begin_statement), context))
|
|
260
|
+
|
|
261
|
+
for numz, line in enumerate(input):
|
|
262
|
+
context.apply(numz, line, headers=headers)
|
|
263
|
+
for action in actions:
|
|
264
|
+
write_result(action.apply(context, line), when_true=line)
|
|
265
|
+
|
|
266
|
+
if end_statement:
|
|
267
|
+
write_result(eval_in_context(compile_command(end_statement), context))
|
|
268
|
+
|
|
269
|
+
finally:
|
|
270
|
+
sys.stdout = old_stdout
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def parse_commandline(argv: ta.Sequence[str]) -> tuple[ta.Any, ta.Sequence[str]]:
|
|
274
|
+
parser = argparse.ArgumentParser()
|
|
275
|
+
# parser.set_usage(__doc__.strip())
|
|
276
|
+
parser.add_argument(
|
|
277
|
+
'-I',
|
|
278
|
+
'--in_place',
|
|
279
|
+
dest='in_place',
|
|
280
|
+
help='modify given input file in-place',
|
|
281
|
+
metavar='<filename>',
|
|
282
|
+
)
|
|
283
|
+
parser.add_argument(
|
|
284
|
+
'-i',
|
|
285
|
+
'--import',
|
|
286
|
+
dest='imports',
|
|
287
|
+
help='comma-separated list of modules to "from x import *" from',
|
|
288
|
+
metavar='<modules>',
|
|
289
|
+
)
|
|
290
|
+
parser.add_argument(
|
|
291
|
+
'-F',
|
|
292
|
+
dest='delim',
|
|
293
|
+
help='input delimiter',
|
|
294
|
+
metavar='<delim>',
|
|
295
|
+
default=None,
|
|
296
|
+
)
|
|
297
|
+
parser.add_argument(
|
|
298
|
+
'-O',
|
|
299
|
+
dest='delim_out',
|
|
300
|
+
help='output delimiter',
|
|
301
|
+
metavar='<delim>',
|
|
302
|
+
default=' ',
|
|
303
|
+
)
|
|
304
|
+
parser.add_argument(
|
|
305
|
+
'-L',
|
|
306
|
+
dest='line_separator',
|
|
307
|
+
help='output line separator',
|
|
308
|
+
metavar='<delim>',
|
|
309
|
+
default='\n',
|
|
310
|
+
)
|
|
311
|
+
parser.add_argument(
|
|
312
|
+
'-B',
|
|
313
|
+
'--begin',
|
|
314
|
+
help='begin statement',
|
|
315
|
+
metavar='<statement>',
|
|
316
|
+
)
|
|
317
|
+
parser.add_argument(
|
|
318
|
+
'-E',
|
|
319
|
+
'--end',
|
|
320
|
+
help='end statement',
|
|
321
|
+
metavar='<statement>',
|
|
322
|
+
)
|
|
323
|
+
parser.add_argument(
|
|
324
|
+
'-s',
|
|
325
|
+
'--statement',
|
|
326
|
+
action='store_true',
|
|
327
|
+
help='DEPRECATED. retained for backward compatibility',
|
|
328
|
+
)
|
|
329
|
+
parser.add_argument(
|
|
330
|
+
'-H',
|
|
331
|
+
'--header',
|
|
332
|
+
action='store_true',
|
|
333
|
+
help='use first row as field variable names in subsequent rows',
|
|
334
|
+
)
|
|
335
|
+
parser.add_argument(
|
|
336
|
+
'--strict',
|
|
337
|
+
action='store_true',
|
|
338
|
+
help='abort on exceptions',
|
|
339
|
+
)
|
|
340
|
+
return parser.parse_known_args(argv[1:])
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
# For integration tests.
|
|
344
|
+
def run(
|
|
345
|
+
argv: ta.Sequence[str],
|
|
346
|
+
input: ta.TextIO, # noqa
|
|
347
|
+
output: ta.TextIO,
|
|
348
|
+
) -> None:
|
|
349
|
+
options, args = parse_commandline(argv)
|
|
350
|
+
|
|
351
|
+
with contextlib.ExitStack() as es:
|
|
352
|
+
if options.in_place:
|
|
353
|
+
os.rename(options.in_place, options.in_place + '~')
|
|
354
|
+
input = es.enter_context(open(options.in_place + '~')) # noqa
|
|
355
|
+
output = es.enter_context(open(options.in_place, 'w'))
|
|
356
|
+
|
|
357
|
+
# Auto-import. This is not smart.
|
|
358
|
+
all_text = ' '.join([(options.begin or ''), ' '.join(args), (options.end or '')])
|
|
359
|
+
modules = re.findall(r'([\w.]+)+(?=\.\w+)\b', all_text)
|
|
360
|
+
|
|
361
|
+
context = Context.from_options(options, modules)
|
|
362
|
+
actions = [Action.from_options(options, arg) for arg in args]
|
|
363
|
+
if not actions:
|
|
364
|
+
actions = [Action.from_options(options, '')]
|
|
365
|
+
|
|
366
|
+
process(
|
|
367
|
+
context,
|
|
368
|
+
input,
|
|
369
|
+
output,
|
|
370
|
+
options.begin,
|
|
371
|
+
actions,
|
|
372
|
+
options.end,
|
|
373
|
+
options.strict,
|
|
374
|
+
options.header,
|
|
375
|
+
)
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def main() -> None:
|
|
379
|
+
try:
|
|
380
|
+
run(sys.argv, sys.stdin, sys.stdout)
|
|
381
|
+
except OSError as e:
|
|
382
|
+
# Workaround for close failed in file object destructor: sys.excepthook is missing lost sys.stderr
|
|
383
|
+
# http://stackoverflow.com/questions/7955138/addressing-sys-excepthook-error-in-bash-script
|
|
384
|
+
sys.stderr.write(str(e) + '\n')
|
|
385
|
+
sys.exit(1)
|
|
386
|
+
except KeyboardInterrupt:
|
|
387
|
+
sys.exit(1)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
# @omlish-manifest
|
|
391
|
+
_CLI_MODULE = CliModule('pawk', __name__)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
if __name__ == '__main__':
|
|
395
|
+
main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev98
|
|
4
4
|
Summary: omdev
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -12,13 +12,14 @@ 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.dev98
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: black ~=24.10 ; extra == 'all'
|
|
18
18
|
Requires-Dist: pycparser ~=2.22 ; extra == 'all'
|
|
19
|
-
Requires-Dist: cffi ~=1.17 ; extra == 'all'
|
|
20
19
|
Requires-Dist: pcpp ~=1.30 ; extra == 'all'
|
|
20
|
+
Requires-Dist: cffi ~=1.17 ; extra == 'all'
|
|
21
21
|
Requires-Dist: docutils ~=0.21 ; extra == 'all'
|
|
22
|
+
Requires-Dist: markdown ~=3.7 ; extra == 'all'
|
|
22
23
|
Requires-Dist: mypy ~=1.11 ; extra == 'all'
|
|
23
24
|
Requires-Dist: gprof2dot ~=2024.6 ; extra == 'all'
|
|
24
25
|
Requires-Dist: prompt-toolkit ~=3.0 ; extra == 'all'
|
|
@@ -28,10 +29,11 @@ Provides-Extra: black
|
|
|
28
29
|
Requires-Dist: black ~=24.10 ; extra == 'black'
|
|
29
30
|
Provides-Extra: c
|
|
30
31
|
Requires-Dist: pycparser ~=2.22 ; extra == 'c'
|
|
31
|
-
Requires-Dist: cffi ~=1.17 ; extra == 'c'
|
|
32
32
|
Requires-Dist: pcpp ~=1.30 ; extra == 'c'
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
Requires-Dist: cffi ~=1.17 ; extra == 'c'
|
|
34
|
+
Provides-Extra: doc
|
|
35
|
+
Requires-Dist: docutils ~=0.21 ; extra == 'doc'
|
|
36
|
+
Requires-Dist: markdown ~=3.7 ; extra == 'doc'
|
|
35
37
|
Provides-Extra: mypy
|
|
36
38
|
Requires-Dist: mypy ~=1.11 ; extra == 'mypy'
|
|
37
39
|
Provides-Extra: prof
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
omdev/.manifests.json,sha256=
|
|
2
|
-
omdev/__about__.py,sha256=
|
|
1
|
+
omdev/.manifests.json,sha256=EyJdfAeMmdF7DSbwubowYqeoe_nnLE5-8VdZh0UuK7w,6781
|
|
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
|
|
@@ -121,17 +121,20 @@ omdev/toml/parser.py,sha256=84bn09uhYHwQGyfww6Rw6y1RxPAE_HDltODOSakcqDM,29186
|
|
|
121
121
|
omdev/toml/writer.py,sha256=lk3on3YXVbWuLJa-xsOzOhs1bBAT1vXqw4mBbluZl_w,3040
|
|
122
122
|
omdev/tools/__init__.py,sha256=iVJAOQ0viGTQOm0DLX4uZLro-9jOioYJGLg9s0kDx1A,78
|
|
123
123
|
omdev/tools/dockertools.py,sha256=k2BrVvFYwyGov064CPHd_HWo9aqR1zHc2UeEsVwPth4,6827
|
|
124
|
+
omdev/tools/doctools.py,sha256=mv9XfitzqXl3vFHSenv01xHCxWf8g03rUAb_sqoty98,2556
|
|
124
125
|
omdev/tools/gittools.py,sha256=1Oa2AgdZIJZ2eusso9yFzkd9zLWH3d4lTiVFzwg0uDM,3808
|
|
125
126
|
omdev/tools/importscan.py,sha256=QeGjR3UGcuuuDUiisFuAXWHlcKJScGxGEcU6tfOh2CM,4069
|
|
126
127
|
omdev/tools/mkrelimp.py,sha256=wsJAjTIf3nqcSfnT9TkDpS1VUOoM9W2Az5tZdWuzyLM,4054
|
|
127
128
|
omdev/tools/nbtools.py,sha256=M8Xi_gfZdlahnyFLtp0RBgYZPSHWQStMMDYZc71Zync,3494
|
|
128
129
|
omdev/tools/piptools.py,sha256=-jR5q3w4sHqntxCLExFCBNIARB788FUsAbJ62PK2sBU,2774
|
|
129
130
|
omdev/tools/proftools.py,sha256=8ZU9x_Dq8eT2ZFwU9sJpDIvxcIn9qBc8y2ELKPb5e5M,1382
|
|
130
|
-
omdev/tools/rsttool.py,sha256=suwsfseUf8GH8rYmYygTUdif-Jk_bX1g9fYRLXaKkmM,1340
|
|
131
131
|
omdev/tools/sqlrepl.py,sha256=tmFZh80-xsGM62dyQ7_UGLebChrj7IHbIPYBWDJMgVk,5741
|
|
132
|
-
omdev
|
|
133
|
-
omdev
|
|
134
|
-
omdev
|
|
135
|
-
omdev-0.0.0.
|
|
136
|
-
omdev-0.0.0.
|
|
137
|
-
omdev-0.0.0.
|
|
132
|
+
omdev/tools/pawk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
133
|
+
omdev/tools/pawk/__main__.py,sha256=VCqeRVnqT1RPEoIrqHFSu4PXVMg4YEgF4qCQm90-eRI,66
|
|
134
|
+
omdev/tools/pawk/pawk.py,sha256=Eckymn22GfychCQcQi96BFqRo_LmiJ-EPhC8TTUJdB4,11446
|
|
135
|
+
omdev-0.0.0.dev98.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
|
136
|
+
omdev-0.0.0.dev98.dist-info/METADATA,sha256=iTM12k8q9OTLBHP1Ed0J-xxukNVE65PUwPPCoOOOV9M,1702
|
|
137
|
+
omdev-0.0.0.dev98.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
138
|
+
omdev-0.0.0.dev98.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
|
|
139
|
+
omdev-0.0.0.dev98.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
|
140
|
+
omdev-0.0.0.dev98.dist-info/RECORD,,
|
omdev/tools/rsttool.py
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
TODO:
|
|
3
|
-
- omdev/rst.py *and* rsttool.py, when we want extracted helpers
|
|
4
|
-
"""
|
|
5
|
-
import contextlib
|
|
6
|
-
import io
|
|
7
|
-
import sys
|
|
8
|
-
|
|
9
|
-
import docutils.core
|
|
10
|
-
|
|
11
|
-
from omlish import argparse as ap
|
|
12
|
-
|
|
13
|
-
from ..cli import CliModule
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def rst2html(rst, report_level=None):
|
|
17
|
-
kwargs = {
|
|
18
|
-
'writer_name': 'html',
|
|
19
|
-
'settings_overrides': {
|
|
20
|
-
'_disable_config': True,
|
|
21
|
-
'report_level': int(report_level) if report_level else 0,
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
target = io.StringIO()
|
|
26
|
-
with contextlib.redirect_stderr(target):
|
|
27
|
-
parts = docutils.core.publish_parts(rst, **kwargs) # type: ignore
|
|
28
|
-
html = parts['html_body']
|
|
29
|
-
warning = target.getvalue().strip()
|
|
30
|
-
return html, warning
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class Cli(ap.Cli):
|
|
34
|
-
@ap.command(
|
|
35
|
-
ap.arg('input-file', nargs='?'),
|
|
36
|
-
ap.arg('--report-level', type=int),
|
|
37
|
-
)
|
|
38
|
-
def html(self) -> None:
|
|
39
|
-
if self.args.input_file is not None:
|
|
40
|
-
with open(self.args.input_file) as f:
|
|
41
|
-
src = f.read()
|
|
42
|
-
else:
|
|
43
|
-
src = sys.stdin.read()
|
|
44
|
-
|
|
45
|
-
html, warning = rst2html(
|
|
46
|
-
src,
|
|
47
|
-
report_level=self.args.report_level,
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
if warning:
|
|
51
|
-
sys.stderr.write(warning)
|
|
52
|
-
print(html)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
# @omlish-manifest
|
|
56
|
-
_CLI_MODULE = CliModule('rst', __name__)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if __name__ == '__main__':
|
|
60
|
-
Cli().call_and_exit()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|