omdev 0.0.0.dev78__tar.gz → 0.0.0.dev79__tar.gz

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.

Files changed (136) hide show
  1. {omdev-0.0.0.dev78/omdev.egg-info → omdev-0.0.0.dev79}/PKG-INFO +2 -2
  2. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/.manifests.json +6 -6
  3. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/classdot.py +1 -1
  4. omdev-0.0.0.dev79/omdev/cli/main.py +288 -0
  5. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/scripts/execrss.py +1 -1
  6. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/scripts/exectime.py +1 -1
  7. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/scripts/importtrace.py +1 -1
  8. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/importscan.py +1 -1
  9. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/mkrelimp.py +1 -1
  10. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79/omdev.egg-info}/PKG-INFO +2 -2
  11. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev.egg-info/requires.txt +1 -1
  12. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/pyproject.toml +2 -2
  13. omdev-0.0.0.dev78/omdev/cli/main.py +0 -167
  14. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/LICENSE +0 -0
  15. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/MANIFEST.in +0 -0
  16. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/README.rst +0 -0
  17. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/__about__.py +0 -0
  18. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/__init__.py +0 -0
  19. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/amalg/__init__.py +0 -0
  20. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/amalg/__main__.py +0 -0
  21. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/amalg/amalg.py +0 -0
  22. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/antlr/__init__.py +0 -0
  23. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/antlr/_antlr/__init__.py +0 -0
  24. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/antlr/consts.py +0 -0
  25. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/antlr/gen.py +0 -0
  26. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/bracepy.py +0 -0
  27. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/__init__.py +0 -0
  28. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/compute/__init__.py +0 -0
  29. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/compute/cache.py +0 -0
  30. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/compute/contexts.py +0 -0
  31. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/compute/currents.py +0 -0
  32. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/compute/fns.py +0 -0
  33. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/compute/resolvers.py +0 -0
  34. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/compute/storage.py +0 -0
  35. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/compute/types.py +0 -0
  36. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/data/__init__.py +0 -0
  37. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/data/actions.py +0 -0
  38. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/data/cache.py +0 -0
  39. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/data/consts.py +0 -0
  40. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/data/defaults.py +0 -0
  41. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/data/manifests.py +0 -0
  42. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cache/data/specs.py +0 -0
  43. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/__init__.py +0 -0
  44. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_boilerplate.cc +0 -0
  45. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/LICENSE +0 -0
  46. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/__init__.py +0 -0
  47. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/build_ext.py +0 -0
  48. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/compilers/__init__.py +0 -0
  49. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/compilers/ccompiler.py +0 -0
  50. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/compilers/options.py +0 -0
  51. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/compilers/unixccompiler.py +0 -0
  52. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/dir_util.py +0 -0
  53. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/errors.py +0 -0
  54. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/extension.py +0 -0
  55. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/file_util.py +0 -0
  56. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/modified.py +0 -0
  57. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/spawn.py +0 -0
  58. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/sysconfig.py +0 -0
  59. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/util.py +0 -0
  60. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/version.py +0 -0
  61. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/build.py +0 -0
  62. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/cmake.py +0 -0
  63. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/importhook.py +0 -0
  64. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/magic.py +0 -0
  65. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cexts/scan.py +0 -0
  66. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cli/__init__.py +0 -0
  67. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cli/__main__.py +0 -0
  68. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cli/_pathhack.py +0 -0
  69. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cli/clicli.py +0 -0
  70. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cli/install.py +0 -0
  71. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cli/managers.py +0 -0
  72. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cli/types.py +0 -0
  73. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/cmake.py +0 -0
  74. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/findimports.py +0 -0
  75. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/findmagic.py +0 -0
  76. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/git.py +0 -0
  77. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/imgur.py +0 -0
  78. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/__init__.py +0 -0
  79. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/__main__.py +0 -0
  80. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/cli.py +0 -0
  81. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/inspect.py +0 -0
  82. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/providers.py +0 -0
  83. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/pyenv.py +0 -0
  84. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/resolvers.py +0 -0
  85. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/standalone.py +0 -0
  86. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/system.py +0 -0
  87. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/interp/types.py +0 -0
  88. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/manifests/__init__.py +0 -0
  89. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/manifests/build.py +0 -0
  90. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/manifests/load.py +0 -0
  91. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/manifests/types.py +0 -0
  92. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/mypy/__init__.py +0 -0
  93. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/mypy/debug.py +0 -0
  94. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/packaging/__init__.py +0 -0
  95. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/packaging/names.py +0 -0
  96. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/packaging/requires.py +0 -0
  97. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/packaging/specifiers.py +0 -0
  98. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/packaging/versions.py +0 -0
  99. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/precheck/__init__.py +0 -0
  100. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/precheck/__main__.py +0 -0
  101. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/precheck/base.py +0 -0
  102. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/precheck/git.py +0 -0
  103. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/precheck/lite.py +0 -0
  104. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/precheck/precheck.py +0 -0
  105. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/precheck/scripts.py +0 -0
  106. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/pyproject/__init__.py +0 -0
  107. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/pyproject/__main__.py +0 -0
  108. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/pyproject/cexts.py +0 -0
  109. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/pyproject/cli.py +0 -0
  110. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/pyproject/configs.py +0 -0
  111. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/pyproject/pkg.py +0 -0
  112. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/pyproject/reqs.py +0 -0
  113. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/revisions.py +0 -0
  114. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/scripts/__init__.py +0 -0
  115. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/scripts/bumpversion.py +0 -0
  116. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/scripts/interp.py +0 -0
  117. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/scripts/pyproject.py +0 -0
  118. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/secrets.py +0 -0
  119. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tokens.py +0 -0
  120. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/toml/__init__.py +0 -0
  121. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/toml/parser.py +0 -0
  122. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/toml/writer.py +0 -0
  123. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/__init__.py +0 -0
  124. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/dockertools.py +0 -0
  125. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/gittools.py +0 -0
  126. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/nbtools.py +0 -0
  127. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/piptools.py +0 -0
  128. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/proftools.py +0 -0
  129. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/rsttool.py +0 -0
  130. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/tools/sqlrepl.py +0 -0
  131. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev/wheelfile.py +0 -0
  132. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev.egg-info/SOURCES.txt +0 -0
  133. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev.egg-info/dependency_links.txt +0 -0
  134. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev.egg-info/entry_points.txt +0 -0
  135. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/omdev.egg-info/top_level.txt +0 -0
  136. {omdev-0.0.0.dev78 → omdev-0.0.0.dev79}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev78
