omdev 0.0.0.dev305__py3-none-any.whl → 0.0.0.dev306__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-0.0.0.dev305.dist-info → omdev-0.0.0.dev306.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev306.dist-info}/RECORD +12 -7
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev306.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev306.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev306.dist-info}/licenses/LICENSE +0 -0
- {omdev-0.0.0.dev305.dist-info → omdev-0.0.0.dev306.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
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: omdev
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev306
|
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.dev306
|
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
|
@@ -277,9 +282,9 @@ omdev/tools/json/rendering.py,sha256=tMcjOW5edfozcMSTxxvF7WVTsbYLoe9bCKFh50qyaGw
|
|
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.dev306.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
286
|
+
omdev-0.0.0.dev306.dist-info/METADATA,sha256=fiHu3utIwUEtAURhnU-PYrXupHEa1PloV_2uGgqozvk,1674
|
287
|
+
omdev-0.0.0.dev306.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
|
288
|
+
omdev-0.0.0.dev306.dist-info/entry_points.txt,sha256=dHLXFmq5D9B8qUyhRtFqTGWGxlbx3t5ejedjrnXNYLU,33
|
289
|
+
omdev-0.0.0.dev306.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
290
|
+
omdev-0.0.0.dev306.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|