omdev 0.0.0.dev77__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.
- {omdev-0.0.0.dev77/omdev.egg-info → omdev-0.0.0.dev79}/PKG-INFO +4 -4
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/.manifests.json +6 -6
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/__about__.py +1 -1
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/classdot.py +1 -1
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cli/_pathhack.py +1 -1
- omdev-0.0.0.dev79/omdev/cli/main.py +288 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/scripts/execrss.py +1 -1
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/scripts/exectime.py +1 -1
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/scripts/importtrace.py +1 -1
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/scripts/interp.py +28 -2
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/scripts/pyproject.py +28 -2
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/importscan.py +1 -1
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/mkrelimp.py +1 -1
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79/omdev.egg-info}/PKG-INFO +4 -4
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev.egg-info/requires.txt +3 -3
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/pyproject.toml +4 -4
- omdev-0.0.0.dev77/omdev/cli/main.py +0 -167
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/LICENSE +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/MANIFEST.in +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/README.rst +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/amalg/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/amalg/__main__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/amalg/amalg.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/antlr/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/antlr/_antlr/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/antlr/consts.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/antlr/gen.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/bracepy.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/compute/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/compute/cache.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/compute/contexts.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/compute/currents.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/compute/fns.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/compute/resolvers.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/compute/storage.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/compute/types.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/data/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/data/actions.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/data/cache.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/data/consts.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/data/defaults.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/data/manifests.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cache/data/specs.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_boilerplate.cc +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/LICENSE +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/build_ext.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/compilers/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/compilers/ccompiler.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/compilers/options.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/compilers/unixccompiler.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/dir_util.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/errors.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/extension.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/file_util.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/modified.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/spawn.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/sysconfig.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/util.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/_distutils/version.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/build.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/cmake.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/importhook.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/magic.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cexts/scan.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cli/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cli/__main__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cli/clicli.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cli/install.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cli/managers.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cli/types.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/cmake.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/findimports.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/findmagic.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/git.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/imgur.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/__main__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/cli.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/inspect.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/providers.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/pyenv.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/resolvers.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/standalone.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/system.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/interp/types.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/manifests/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/manifests/build.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/manifests/load.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/manifests/types.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/mypy/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/mypy/debug.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/packaging/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/packaging/names.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/packaging/requires.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/packaging/specifiers.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/packaging/versions.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/precheck/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/precheck/__main__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/precheck/base.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/precheck/git.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/precheck/lite.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/precheck/precheck.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/precheck/scripts.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/pyproject/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/pyproject/__main__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/pyproject/cexts.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/pyproject/cli.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/pyproject/configs.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/pyproject/pkg.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/pyproject/reqs.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/revisions.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/scripts/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/scripts/bumpversion.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/secrets.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tokens.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/toml/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/toml/parser.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/toml/writer.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/__init__.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/dockertools.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/gittools.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/nbtools.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/piptools.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/proftools.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/rsttool.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/tools/sqlrepl.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev/wheelfile.py +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev.egg-info/SOURCES.txt +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev.egg-info/dependency_links.txt +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev.egg-info/entry_points.txt +0 -0
- {omdev-0.0.0.dev77 → omdev-0.0.0.dev79}/omdev.egg-info/top_level.txt +0 -0
- {omdev-0.0.0.dev77 → 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.
|
|
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.
|
|
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"
|
|
@@ -21,7 +21,7 @@ Requires-Dist: pcpp~=1.30; extra == "all"
|
|
|
21
21
|
Requires-Dist: docutils~=0.21; extra == "all"
|
|
22
22
|
Requires-Dist: mypy~=1.11; extra == "all"
|
|
23
23
|
Requires-Dist: gprof2dot~=2024.6; extra == "all"
|
|
24
|
-
Requires-Dist: tokenize_rt~=6.
|
|
24
|
+
Requires-Dist: tokenize_rt~=6.1; extra == "all"
|
|
25
25
|
Requires-Dist: wheel~=0.44; extra == "all"
|
|
26
26
|
Provides-Extra: black
|
|
27
27
|
Requires-Dist: black~=24.10; extra == "black"
|
|
@@ -36,6 +36,6 @@ Requires-Dist: mypy~=1.11; extra == "mypy"
|
|
|
36
36
|
Provides-Extra: prof
|
|
37
37
|
Requires-Dist: gprof2dot~=2024.6; extra == "prof"
|
|
38
38
|
Provides-Extra: tokens
|
|
39
|
-
Requires-Dist: tokenize_rt~=6.
|
|
39
|
+
Requires-Dist: tokenize_rt~=6.1; extra == "tokens"
|
|
40
40
|
Provides-Extra: wheel
|
|
41
41
|
Requires-Dist: wheel~=0.44; extra == "wheel"
|
|
@@ -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
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Python is insistent on prepending sys.path with an empty string (translating to the current working directory), which
|
|
3
3
|
leads to problems when using the cli in directories containing python packages (such as within this very source tree).
|
|
4
4
|
This can't be done in cli main as the code frequently spawns other sys.executable processes which wouldn't know to do
|
|
5
|
-
that, so a .pth file hack is used. Cleaning sys.path solely there is also insufficient as that code runs before
|
|
5
|
+
that, so a .pth file hack is used. Cleaning sys.path solely there is also insufficient as that code runs before the
|
|
6
6
|
problematic empty string is added, so a sys.meta_path hook is prepended.
|
|
7
7
|
|
|
8
8
|
See:
|
|
@@ -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)
|
|
@@ -527,6 +527,23 @@ def check_state(v: bool, msg: str = 'Illegal state') -> None:
|
|
|
527
527
|
raise ValueError(msg)
|
|
528
528
|
|
|
529
529
|
|
|
530
|
+
def check_equal(l: T, r: T) -> T:
|
|
531
|
+
if l != r:
|
|
532
|
+
raise ValueError(l, r)
|
|
533
|
+
return l
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
def check_not_equal(l: T, r: T) -> T:
|
|
537
|
+
if l == r:
|
|
538
|
+
raise ValueError(l, r)
|
|
539
|
+
return l
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def check_single(vs: ta.Iterable[T]) -> T:
|
|
543
|
+
[v] = vs
|
|
544
|
+
return v
|
|
545
|
+
|
|
546
|
+
|
|
530
547
|
########################################
|
|
531
548
|
# ../../../omlish/lite/json.py
|
|
532
549
|
|
|
@@ -609,8 +626,13 @@ def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
|
|
|
609
626
|
# ../../../omlish/lite/strings.py
|
|
610
627
|
|
|
611
628
|
|
|
612
|
-
def camel_case(name: str) -> str:
|
|
613
|
-
|
|
629
|
+
def camel_case(name: str, lower: bool = False) -> str:
|
|
630
|
+
if not name:
|
|
631
|
+
return ''
|
|
632
|
+
s = ''.join(map(str.capitalize, name.split('_'))) # noqa
|
|
633
|
+
if lower:
|
|
634
|
+
s = s[0].lower() + s[1:]
|
|
635
|
+
return s
|
|
614
636
|
|
|
615
637
|
|
|
616
638
|
def snake_case(name: str) -> str:
|
|
@@ -636,6 +658,10 @@ def is_sunder(name: str) -> bool:
|
|
|
636
658
|
)
|
|
637
659
|
|
|
638
660
|
|
|
661
|
+
def attr_repr(obj: ta.Any, *attrs: str) -> str:
|
|
662
|
+
return f'{type(obj).__name__}({", ".join(f"{attr}={getattr(obj, attr)!r}" for attr in attrs)})'
|
|
663
|
+
|
|
664
|
+
|
|
639
665
|
########################################
|
|
640
666
|
# ../../packaging/specifiers.py
|
|
641
667
|
# Copyright (c) Donald Stufft and individual contributors.
|
|
@@ -1908,6 +1908,23 @@ def check_state(v: bool, msg: str = 'Illegal state') -> None:
|
|
|
1908
1908
|
raise ValueError(msg)
|
|
1909
1909
|
|
|
1910
1910
|
|
|
1911
|
+
def check_equal(l: T, r: T) -> T:
|
|
1912
|
+
if l != r:
|
|
1913
|
+
raise ValueError(l, r)
|
|
1914
|
+
return l
|
|
1915
|
+
|
|
1916
|
+
|
|
1917
|
+
def check_not_equal(l: T, r: T) -> T:
|
|
1918
|
+
if l == r:
|
|
1919
|
+
raise ValueError(l, r)
|
|
1920
|
+
return l
|
|
1921
|
+
|
|
1922
|
+
|
|
1923
|
+
def check_single(vs: ta.Iterable[T]) -> T:
|
|
1924
|
+
[v] = vs
|
|
1925
|
+
return v
|
|
1926
|
+
|
|
1927
|
+
|
|
1911
1928
|
########################################
|
|
1912
1929
|
# ../../../omlish/lite/json.py
|
|
1913
1930
|
|
|
@@ -1990,8 +2007,13 @@ def deep_subclasses(cls: ta.Type[T]) -> ta.Iterator[ta.Type[T]]:
|
|
|
1990
2007
|
# ../../../omlish/lite/strings.py
|
|
1991
2008
|
|
|
1992
2009
|
|
|
1993
|
-
def camel_case(name: str) -> str:
|
|
1994
|
-
|
|
2010
|
+
def camel_case(name: str, lower: bool = False) -> str:
|
|
2011
|
+
if not name:
|
|
2012
|
+
return ''
|
|
2013
|
+
s = ''.join(map(str.capitalize, name.split('_'))) # noqa
|
|
2014
|
+
if lower:
|
|
2015
|
+
s = s[0].lower() + s[1:]
|
|
2016
|
+
return s
|
|
1995
2017
|
|
|
1996
2018
|
|
|
1997
2019
|
def snake_case(name: str) -> str:
|
|
@@ -2017,6 +2039,10 @@ def is_sunder(name: str) -> bool:
|
|
|
2017
2039
|
)
|
|
2018
2040
|
|
|
2019
2041
|
|
|
2042
|
+
def attr_repr(obj: ta.Any, *attrs: str) -> str:
|
|
2043
|
+
return f'{type(obj).__name__}({", ".join(f"{attr}={getattr(obj, attr)!r}" for attr in attrs)})'
|
|
2044
|
+
|
|
2045
|
+
|
|
2020
2046
|
########################################
|
|
2021
2047
|
# ../../packaging/specifiers.py
|
|
2022
2048
|
# Copyright (c) Donald Stufft and individual contributors.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
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.
|
|
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"
|
|
@@ -21,7 +21,7 @@ Requires-Dist: pcpp~=1.30; extra == "all"
|
|
|
21
21
|
Requires-Dist: docutils~=0.21; extra == "all"
|
|
22
22
|
Requires-Dist: mypy~=1.11; extra == "all"
|
|
23
23
|
Requires-Dist: gprof2dot~=2024.6; extra == "all"
|
|
24
|
-
Requires-Dist: tokenize_rt~=6.
|
|
24
|
+
Requires-Dist: tokenize_rt~=6.1; extra == "all"
|
|
25
25
|
Requires-Dist: wheel~=0.44; extra == "all"
|
|
26
26
|
Provides-Extra: black
|
|
27
27
|
Requires-Dist: black~=24.10; extra == "black"
|
|
@@ -36,6 +36,6 @@ Requires-Dist: mypy~=1.11; extra == "mypy"
|
|
|
36
36
|
Provides-Extra: prof
|
|
37
37
|
Requires-Dist: gprof2dot~=2024.6; extra == "prof"
|
|
38
38
|
Provides-Extra: tokens
|
|
39
|
-
Requires-Dist: tokenize_rt~=6.
|
|
39
|
+
Requires-Dist: tokenize_rt~=6.1; extra == "tokens"
|
|
40
40
|
Provides-Extra: wheel
|
|
41
41
|
Requires-Dist: wheel~=0.44; extra == "wheel"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
omlish==0.0.0.
|
|
1
|
+
omlish==0.0.0.dev79
|
|
2
2
|
|
|
3
3
|
[all]
|
|
4
4
|
black~=24.10
|
|
@@ -8,7 +8,7 @@ pcpp~=1.30
|
|
|
8
8
|
docutils~=0.21
|
|
9
9
|
mypy~=1.11
|
|
10
10
|
gprof2dot~=2024.6
|
|
11
|
-
tokenize_rt~=6.
|
|
11
|
+
tokenize_rt~=6.1
|
|
12
12
|
wheel~=0.44
|
|
13
13
|
|
|
14
14
|
[black]
|
|
@@ -29,7 +29,7 @@ mypy~=1.11
|
|
|
29
29
|
gprof2dot~=2024.6
|
|
30
30
|
|
|
31
31
|
[tokens]
|
|
32
|
-
tokenize_rt~=6.
|
|
32
|
+
tokenize_rt~=6.1
|
|
33
33
|
|
|
34
34
|
[wheel]
|
|
35
35
|
wheel~=0.44
|
|
@@ -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.
|
|
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.
|
|
25
|
+
'omlish == 0.0.0.dev79',
|
|
26
26
|
]
|
|
27
27
|
|
|
28
28
|
[project.optional-dependencies]
|
|
@@ -34,7 +34,7 @@ all = [
|
|
|
34
34
|
'docutils ~= 0.21',
|
|
35
35
|
'mypy ~= 1.11',
|
|
36
36
|
'gprof2dot ~= 2024.6',
|
|
37
|
-
'tokenize_rt ~= 6.
|
|
37
|
+
'tokenize_rt ~= 6.1',
|
|
38
38
|
'wheel ~= 0.44',
|
|
39
39
|
]
|
|
40
40
|
black = [
|
|
@@ -55,7 +55,7 @@ prof = [
|
|
|
55
55
|
'gprof2dot ~= 2024.6',
|
|
56
56
|
]
|
|
57
57
|
tokens = [
|
|
58
|
-
'tokenize_rt ~= 6.
|
|
58
|
+
'tokenize_rt ~= 6.1',
|
|
59
59
|
]
|
|
60
60
|
wheel = [
|
|
61
61
|
'wheel ~= 0.44',
|