3
+ Version: 0.0.0.dev79
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.dev78
15
+ Requires-Dist: omlish==0.0.0.dev79
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=24.10; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
@@ -30,7 +30,7 @@
30
30
  "line": 62,
31
31
  "value": {
32
32
  "$.cli.types.CliModule": {
33
- "cmd_name": "classdot",
33
+ "cmd_name": "py/classdot",
34
34
  "mod_name": "omdev.classdot"
35
35
  }
36
36
  }
@@ -102,7 +102,7 @@
102
102
  "line": 11,
103
103
  "value": {
104
104
  "$.cli.types.CliModule": {
105
- "cmd_name": "execrss",
105
+ "cmd_name": "py/execrss",
106
106
  "mod_name": "omdev.scripts.execrss"
107
107
  }
108
108
  }
@@ -114,7 +114,7 @@
114
114
  "line": 7,
115
115
  "value": {
116
116
  "$.cli.types.CliModule": {
117
- "cmd_name": "exectime",
117
+ "cmd_name": "py/exectime",
118
118
  "mod_name": "omdev.scripts.exectime"
119
119
  }
120
120
  }
@@ -126,7 +126,7 @@
126
126
  "line": 481,
127
127
  "value": {
128
128
  "$.cli.types.CliModule": {
129
- "cmd_name": "importtrace",
129
+ "cmd_name": "py/importtrace",
130
130
  "mod_name": "omdev.scripts.importtrace"
131
131
  }
132
132
  }
