omdev 0.0.0.dev305__py3-none-any.whl → 0.0.0.dev307__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 +12 -0
- omdev/cmdlog/__init__.py +7 -0
- omdev/cmdlog/__main__.py +11 -0
- omdev/cmdlog/_cmdlog.py +73 -0
- omdev/cmdlog/cli.py +67 -0
- omdev/cmdlog/cmdlog.py +86 -0
- omdev/tools/json/parsing.py +4 -4
- omdev/tools/json/rendering.py +3 -3
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev307.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev307.dist-info}/RECORD +14 -9
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev307.dist-info}/WHEEL +1 -1
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev307.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev307.dist-info}/licenses/LICENSE +0 -0
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev307.dist-info}/top_level.txt +0 -0
omdev/.manifests.json
CHANGED
@@ -47,6 +47,18 @@
|
|
47
47
|
}
|
48
48
|
}
|
49
49
|
},
|
50
|
+
{
|
51
|
+
"module": ".cmdlog.__main__",
|
52
|
+
"attr": "_CLI_MODULE",
|
53
|
+
"file": "omdev/cmdlog/__main__.py",
|
54
|
+
"line": 4,
|
55
|
+
"value": {
|
56
|
+
"$.cli.types.CliModule": {
|
57
|
+
"cmd_name": "cmdlog",
|
58
|
+
"mod_name": "omdev.cmdlog.__main__"
|
59
|
+
}
|
60
|
+
}
|
61
|
+
},
|
50
62
|
{
|
51
63
|
"module": ".imgur",
|
52
64
|
"attr": "_FOO_CLI_MODULE",
|
omdev/cmdlog/__init__.py
ADDED
omdev/cmdlog/__main__.py
ADDED
omdev/cmdlog/_cmdlog.py
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# NOTE: not '@omlish-lite' due to root level __init__ imports, but effectively lite.
|
2
|
+
import dataclasses as dc
|
3
|
+
import fcntl
|
4
|
+
import json
|
5
|
+
import os.path
|
6
|
+
import shutil
|
7
|
+
import sys
|
8
|
+
import time
|
9
|
+
import typing as ta
|
10
|
+
|
11
|
+
|
12
|
+
##
|
13
|
+
|
14
|
+
|
15
|
+
@dc.dataclass(frozen=True)
|
16
|
+
class CmdLogEntry:
|
17
|
+
cmd: str
|
18
|
+
pid: int
|
19
|
+
ppid: int
|
20
|
+
time: float
|
21
|
+
cwd: str
|
22
|
+
|
23
|
+
argv: ta.Sequence[str]
|
24
|
+
env: ta.Mapping[str, str]
|
25
|
+
|
26
|
+
|
27
|
+
##
|
28
|
+
|
29
|
+
|
30
|
+
LOG_FILE_ENV_VAR: str = '_CMD_LOG_FILE'
|
31
|
+
|
32
|
+
|
33
|
+
def _main() -> None:
|
34
|
+
cmd = os.path.basename(sys.argv[0])
|
35
|
+
|
36
|
+
entry = CmdLogEntry(
|
37
|
+
cmd=cmd,
|
38
|
+
pid=os.getpid(),
|
39
|
+
ppid=os.getppid(),
|
40
|
+
time=time.time(),
|
41
|
+
cwd=os.getcwd(),
|
42
|
+
|
43
|
+
argv=sys.argv,
|
44
|
+
env=dict(os.environ),
|
45
|
+
)
|
46
|
+
|
47
|
+
entry_json = json.dumps(dc.asdict(entry), separators=(',', ':'), indent=None)
|
48
|
+
|
49
|
+
log_file = os.environ[LOG_FILE_ENV_VAR]
|
50
|
+
fd = os.open(log_file, os.O_WRONLY | os.O_CREAT | os.O_APPEND)
|
51
|
+
fcntl.flock(fd, fcntl.LOCK_EX)
|
52
|
+
os.write(fd, entry_json.encode() + b'\n')
|
53
|
+
os.close(fd)
|
54
|
+
|
55
|
+
u_ap = None # type: str | None
|
56
|
+
self_ap = os.path.abspath(os.path.realpath(__file__))
|
57
|
+
for p in os.environ.get('PATH', '').split(os.pathsep):
|
58
|
+
if (p_cmd := shutil.which(cmd, path=p)) is None:
|
59
|
+
continue
|
60
|
+
p_ap = os.path.abspath(os.path.realpath(p_cmd))
|
61
|
+
if p_ap == self_ap:
|
62
|
+
continue
|
63
|
+
u_ap = p_ap
|
64
|
+
break
|
65
|
+
|
66
|
+
if u_ap is None:
|
67
|
+
raise FileNotFoundError(cmd)
|
68
|
+
|
69
|
+
os.execl(u_ap, cmd, *sys.argv[1:])
|
70
|
+
|
71
|
+
|
72
|
+
if __name__ == '__main__':
|
73
|
+
_main()
|
omdev/cmdlog/cli.py
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
import argparse
|
2
|
+
import os.path
|
3
|
+
import subprocess
|
4
|
+
import sys
|
5
|
+
import typing as ta
|
6
|
+
|
7
|
+
from omlish.formats import json
|
8
|
+
|
9
|
+
from .cmdlog import CmdLog
|
10
|
+
|
11
|
+
|
12
|
+
##
|
13
|
+
|
14
|
+
|
15
|
+
DEFAULT_PROXIED_CMDS: ta.Collection[str] = [
|
16
|
+
'ar',
|
17
|
+
'as',
|
18
|
+
'clang',
|
19
|
+
'clang++',
|
20
|
+
'g++',
|
21
|
+
'gcc',
|
22
|
+
'ld',
|
23
|
+
'lld',
|
24
|
+
'make',
|
25
|
+
]
|
26
|
+
|
27
|
+
|
28
|
+
def _main() -> None:
|
29
|
+
parser = argparse.ArgumentParser()
|
30
|
+
parser.add_argument('cmd', nargs=argparse.REMAINDER)
|
31
|
+
parser.add_argument('-l', '--log-file')
|
32
|
+
parser.add_argument('-P', '--print', action='store_true')
|
33
|
+
parser.add_argument('-p', '--proxy', action='append')
|
34
|
+
args = parser.parse_args()
|
35
|
+
|
36
|
+
if not args.cmd:
|
37
|
+
parser.error('Must specify cmd')
|
38
|
+
raise RuntimeError # noqa
|
39
|
+
|
40
|
+
exec_cmd, *exec_argv = args.cmd
|
41
|
+
|
42
|
+
#
|
43
|
+
|
44
|
+
cl = CmdLog(
|
45
|
+
args.proxy if args.proxy is not None else DEFAULT_PROXIED_CMDS,
|
46
|
+
log_file=os.path.abspath(args.log_file) if args.log_file is not None else None,
|
47
|
+
)
|
48
|
+
cl.exe()
|
49
|
+
cl.proxy_cmds()
|
50
|
+
|
51
|
+
rc = subprocess.call(
|
52
|
+
[exec_cmd, *exec_argv],
|
53
|
+
env=cl.child_env(),
|
54
|
+
)
|
55
|
+
|
56
|
+
if args.log_file is None or args.print:
|
57
|
+
if os.path.exists(cl.log_file()):
|
58
|
+
with open(cl.log_file()) as f:
|
59
|
+
log_lines = f.readlines()
|
60
|
+
entry_dcts = [json.loads(sl) for l in log_lines if (sl := l.strip())]
|
61
|
+
print(json.dumps_compact(entry_dcts))
|
62
|
+
|
63
|
+
sys.exit(rc)
|
64
|
+
|
65
|
+
|
66
|
+
if __name__ == '__main__':
|
67
|
+
_main()
|
omdev/cmdlog/cmdlog.py
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
import inspect
|
2
|
+
import os.path
|
3
|
+
import sys
|
4
|
+
import tempfile
|
5
|
+
import typing as ta
|
6
|
+
|
7
|
+
from omlish import cached
|
8
|
+
from omlish import check
|
9
|
+
|
10
|
+
from . import _cmdlog
|
11
|
+
|
12
|
+
|
13
|
+
##
|
14
|
+
|
15
|
+
|
16
|
+
class CmdLog:
|
17
|
+
def __init__(
|
18
|
+
self,
|
19
|
+
proxied_cmds: ta.Iterable[str],
|
20
|
+
*,
|
21
|
+
tmp_dir: str | None = None,
|
22
|
+
log_file: str | None = None,
|
23
|
+
exe_name: str | None = None,
|
24
|
+
) -> None:
|
25
|
+
super().__init__()
|
26
|
+
|
27
|
+
self._proxied_cmds = {
|
28
|
+
check.non_empty_str(c)
|
29
|
+
for c in check.not_isinstance(proxied_cmds, str)
|
30
|
+
}
|
31
|
+
|
32
|
+
self._given_tmp_dir = tmp_dir
|
33
|
+
self._given_log_file = log_file
|
34
|
+
self._exe_name = check.non_empty_str(exe_name) if exe_name is not None else self.DEFAULT_EXE_NAME
|
35
|
+
|
36
|
+
#
|
37
|
+
|
38
|
+
@cached.function
|
39
|
+
def tmp_dir(self) -> str:
|
40
|
+
if (gtd := self._given_tmp_dir) is not None:
|
41
|
+
return gtd
|
42
|
+
return tempfile.mkdtemp()
|
43
|
+
|
44
|
+
#
|
45
|
+
|
46
|
+
DEFAULT_LOG_FILE_NAME: ta.ClassVar[str] = '_cmdlog.jsonl'
|
47
|
+
|
48
|
+
@cached.function
|
49
|
+
def log_file(self) -> str:
|
50
|
+
if (glf := self._given_log_file) is not None:
|
51
|
+
return glf
|
52
|
+
return os.path.join(self.tmp_dir(), self.DEFAULT_LOG_FILE_NAME)
|
53
|
+
|
54
|
+
#
|
55
|
+
|
56
|
+
DEFAULT_EXE_NAME: ta.ClassVar[str] = '_cmdlog.py'
|
57
|
+
|
58
|
+
@cached.function
|
59
|
+
def exe(self) -> str:
|
60
|
+
src = '\n'.join([
|
61
|
+
f'#!{os.path.abspath(sys.executable)}',
|
62
|
+
inspect.getsource(_cmdlog),
|
63
|
+
])
|
64
|
+
|
65
|
+
exe = os.path.join(self.tmp_dir(), self._exe_name)
|
66
|
+
|
67
|
+
with open(exe, 'w') as f:
|
68
|
+
f.write(src)
|
69
|
+
|
70
|
+
os.chmod(exe, 0o550) # noqa
|
71
|
+
|
72
|
+
return exe
|
73
|
+
|
74
|
+
#
|
75
|
+
|
76
|
+
def proxy_cmds(self) -> None:
|
77
|
+
for p_c in self._proxied_cmds:
|
78
|
+
os.symlink(self._exe_name, os.path.join(self.tmp_dir(), p_c))
|
79
|
+
|
80
|
+
#
|
81
|
+
|
82
|
+
def child_env(self) -> ta.Mapping[str, str]:
|
83
|
+
return {
|
84
|
+
_cmdlog.LOG_FILE_ENV_VAR: self.log_file(),
|
85
|
+
'PATH': os.pathsep.join([self.tmp_dir(), os.environ['PATH']]),
|
86
|
+
}
|
omdev/tools/json/parsing.py
CHANGED
@@ -4,10 +4,10 @@ import typing as ta
|
|
4
4
|
|
5
5
|
from omlish import check
|
6
6
|
from omlish import lang
|
7
|
-
from omlish.formats.json.stream.
|
8
|
-
from omlish.formats.json.stream.
|
9
|
-
from omlish.formats.json.stream.
|
10
|
-
from omlish.formats.json.stream.
|
7
|
+
from omlish.formats.json.stream.building import JsonObjectBuilder
|
8
|
+
from omlish.formats.json.stream.lexing import JsonStreamLexer
|
9
|
+
from omlish.formats.json.stream.parsing import JsonStreamParser
|
10
|
+
from omlish.formats.json.stream.parsing import JsonStreamParserEvent
|
11
11
|
from omlish.io.buffers import DelimitingBuffer
|
12
12
|
|
13
13
|
from .formats import Format
|
omdev/tools/json/rendering.py
CHANGED
@@ -3,9 +3,9 @@ import json
|
|
3
3
|
import typing as ta
|
4
4
|
|
5
5
|
from omlish import lang
|
6
|
-
from omlish.formats.json.
|
7
|
-
from omlish.formats.json.stream.
|
8
|
-
from omlish.formats.json.stream.
|
6
|
+
from omlish.formats.json.rendering import JsonRenderer
|
7
|
+
from omlish.formats.json.stream.parsing import JsonStreamParserEvent
|
8
|
+
from omlish.formats.json.stream.rendering import StreamJsonRenderer
|
9
9
|
from omlish.term import codes as tc
|
10
10
|
|
11
11
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: omdev
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev307
|
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.dev307
|
16
16
|
Provides-Extra: all
|
17
17
|
Requires-Dist: black~=25.1; extra == "all"
|
18
18
|
Requires-Dist: pycparser~=2.22; extra == "all"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
omdev/.manifests.json,sha256=
|
1
|
+
omdev/.manifests.json,sha256=M4fAkk-dlyvEzkya4HhuU9Hb9QpVYgp1AgJB6eXgmuI,10982
|
2
2
|
omdev/__about__.py,sha256=16xa_1BdZanTpZbkjAOQ11_x5kJcb1m1tKdvb06J7VI,1202
|
3
3
|
omdev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
4
|
omdev/cmake.py,sha256=9rfSvFHPmKDj9ngvfDB2vK8O-xO_ZwUm7hMKLWA-yOw,4578
|
@@ -114,6 +114,11 @@ omdev/clipboard/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
114
114
|
omdev/clipboard/clipboard.py,sha256=9HFpcijpn0XDTI89ZRm2WA1G7O4HsTdVXZHqMULu3N0,1630
|
115
115
|
omdev/clipboard/darwin_cf.py,sha256=1gFkxEN6w9HTcA0eiWw14oL7xjC1wSmY_hUrRr5OU4Y,7687
|
116
116
|
omdev/clipboard/linux_x11.py,sha256=oa-mxMRNaZJOdBAZ8Nki-CAGIb63X8OFUTXKjmiwfSo,6718
|
117
|
+
omdev/cmdlog/__init__.py,sha256=026o1leEXU5bsNZPpEOeLf_Ml1wQXzbiFDmlcKHX-Nw,95
|
118
|
+
omdev/cmdlog/__main__.py,sha256=m31h6AcI9rjRNVeBGoLcR-5pWp-yS8LXCorf4iBhX9w,162
|
119
|
+
omdev/cmdlog/_cmdlog.py,sha256=9VSuUKXBMBHAH3OfBCeqp16YPddPT9Man2zDHgzzCtI,1507
|
120
|
+
omdev/cmdlog/cli.py,sha256=9AJC3xeQA-2pdmTnsjo__9WRAML1jpEJUJMn6qQQpJA,1427
|
121
|
+
omdev/cmdlog/cmdlog.py,sha256=MJqfCG7sVWjSK_i1shD7cgWpFZXZkPvGhGEh-yd6iwM,1982
|
117
122
|
omdev/dataserver/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
118
123
|
omdev/dataserver/handlers.py,sha256=rCptrmV2RnutmGE5MAgjLDYW1QncqsSHhyRBL4H5bsg,5440
|
119
124
|
omdev/dataserver/http.py,sha256=SozI4233RP40m2EX45HtBvdIj-CBFlhHH7ekIbMir-Q,1724
|
@@ -271,15 +276,15 @@ omdev/tools/json/__main__.py,sha256=wqpkN_NsQyNwKW4qjVj8ADJ4_C98KhrFBtE-Z1UamfU,
|
|
271
276
|
omdev/tools/json/cli.py,sha256=WQ8VQ9EkGD6IeIuUci8hLPwfx6y2B8ZzFlTTizwwKXU,9598
|
272
277
|
omdev/tools/json/formats.py,sha256=RgtPdcs294o9n9czjafHppg1iSzD-olsIc3v8ApM9Os,1908
|
273
278
|
omdev/tools/json/io.py,sha256=sfj2hJS9Hy3aUR8a_lLzOrYcmL9fSKyvOHiofdUASsI,1427
|
274
|
-
omdev/tools/json/parsing.py,sha256=
|
279
|
+
omdev/tools/json/parsing.py,sha256=csoTuG2C2AJB7PgG4TKt2XqdiBAQXtpXRWBxoMkk14g,2103
|
275
280
|
omdev/tools/json/processing.py,sha256=iFm5VqaxJ97WHaun2ed7NEjMxhFeJqf28bLNfoDJft0,1209
|
276
|
-
omdev/tools/json/rendering.py,sha256=
|
281
|
+
omdev/tools/json/rendering.py,sha256=3HhdlKSetS6iK1tjF2aILzsl8Mb3D8wW92vYwGpRdVA,2244
|
277
282
|
omdev/tools/pawk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
278
283
|
omdev/tools/pawk/__main__.py,sha256=VCqeRVnqT1RPEoIrqHFSu4PXVMg4YEgF4qCQm90-eRI,66
|
279
284
|
omdev/tools/pawk/pawk.py,sha256=zsEkfQX0jF5bn712uqPAyBSdJt2dno1LH2oeSMNfXQI,11424
|
280
|
-
omdev-0.0.0.
|
281
|
-
omdev-0.0.0.
|
282
|
-
omdev-0.0.0.
|
283
|
-
omdev-0.0.0.
|
284
|
-
omdev-0.0.0.
|
285
|
-
omdev-0.0.0.
|
285
|
+
omdev-0.0.0.dev307.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
286
|
+
omdev-0.0.0.dev307.dist-info/METADATA,sha256=0jPC9ndeHfkBuwMuBVx4376pei_zDitc66yb3610pj0,1674
|
287
|
+
omdev-0.0.0.dev307.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
288
|
+
omdev-0.0.0.dev307.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
|
289
|
+
omdev-0.0.0.dev307.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
290
|
+
omdev-0.0.0.dev307.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|