@@ -162,7 +162,7 @@
162
162
  "line": 166,
163
163
  "value": {
164
164
  "$.cli.types.CliModule": {
165
- "cmd_name": "importscan",
165
+ "cmd_name": "py/importscan",
166
166
  "mod_name": "omdev.tools.importscan"
167
167
  }
168
168
  }
@@ -174,7 +174,7 @@
174
174
  "line": 148,
175
175
  "value": {
176
176
  "$.cli.types.CliModule": {
177
- "cmd_name": "mkrelimp",
177
+ "cmd_name": "py/mkrelimp",
178
178
  "mod_name": "omdev.tools.mkrelimp"
179
179
  }
180
180
  }
@@ -60,7 +60,7 @@ def _main() -> None:
60
60
 
61
61
 
62
62
  # @omlish-manifest
63
- _CLI_MODULE = CliModule('classdot', __name__)
63
+ _CLI_MODULE = CliModule('py/classdot', __name__)
64
64
 
65
65
 
66
66
  if __name__ == '__main__':
@@ -0,0 +1,288 @@
1
+ """
2
+ TODO:
3
+ - py/foo - root command 'py'
4
+ - cache ldr.discover() somehow if in uvx/pipx - very slow
5
+ - <venv-root>/.omdev-cli-manifest-cache.json - {pkg_name: manifests_json}
6
+ - allow manually specifying manifest packages
7
+ """
8
+ import argparse
9
+ import dataclasses as dc
10
+ import os
11
+ import runpy
12
+ import sys
13
+ import typing as ta
14
+
15
+ from omlish import check
16
+ from omlish.lite.cached import cached_nullary
17
+
18
+ from ..manifests.load import ManifestLoader
19
+ from .types import CliCmd
20
+ from .types import CliFunc
21
+ from .types import CliModule
22
+
23
+
24
+ ##
25
+
26
+
27
+ def _post_install(cli_pkg: str) -> None:
28
+ from .managers import setup_install_manager
29
+
30
+ setup_install_manager(cli_pkg)
31
+
32
+
33
+ ##
34
+
35
+
36
+ _CLI_FUNCS: ta.Sequence[CliFunc] = [
37
+ CliFunc('_post_install', _post_install),
38
+ ]
39
+
40
+
41
+ ##
42
+
43
+
44
+ StrTuple: ta.TypeAlias = tuple[str, ...]
45
+ RecStrMap: ta.TypeAlias = ta.Mapping[str, ta.Union[str, 'RecStrMap']]
46
+ RecCmdMap: ta.TypeAlias = ta.Mapping[str, ta.Union[CliCmd, 'RecCmdMap']]
47
+
48
+
49
+ class CliCmdSet:
50
+ def __init__(self, cmds: ta.Iterable[CliCmd]) -> None:
51
+ super().__init__()
52
+
53
+ self._cmds = list(cmds)
54
+
55
+ @dc.dataclass(frozen=True)
56
+ class Entry:
57
+ cmd: CliCmd
58
+
59
+ exec_paths: ta.Sequence[StrTuple] # len > 1, len([0]) > 1
60
+ help_path: StrTuple | None
61
+
62
+ def _make_entry(self, cmd: CliCmd) -> Entry:
63
+ help_path: StrTuple | None
64
+
65
+ if isinstance(cmd.cmd_name, str):
66
+ ns = [cmd.cmd_name]
67
+ else:
68
+ ns = list(cmd.cmd_name)
69
+ exec_paths = [tuple(n.split('/')) for n in ns]
70
+
71
+ if isinstance(cmd.cmd_name, str) and cmd.cmd_name[0] == '_':
72
+ help_path = None
73
+
74
+ elif isinstance(cmd, CliFunc):
75
+ help_path = ('-', *exec_paths[0])
76
+
77
+ elif isinstance(cmd, CliModule):
78
+ help_path = (cmd.mod_name.partition('.')[0], *exec_paths[0])
79
+
80
+ else:
81
+ raise TypeError(cmd)
82
+
83
+ return CliCmdSet.Entry(
84
+ cmd,
85
+
86
+ exec_paths=exec_paths,
87
+ help_path=help_path,
88
+ )
89
+
90
+ @cached_nullary
91
+ def entries(self) -> ta.Sequence[Entry]:
92
+ return [self._make_entry(c) for c in self._cmds]
93
+
94
+ @cached_nullary
95
+ def exec_tree(self) -> RecCmdMap:
96
+ d: dict = {}
97
+ for e in self.entries():
98
+ for ep in e.exec_paths:
99
+ c = d
100
+ for p in ep[:-1]:
101
+ n = c.setdefault(p, {})
102
+ if not isinstance(n, dict):
103
+ raise NameError(e) # noqa
104
+ c = n
105
+
106
+ h = ep[-1]
107
+ if h in c:
108
+ raise NameError(e) # noqa
109
+
110
+ c[h] = e.cmd
111
+
112
+ return d
113
+
114
+ @cached_nullary
115
+ def help_tree(self) -> RecStrMap:
116
+ d: dict = {}
117
+ for e in self.entries():
118
+ if not e.help_path:
119
+ continue
120
+
121
+ c = d
122
+ for p in e.help_path[:-1]:
123
+ n = c.setdefault(p, {})
124
+ if not isinstance(n, dict):
125
+ raise NameError(e) # noqa
126
+ c = n
127
+
128
+ h = e.help_path[-1]
129
+ if h in c:
130
+ raise NameError(e)
131
+
132
+ if isinstance(e.cmd.cmd_name, str):
133
+ l = [e.cmd.cmd_name]
134
+ else:
135
+ l = list(e.cmd.cmd_name)
136
+
137
+ s = (
138
+ f'{l[0].split("/")[-1]}'
139
+ f'{(" (" + ", ".join(l[1:]) + ")") if len(l) > 1 else ""}'
140
+ )
141
+
142
+ c[h] = s
143
+
144
+ return d
145
+
146
+ class SelectedCmd(ta.NamedTuple):
147
+ cmd: CliCmd
148
+ args: ta.Sequence[str]
149
+
150
+ class InvalidCmd(ta.NamedTuple):
151
+ path: ta.Sequence[str]
152
+
153
+ def select_cmd(self, args: ta.Sequence[str]) -> SelectedCmd | InvalidCmd:
154
+ check.not_isinstance(args, str)
155
+
156
+ d = self.exec_tree()
157
+ for i in range(len(args)):
158
+ n = args[i]
159
+ if n not in d:
160
+ return CliCmdSet.InvalidCmd(args[:i + 1])
161
+
162
+ c = d[n]
163
+
164
+ if isinstance(c, CliCmd):
165
+ return CliCmdSet.SelectedCmd(c, args[i + 1:])
166
+ elif isinstance(c, ta.Mapping):
167
+ d = c
168
+ else:
169
+ raise TypeError(c)
170
+
171
+ return CliCmdSet.InvalidCmd([])
172
+
173
+
174
+ ##
175
+
176
+
177
+ def _build_arg_parser() -> argparse.ArgumentParser:
178
+ parser = argparse.ArgumentParser()
179
+ parser.add_argument('--cli-pkg-root', action='append')
180
+ parser.add_argument('--cli-debug', action='store_true')
181
+ parser.add_argument('cmd', nargs='?')
182
+ parser.add_argument('args', nargs=argparse.REMAINDER)
183
+ return parser
184
+
185
+
186
+ def _build_cmd_set(args: ta.Any) -> CliCmdSet:
187
+ ldr = ManifestLoader.from_entry_point(globals())
188
+
189
+ pkgs: list[str] = []
190
+
191
+ def scan_pkg_root(r: str) -> None:
192
+ r = os.path.expanduser(r)
193
+ for n in os.listdir(r):
194
+ if os.path.isdir(p := os.path.join(r, n)) and os.path.exists(os.path.join(p, '__init__.py')):
195
+ pkgs.append(n)
196
+
197
+ if args.cli_pkg_root:
198
+ for r in args.cli_pkg_root:
199
+ scan_pkg_root(r)
200
+
201
+ else:
202
+ pkgs.extend(ldr.discover())
203
+
204
+ if not pkgs:
205
+ scan_pkg_root(os.getcwd())
206
+
207
+ #
208
+
209
+ lst: list[CliCmd] = []
210
+
211
+ for m in ldr.load(*pkgs, only=[CliModule]):
212
+ lst.append(check.isinstance(m.value, CliModule))
213
+
214
+ lst.extend(_CLI_FUNCS)
215
+
216
+ #
217
+
218
+ return CliCmdSet(lst)
219
+
220
+
221
+ def _select_cmd(args: ta.Any, cmds: CliCmdSet) -> CliCmdSet.SelectedCmd | int:
222
+ def print_err(*args, **kwargs): # noqa
223
+ print(*args, **kwargs, file=sys.stderr)
224
+
225
+ if args.cmd:
226
+ sel_cmd = cmds.select_cmd([args.cmd, *args.args])
227
+ if isinstance(sel_cmd, CliCmdSet.SelectedCmd):
228
+ return sel_cmd
229
+ elif isinstance(sel_cmd, CliCmdSet.InvalidCmd):
230
+ print_err(f'Invalid command: {" ".join(sel_cmd.path)}\n')
231
+ else:
232
+ raise TypeError(sel_cmd)
233
+ rc = 1
234
+ else:
235
+ rc = 0
236
+
237
+ print_err('Subcommands:\n')
238
+
239
+ def rec(d, pfx=''):
240
+ for k, v in sorted(d.items(), key=lambda t: t[0]):
241
+ if isinstance(v, str):
242
+ print_err(pfx + v)
243
+ else:
244
+ print_err(pfx + k)
245
+ rec(v, pfx + ' ')
246
+ if not pfx:
247
+ print_err('')
248
+
249
+ rec(cmds.help_tree())
250
+
251
+ return rc
252
+
253
+
254
+ def _main() -> ta.Any:
255
+ parser = _build_arg_parser()
256
+ args = parser.parse_args()
257
+
258
+ def inner():
259
+ cmds = _build_cmd_set(args)
260
+ sel = _select_cmd(args, cmds)
261
+
262
+ if isinstance(sel, int):
263
+ return sel
264
+
265
+ cmd = sel.cmd
266
+ if isinstance(cmd, CliModule):
267
+ sys.argv = [args.cmd, *(sel.args or ())]
268
+ runpy._run_module_as_main(cmd.mod_name) # type: ignore # noqa
269
+ return 0
270
+
271
+ elif isinstance(cmd, CliFunc):
272
+ return cmd.fn(*(sel.args or ()))
273
+
274
+ else:
275
+ raise TypeError(cmd)
276
+
277
+ if args.cli_debug:
278
+ from omlish.diag.debug import debugging_on_exception
279
+
280
+ with debugging_on_exception():
281
+ return inner()
282
+
283
+ else:
284
+ return inner()
285
+
286
+
287
+ if __name__ == '__main__':
288
+ sys.exit(rc if isinstance(rc := _main(), int) else 0)
@@ -10,7 +10,7 @@ def _get_rss() -> int:
10
10
 
11
11
  # @omlish-manifest
12
12
  _CLI_MODULE = {'$omdev.cli.types.CliModule': {
13
- 'cmd_name': 'execrss',
13
+ 'cmd_name': 'py/execrss',
14
14
  'mod_name': __name__,
15
15
  }}
16
16
 
@@ -6,7 +6,7 @@ import time
6
6
 
7
7
  # @omlish-manifest
8
8
  _CLI_MODULE = {'$omdev.cli.types.CliModule': {
9
- 'cmd_name': 'exectime',
9
+ 'cmd_name': 'py/exectime',
10
10
  'mod_name': __name__,
11
11
  }}
12
12
 
@@ -480,7 +480,7 @@ class SqliteWriter:
480
480
 
481
481
  # @omlish-manifest
482
482
  _CLI_MODULE = {'$omdev.cli.types.CliModule': {
483
- 'cmd_name': 'importtrace',
483
+ 'cmd_name': 'py/importtrace',
484
484
  'mod_name': __name__,
485
485
  }}
486
486
 
@@ -164,7 +164,7 @@ def run(
164
164
 
165
165
 
166
166
  # @omlish-manifest
167
- _CLI_MODULE = CliModule('importscan', __name__)
167
+ _CLI_MODULE = CliModule('py/importscan', __name__)
168
168
 
169
169
 
170
170
  def _main() -> None:
@@ -146,7 +146,7 @@ class Processor:
146
146
 
147
147
 
148
148
  # @omlish-manifest
149
- _CLI_MODULE = CliModule('mkrelimp', __name__)
149
+ _CLI_MODULE = CliModule('py/mkrelimp', __name__)
150
150
 
151
151
 
152
152
  def _main() -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev78
3
+ Version: 0.0.0.dev79
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.dev78
15
+ Requires-Dist: omlish==0.0.0.dev79
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=24.10; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
@@ -1,4 +1,4 @@
1
- omlish==0.0.0.dev78
1
+ omlish==0.0.0.dev79
2
2
 
3
3
  [all]
4
4
  black~=24.10
@@ -12,7 +12,7 @@ authors = [
12
12
  urls = {source = 'https://github.com/wrmsr/omlish'}
13
13
  license = {text = 'BSD-3-Clause'}
14
14
  requires-python = '~=3.12'
15
- version = '0.0.0.dev78'
15
+ version = '0.0.0.dev79'
16
16
  classifiers = [
17
17
  'License :: OSI Approved :: BSD License',
18
18
  'Development Status :: 2 - Pre-Alpha',
@@ -22,7 +22,7 @@ classifiers = [
22
22
  ]
23
23
  description = 'omdev'
24
24
  dependencies = [
25
- 'omlish == 0.0.0.dev78',
25
+ 'omlish == 0.0.0.dev79',
26
26
  ]
27
27
 
28
28
  [project.optional-dependencies]
@@ -1,167 +0,0 @@
1
- """
2
- TODO:
3
- - cache ldr.discover() somehow if in uvx/pipx - very slow
4
- - <venv-root>/.omdev-cli-manifest-cache.json - {pkg_name: manifests_json}
5
- - allow manually specifying manifest packages
6
- """
7
- import argparse
8
- import os
9
- import runpy
10
- import sys
11
- import typing as ta
12
-
13
- from omlish import check
14
-
15
- from ..manifests.load import ManifestLoader
16
- from .types import CliCmd
17
- from .types import CliFunc
18
- from .types import CliModule
19
-
20
-
21
- ##
22
-
23
-
24
- def _post_install(cli_pkg: str) -> None:
25
- from .managers import setup_install_manager
26
-
27
- setup_install_manager(cli_pkg)
28
-
29
-
30
- ##
31
-
32
-
33
- _CLI_FUNCS: ta.Sequence[CliFunc] = [
34
- CliFunc('_post_install', _post_install),
35
- ]
36
-
37
-
38
- ##
39
-
40
-
41
- def _build_arg_parser() -> argparse.ArgumentParser:
42
- parser = argparse.ArgumentParser()
43
- parser.add_argument('--cli-pkg-root', action='append')
44
- parser.add_argument('--cli-debug', action='store_true')
45
- parser.add_argument('cmd', nargs='?')
46
- parser.add_argument('args', nargs=argparse.REMAINDER)
47
- return parser
48
-
49
-
50
- def _build_cmd_dct(args: ta.Any) -> ta.Mapping[str, CliCmd]:
51
- ccs: list[CliCmd] = []
52
-
53
- ldr = ManifestLoader.from_entry_point(globals())
54
-
55
- pkgs: list[str] = []
56
-
57
- def scan_pkg_root(r: str) -> None:
58
- r = os.path.expanduser(r)
59
- for n in os.listdir(r):
60
- if os.path.isdir(p := os.path.join(r, n)) and os.path.exists(os.path.join(p, '__init__.py')):
61
- pkgs.append(n)
62
-
63
- if args.cli_pkg_root:
64
- for r in args.cli_pkg_root:
65
- scan_pkg_root(r)
66
-
67
- else:
68
- pkgs.extend(ldr.discover())
69
-
70
- if not pkgs:
71
- scan_pkg_root(os.getcwd())
72
-
73
- for m in ldr.load(*pkgs, only=[CliModule]):
74
- ccs.append(check.isinstance(m.value, CliModule))
75
-
76
- ccs.extend(_CLI_FUNCS)
77
-
78
- dct: dict[str, CliCmd] = {}
79
- for cc in ccs:
80
- for cn in [cc.cmd_name] if isinstance(cc.cmd_name, str) else cc.cmd_name:
81
- if cn in dct:
82
- raise NameError(cc)
83
- dct[cn] = cc
84
-
85
- return dct
86
-
87
-
88
- def _select_cmd(args: ta.Any, cmds: ta.Mapping[str, CliCmd]) -> CliCmd | int:
89
- cmd = args.cmd
90
- if cmd and cmd in cmds:
91
- return cmds[cmd]
92
-
93
- def print_err(*args, **kwargs): # noqa
94
- print(*args, **kwargs, file=sys.stderr)
95
-
96
- if cmd:
97
- print_err(f'Invalid command: {cmd}\n')
98
- rc = 1
99
- else:
100
- rc = 0
101
-
102
- mset = set()
103
- mdct: dict = {}
104
- for cc in cmds.values():
105
- if id(cc) in mset:
106
- continue
107
- mset.add(id(cc))
108
- if isinstance(cc.cmd_name, str) and cc.cmd_name[0] == '_':
109
- continue
110
- if isinstance(cc, CliFunc):
111
- mdct.setdefault('-', []).append(cc)
112
- elif isinstance(cc, CliModule):
113
- mdct.setdefault(cc.mod_name.partition('.')[0], []).append(cc)
114
- else:
115
- raise TypeError(cc)
116
-
117
- print_err('Subcommands:\n')
118
- for m, l in sorted(mdct.items(), key=lambda t: (t[0] == '-', t[0])):
119
- print_err(f' {m}')
120
- for cc in sorted(l, key=lambda c: c.primary_name):
121
- if isinstance(cc.cmd_name, str):
122
- print_err(f' {cc.cmd_name}')
123
- else:
124
- print_err(
125
- f' {cc.cmd_name[0]}'
126
- f'{(" (" + ", ".join(cc.cmd_name[1:]) + ")") if len(cc.cmd_name) > 1 else ""}',
127
- )
128
- print_err()
129
-
130
- return rc
131
-
132
-
133
- def _main() -> ta.Any:
134
- parser = _build_arg_parser()
135
- args = parser.parse_args()
136
-
137
- def inner():
138
- cmds = _build_cmd_dct(args)
139
- sel = _select_cmd(args, cmds)
140
-
141
- match sel:
142
- case int():
143
- return sel
144
-
145
- case CliModule() as cm:
146
- sys.argv = [args.cmd, *(args.args or ())]
147
- runpy._run_module_as_main(cm.mod_name) # type: ignore # noqa
148
- return 0
149
-
150
- case CliFunc() as cf:
151
- return cf.fn(*(args.args or ()))
152
-
153
- case _:
154
- raise TypeError(sel)
155
-
156
- if args.cli_debug:
157
- from omlish.diag.debug import debugging_on_exception
158
-
159
- with debugging_on_exception():
160
- return inner()
161
-
162
- else:
163
- return inner()
164
-
165
-
166
- if __name__ == '__main__':
167
- sys.exit(rc if isinstance(rc := _main(), int) else 0)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes