omdev 0.0.0.dev39__tar.gz → 0.0.0.dev41__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 (128) hide show
  1. {omdev-0.0.0.dev39/omdev.egg-info → omdev-0.0.0.dev41}/PKG-INFO +2 -2
  2. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/.manifests.json +48 -12
  3. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cli/install.py +2 -2
  4. omdev-0.0.0.dev41/omdev/cli/main.py +100 -0
  5. omdev-0.0.0.dev41/omdev/cli/types.py +17 -0
  6. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/git.py +9 -5
  7. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/manifests/load.py +30 -14
  8. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/pyproject/cli.py +28 -15
  9. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/pyproject/pkg.py +38 -41
  10. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/scripts/execrss.py +7 -0
  11. omdev-0.0.0.dev41/omdev/scripts/exectime.py +24 -0
  12. {omdev-0.0.0.dev39/omdev/tools → omdev-0.0.0.dev41/omdev/scripts}/importtrace.py +7 -0
  13. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/scripts/pyproject.py +74 -61
  14. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/tools/importscan.py +6 -0
  15. omdev-0.0.0.dev41/omdev/tools/proftools.py +4 -0
  16. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41/omdev.egg-info}/PKG-INFO +2 -2
  17. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev.egg-info/SOURCES.txt +3 -2
  18. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev.egg-info/requires.txt +1 -1
  19. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/pyproject.toml +2 -2
  20. omdev-0.0.0.dev39/omdev/cli/_version.py +0 -14
  21. omdev-0.0.0.dev39/omdev/cli/main.py +0 -54
  22. omdev-0.0.0.dev39/omdev/cli/types.py +0 -7
  23. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/LICENSE +0 -0
  24. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/MANIFEST.in +0 -0
  25. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/README.rst +0 -0
  26. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/__about__.py +0 -0
  27. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/__init__.py +0 -0
  28. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/amalg/__init__.py +0 -0
  29. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/amalg/__main__.py +0 -0
  30. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/amalg/amalg.py +0 -0
  31. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/bracepy.py +0 -0
  32. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/__init__.py +0 -0
  33. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/compute/__init__.py +0 -0
  34. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/compute/cache.py +0 -0
  35. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/compute/contexts.py +0 -0
  36. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/compute/currents.py +0 -0
  37. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/compute/fns.py +0 -0
  38. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/compute/resolvers.py +0 -0
  39. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/compute/storage.py +0 -0
  40. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/compute/types.py +0 -0
  41. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/data/__init__.py +0 -0
  42. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/data/actions.py +0 -0
  43. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/data/cache.py +0 -0
  44. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/data/consts.py +0 -0
  45. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/data/defaults.py +0 -0
  46. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/data/manifests.py +0 -0
  47. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cache/data/specs.py +0 -0
  48. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/__init__.py +0 -0
  49. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_boilerplate.cc +0 -0
  50. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/LICENSE +0 -0
  51. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/__init__.py +0 -0
  52. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/build_ext.py +0 -0
  53. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/compilers/__init__.py +0 -0
  54. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/compilers/ccompiler.py +0 -0
  55. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/compilers/options.py +0 -0
  56. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/compilers/unixccompiler.py +0 -0
  57. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/dir_util.py +0 -0
  58. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/errors.py +0 -0
  59. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/extension.py +0 -0
  60. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/file_util.py +0 -0
  61. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/modified.py +0 -0
  62. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/spawn.py +0 -0
  63. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/sysconfig.py +0 -0
  64. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/util.py +0 -0
  65. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/_distutils/version.py +0 -0
  66. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/build.py +0 -0
  67. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/cmake.py +0 -0
  68. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/importhook.py +0 -0
  69. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/magic.py +0 -0
  70. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cexts/scan.py +0 -0
  71. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/classdot.py +0 -0
  72. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cli/__init__.py +0 -0
  73. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cli/__main__.py +0 -0
  74. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/cmake.py +0 -0
  75. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/findimports.py +0 -0
  76. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/findmagic.py +0 -0
  77. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/__init__.py +0 -0
  78. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/__main__.py +0 -0
  79. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/cli.py +0 -0
  80. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/inspect.py +0 -0
  81. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/providers.py +0 -0
  82. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/pyenv.py +0 -0
  83. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/resolvers.py +0 -0
  84. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/standalone.py +0 -0
  85. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/system.py +0 -0
  86. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/interp/types.py +0 -0
  87. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/manifests/__init__.py +0 -0
  88. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/manifests/build.py +0 -0
  89. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/manifests/types.py +0 -0
  90. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/mypy/__init__.py +0 -0
  91. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/mypy/debug.py +0 -0
  92. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/packaging/__init__.py +0 -0
  93. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/packaging/names.py +0 -0
  94. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/packaging/requires.py +0 -0
  95. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/packaging/specifiers.py +0 -0
  96. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/packaging/versions.py +0 -0
  97. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/precheck/__init__.py +0 -0
  98. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/precheck/__main__.py +0 -0
  99. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/precheck/base.py +0 -0
  100. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/precheck/git.py +0 -0
  101. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/precheck/lite.py +0 -0
  102. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/precheck/precheck.py +0 -0
  103. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/precheck/scripts.py +0 -0
  104. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/pyproject/__init__.py +0 -0
  105. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/pyproject/__main__.py +0 -0
  106. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/pyproject/cexts.py +0 -0
  107. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/pyproject/configs.py +0 -0
  108. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/pyproject/reqs.py +0 -0
  109. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/revisions.py +0 -0
  110. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/scripts/__init__.py +0 -0
  111. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/scripts/bumpversion.py +0 -0
  112. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/scripts/interp.py +0 -0
  113. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/secrets.py +0 -0
  114. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/tokens.py +0 -0
  115. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/toml/__init__.py +0 -0
  116. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/toml/parser.py +0 -0
  117. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/toml/writer.py +0 -0
  118. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/tools/__init__.py +0 -0
  119. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/tools/dockertools.py +0 -0
  120. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/tools/gittools.py +0 -0
  121. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/tools/piptools.py +0 -0
  122. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/tools/rst.py +0 -0
  123. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/tools/sqlrepl.py +0 -0
  124. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev/wheelfile.py +0 -0
  125. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev.egg-info/dependency_links.txt +0 -0
  126. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev.egg-info/entry_points.txt +0 -0
  127. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/omdev.egg-info/top_level.txt +0 -0
  128. {omdev-0.0.0.dev39 → omdev-0.0.0.dev41}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev39
3
+ Version: 0.0.0.dev41
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.dev39
15
+ Requires-Dist: omlish==0.0.0.dev41
16
16
  Provides-Extra: all
17
17
  Requires-Dist: pycparser~=2.22; extra == "all"
18
18
  Requires-Dist: cffi~=1.17; extra == "all"
@@ -35,18 +35,6 @@
35
35
  }
36
36
  }
37
37
  },
38
- {
39
- "module": ".cli._version",
40
- "attr": "_CLI_MODULE",
41
- "file": "omdev/cli/_version.py",
42
- "line": 5,
43
- "value": {
44
- "$.cli.types.CliModule": {
45
- "cmd_name": "version",
46
- "mod_name": "omdev.cli._version"
47
- }
48
- }
49
- },
50
38
  {
51
39
  "module": ".interp.__main__",
52
40
  "attr": "_CLI_MODULE",
@@ -83,6 +71,42 @@
83
71
  }
84
72
  }
85
73
  },
74
+ {
75
+ "module": ".scripts.execrss",
76
+ "attr": "_CLI_MODULE",
77
+ "file": "omdev/scripts/execrss.py",
78
+ "line": 11,
79
+ "value": {
80
+ "$.cli.types.CliModule": {
81
+ "cmd_name": "execrss",
82
+ "mod_name": "omdev.scripts.execrss"
83
+ }
84
+ }
85
+ },
86
+ {
87
+ "module": ".scripts.exectime",
88
+ "attr": "_CLI_MODULE",
89
+ "file": "omdev/scripts/exectime.py",
90
+ "line": 7,
91
+ "value": {
92
+ "$.cli.types.CliModule": {
93
+ "cmd_name": "exectime",
94
+ "mod_name": "omdev.scripts.exectime"
95
+ }
96
+ }
97
+ },
98
+ {
99
+ "module": ".scripts.importtrace",
100
+ "attr": "_CLI_MODULE",
101
+ "file": "omdev/scripts/importtrace.py",
102
+ "line": 481,
103
+ "value": {
104
+ "$.cli.types.CliModule": {
105
+ "cmd_name": "importtrace",
106
+ "mod_name": "omdev.scripts.importtrace"
107
+ }
108
+ }
109
+ },
86
110
  {
87
111
  "module": ".tools.dockertools",
88
112
  "attr": "_CLI_MODULE",
@@ -107,6 +131,18 @@
107
131
  }
108
132
  }
109
133
  },
134
+ {
135
+ "module": ".tools.importscan",
136
+ "attr": "_CLI_MODULE",
137
+ "file": "omdev/tools/importscan.py",
138
+ "line": 165,
139
+ "value": {
140
+ "$.cli.types.CliModule": {
141
+ "cmd_name": "importscan",
142
+ "mod_name": "omdev.tools.importscan"
143
+ }
144
+ }
145
+ },
110
146
  {
111
147
  "module": ".tools.piptools",
112
148
  "attr": "_CLI_MODULE",
@@ -46,7 +46,7 @@ class InstallMgr(abc.ABC):
46
46
  raise NotImplementedError
47
47
 
48
48
 
49
- class UvInstallMgr(InstallMgr):
49
+ class UvxInstallMgr(InstallMgr):
50
50
  def is_available(self) -> bool:
51
51
  return bool(shutil.which('uv'))
52
52
 
@@ -110,7 +110,7 @@ class PipxInstallMgr(InstallMgr):
110
110
 
111
111
 
112
112
  INSTALL_MGRS = {
113
- 'uv': UvInstallMgr(),
113
+ 'uvx': UvxInstallMgr(),
114
114
  'pipx': PipxInstallMgr(),
115
115
  }
116
116
 
@@ -0,0 +1,100 @@
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
+ - https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#creating-executable-scripts
7
+ - https://packaging.python.org/en/latest/specifications/entry-points/#entry-points
8
+ """
9
+ import argparse
10
+ import os
11
+ import runpy
12
+ import sys
13
+
14
+ from omlish import __about__
15
+ from omlish import check
16
+
17
+ from ..manifests.load import ManifestLoader
18
+ from .types import CliCmd
19
+ from .types import CliFunc
20
+ from .types import CliModule
21
+
22
+
23
+ ##
24
+
25
+
26
+ def _print_version() -> None:
27
+ print(__about__.__version__)
28
+
29
+
30
+ def _print_revision() -> None:
31
+ print(__about__.__revision__)
32
+
33
+
34
+ _CLI_FUNCS = [
35
+ CliFunc('version', _print_version),
36
+ CliFunc('revision', _print_revision),
37
+ ]
38
+
39
+
40
+ ##
41
+
42
+
43
+ def _main() -> None:
44
+ ccs: list[CliCmd] = []
45
+
46
+ #
47
+
48
+ ldr = ManifestLoader.from_entry_point(globals())
49
+
50
+ pkgs = ldr.discover()
51
+
52
+ if not pkgs:
53
+ pkgs = []
54
+ for n in os.listdir(os.getcwd()):
55
+ if os.path.isdir(n) and os.path.exists(os.path.join(n, '__init__.py')):
56
+ pkgs.append(n)
57
+
58
+ for m in ldr.load(*pkgs, only=[CliModule]):
59
+ ccs.append(check.isinstance(m.value, CliModule))
60
+
61
+ #
62
+
63
+ ccs.extend(_CLI_FUNCS)
64
+
65
+ #
66
+
67
+ dct: dict[str, CliCmd] = {}
68
+ for cc in ccs:
69
+ if cc.cmd_name in dct:
70
+ raise NameError(cc)
71
+ dct[cc.cmd_name] = cc
72
+
73
+ #
74
+
75
+ parser = argparse.ArgumentParser()
76
+ parser.add_argument('cmd', nargs='?', choices=dct.keys())
77
+ parser.add_argument('args', nargs=argparse.REMAINDER)
78
+
79
+ args = parser.parse_args()
80
+ if not args.cmd:
81
+ parser.print_help()
82
+ return
83
+
84
+ #
85
+
86
+ cc = dct[args.cmd]
87
+
88
+ if isinstance(cc, CliModule):
89
+ sys.argv = [cc.cmd_name, *(args.args or ())]
90
+ runpy._run_module_as_main(cc.mod_name) # type: ignore # noqa
91
+
92
+ elif isinstance(cc, CliFunc):
93
+ cc.fn(*(args.args or ()))
94
+
95
+ else:
96
+ raise TypeError(cc)
97
+
98
+
99
+ if __name__ == '__main__':
100
+ _main()
@@ -0,0 +1,17 @@
1
+ import dataclasses as dc
2
+ import typing as ta
3
+
4
+
5
+ @dc.dataclass(frozen=True)
6
+ class CliCmd:
7
+ cmd_name: str
8
+
9
+
10
+ @dc.dataclass(frozen=True)
11
+ class CliModule(CliCmd):
12
+ mod_name: str
13
+
14
+
15
+ @dc.dataclass(frozen=True)
16
+ class CliFunc(CliCmd):
17
+ fn: ta.Callable
@@ -73,11 +73,15 @@ def get_git_revision(
73
73
  if cwd is None:
74
74
  cwd = os.getcwd()
75
75
 
76
- if subprocess.run([ # noqa
77
- 'git',
78
- 'rev-parse',
79
- '--is-inside-work-tree',
80
- ], stderr=subprocess.PIPE).returncode:
76
+ if subprocess.run( # noqa
77
+ [
78
+ 'git',
79
+ 'rev-parse',
80
+ '--is-inside-work-tree',
81
+ ],
82
+ stdout=subprocess.PIPE,
83
+ stderr=subprocess.PIPE,
84
+ ).returncode:
81
85
  return None
82
86
 
83
87
  has_untracked = bool(subprocess.check_output([
@@ -1,7 +1,12 @@
1
+ """
2
+ Should be kept somewhat lightweight - used in cli entrypoints.
3
+
4
+ TODO:
5
+ - persisted caching support - {pkg_name: manifests}
6
+ """
1
7
  # ruff: noqa: UP006 UP007
2
8
  import dataclasses as dc
3
9
  import importlib.machinery
4
- import importlib.metadata
5
10
  import importlib.resources
6
11
  import json
7
12
  import typing as ta
@@ -74,19 +79,7 @@ class ManifestLoader:
74
79
  self._cls_cache[key] = cls
75
80
  return cls
76
81
 
77
- def load_raw(self, pkg_name: str) -> ta.Optional[ta.Sequence[Manifest]]:
78
- try:
79
- return self._raw_cache[pkg_name]
80
- except KeyError:
81
- pass
82
-
83
- t = importlib.resources.files(pkg_name).joinpath('.manifests.json')
84
- if not t.is_file():
85
- self._raw_cache[pkg_name] = None
86
- return None
87
-
88
- src = t.read_text('utf-8')
89
- obj = json.loads(src)
82
+ def load_contents(self, obj: ta.Any, pkg_name: str) -> ta.Sequence[Manifest]:
90
83
  if not isinstance(obj, (list, tuple)):
91
84
  raise TypeError(obj)
92
85
 
@@ -105,6 +98,26 @@ class ManifestLoader:
105
98
 
106
99
  lst.append(m)
107
100
 
101
+ return lst
102
+
103
+ def load_raw(self, pkg_name: str) -> ta.Optional[ta.Sequence[Manifest]]:
104
+ try:
105
+ return self._raw_cache[pkg_name]
106
+ except KeyError:
107
+ pass
108
+
109
+ t = importlib.resources.files(pkg_name).joinpath('.manifests.json')
110
+ if not t.is_file():
111
+ self._raw_cache[pkg_name] = None
112
+ return None
113
+
114
+ src = t.read_text('utf-8')
115
+ obj = json.loads(src)
116
+ if not isinstance(obj, (list, tuple)):
117
+ raise TypeError(obj)
118
+
119
+ lst = self.load_contents(obj, pkg_name)
120
+
108
121
  self._raw_cache[pkg_name] = lst
109
122
  return lst
110
123
 
@@ -143,6 +156,9 @@ class ManifestLoader:
143
156
  ENTRY_POINT_GROUP = 'omlish.manifests'
144
157
 
145
158
  def discover(self) -> ta.Sequence[str]:
159
+ # This is a fat dep so do it late.
160
+ import importlib.metadata
161
+
146
162
  return [
147
163
  ep.value
148
164
  for ep in importlib.metadata.entry_points(group=self.ENTRY_POINT_GROUP)
@@ -47,6 +47,7 @@ from ..toml.parser import toml_loads
47
47
  from .configs import PyprojectConfig
48
48
  from .configs import PyprojectConfigPreparer
49
49
  from .configs import VenvConfig
50
+ from .pkg import BasePyprojectPackageGenerator
50
51
  from .pkg import PyprojectPackageGenerator
51
52
  from .reqs import RequirementsRewriter
52
53
 
@@ -338,25 +339,36 @@ def _pkg_cmd(args) -> None:
338
339
  if run_build:
339
340
  os.makedirs(build_output_dir, exist_ok=True)
340
341
 
341
- num_threads = max(mp.cpu_count() // 2, 1)
342
+ pgs: ta.List[BasePyprojectPackageGenerator] = [
343
+ PyprojectPackageGenerator(
344
+ dir_name,
345
+ pkgs_root,
346
+ )
347
+ for dir_name in run.cfg().pkgs
348
+ ]
349
+ pgs = list(itertools.chain.from_iterable([pg, *pg.children()] for pg in pgs))
350
+
351
+ num_threads = args.jobs or max(mp.cpu_count() // 2, 1)
352
+ futs: ta.List[cf.Future]
342
353
  with cf.ThreadPoolExecutor(num_threads) as ex:
343
- futs = [
344
- ex.submit(functools.partial(
345
- PyprojectPackageGenerator(
346
- dir_name,
347
- pkgs_root,
348
- ).gen,
349
- PyprojectPackageGenerator.GenOpts(
350
- run_build=run_build,
351
- build_output_dir=build_output_dir,
352
- add_revision=add_revision,
353
- ),
354
- ))
355
- for dir_name in run.cfg().pkgs
356
- ]
354
+ futs = [ex.submit(pg.gen) for pg in pgs]
357
355
  for fut in futs:
358
356
  fut.result()
359
357
 
358
+ if run_build:
359
+ futs = [
360
+ ex.submit(functools.partial(
361
+ pg.build,
362
+ build_output_dir,
363
+ BasePyprojectPackageGenerator.BuildOpts(
364
+ add_revision=add_revision,
365
+ ),
366
+ ))
367
+ for pg in pgs
368
+ ]
369
+ for fut in futs:
370
+ fut.result()
371
+
360
372
  else:
361
373
  raise Exception(f'unknown subcommand: {cmd}')
362
374
 
@@ -380,6 +392,7 @@ def _build_parser() -> argparse.ArgumentParser:
380
392
  parser_resolve = subparsers.add_parser('pkg')
381
393
  parser_resolve.add_argument('-b', '--build', action='store_true')
382
394
  parser_resolve.add_argument('-r', '--revision', action='store_true')
395
+ parser_resolve.add_argument('-j', '--jobs', type=int)
383
396
  parser_resolve.add_argument('cmd', nargs='?')
384
397
  parser_resolve.add_argument('args', nargs=argparse.REMAINDER)
385
398
  parser_resolve.set_defaults(func=_pkg_cmd)
@@ -186,12 +186,33 @@ class BasePyprojectPackageGenerator(abc.ABC):
186
186
 
187
187
  #
188
188
 
189
- def _run_build(
189
+ def children(self) -> ta.Sequence['BasePyprojectPackageGenerator']:
190
+ return []
191
+
192
+ #
193
+
194
+ def gen(self) -> str:
195
+ log.info('Generating pyproject package: %s -> %s (%s)', self._dir_name, self._pkgs_root, self._pkg_suffix)
196
+
197
+ self._pkg_dir()
198
+ self._write_git_ignore()
199
+ self._symlink_source_dir()
200
+ self._write_file_contents()
201
+ self._symlink_standard_files()
202
+
203
+ return self._pkg_dir()
204
+
205
+ #
206
+
207
+ @dc.dataclass(frozen=True)
208
+ class BuildOpts:
209
+ add_revision: bool = False
210
+ test: bool = False
211
+
212
+ def build(
190
213
  self,
191
- build_output_dir: ta.Optional[str] = None,
192
- *,
193
- add_revision: bool = False,
194
- test: bool = False,
214
+ output_dir: ta.Optional[str] = None,
215
+ opts: BuildOpts = BuildOpts(),
195
216
  ) -> None:
196
217
  subprocess_check_call(
197
218
  sys.executable,
@@ -202,10 +223,10 @@ class BasePyprojectPackageGenerator(abc.ABC):
202
223
 
203
224
  dist_dir = os.path.join(self._pkg_dir(), 'dist')
204
225
 
205
- if add_revision:
226
+ if opts.add_revision:
206
227
  GitRevisionAdder().add_to(dist_dir)
207
228
 
208
- if test:
229
+ if opts.test:
209
230
  for fn in os.listdir(dist_dir):
210
231
  tmp_dir = tempfile.mkdtemp()
211
232
 
@@ -224,34 +245,9 @@ class BasePyprojectPackageGenerator(abc.ABC):
224
245
  cwd=tmp_dir,
225
246
  )
226
247
 
227
- if build_output_dir is not None:
248
+ if output_dir is not None:
228
249
  for fn in os.listdir(dist_dir):
229
- shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(build_output_dir, fn))
230
-
231
- #
232
-
233
- @dc.dataclass(frozen=True)
234
- class GenOpts:
235
- run_build: bool = False
236
- build_output_dir: ta.Optional[str] = None
237
- add_revision: bool = False
238
-
239
- def gen(self, opts: GenOpts = GenOpts()) -> str:
240
- log.info('Generating pyproject package: %s -> %s (%s)', self._dir_name, self._pkgs_root, self._pkg_suffix)
241
-
242
- self._pkg_dir()
243
- self._write_git_ignore()
244
- self._symlink_source_dir()
245
- self._write_file_contents()
246
- self._symlink_standard_files()
247
-
248
- if opts.run_build:
249
- self._run_build(
250
- opts.build_output_dir,
251
- add_revision=opts.add_revision,
252
- )
253
-
254
- return self._pkg_dir()
250
+ shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(output_dir, fn))
255
251
 
256
252
 
257
253
  #
@@ -377,24 +373,25 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
377
373
 
378
374
  #
379
375
 
380
- def gen(self, opts: BasePyprojectPackageGenerator.GenOpts = BasePyprojectPackageGenerator.GenOpts()) -> str:
381
- ret = super().gen(opts)
376
+ @cached_nullary
377
+ def children(self) -> ta.Sequence[BasePyprojectPackageGenerator]:
378
+ out: ta.List[BasePyprojectPackageGenerator] = []
382
379
 
383
380
  if self.build_specs().setuptools.get('cexts'):
384
- _PyprojectCextPackageGenerator(
381
+ out.append(_PyprojectCextPackageGenerator(
385
382
  self._dir_name,
386
383
  self._pkgs_root,
387
384
  pkg_suffix='-cext',
388
- ).gen(opts)
385
+ ))
389
386
 
390
387
  if self.build_specs().pyproject.get('cli_scripts'):
391
- _PyprojectCliPackageGenerator(
388
+ out.append(_PyprojectCliPackageGenerator(
392
389
  self._dir_name,
393
390
  self._pkgs_root,
394
391
  pkg_suffix='-cli',
395
- ).gen(opts)
392
+ ))
396
393
 
397
- return ret
394
+ return out
398
395
 
399
396
 
400
397
  #
@@ -8,6 +8,13 @@ def _get_rss() -> int:
8
8
  return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
9
9
 
10
10
 
11
+ # @omlish-manifest
12
+ _CLI_MODULE = {'$omdev.cli.types.CliModule': {
13
+ 'cmd_name': 'execrss',
14
+ 'mod_name': __name__,
15
+ }}
16
+
17
+
11
18
  def _main() -> None:
12
19
  [src] = sys.argv[1:]
13
20
  start = _get_rss()
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env python3
2
+ # @omlish-script
3
+ import sys
4
+ import time
5
+
6
+
7
+ # @omlish-manifest
8
+ _CLI_MODULE = {'$omdev.cli.types.CliModule': {
9
+ 'cmd_name': 'exectime',
10
+ 'mod_name': __name__,
11
+ }}
12
+
13
+
14
+ def _main() -> None:
15
+ [src] = sys.argv[1:]
16
+ co = compile(src, '<string>', 'exec')
17
+ start = time.time_ns()
18
+ exec(co)
19
+ end = time.time_ns()
20
+ print(end - start)
21
+
22
+
23
+ if __name__ == '__main__':
24
+ _main()
@@ -478,6 +478,13 @@ class SqliteWriter:
478
478
  ##
479
479
 
480
480
 
481
+ # @omlish-manifest
482
+ _CLI_MODULE = {'$omdev.cli.types.CliModule': {
483
+ 'cmd_name': 'importtrace',
484
+ 'mod_name': __name__,
485
+ }}
486
+
487
+
481
488
  def _main() -> None:
482
489
  if sys.version_info < REQUIRED_PYTHON_VERSION:
483
490
  raise EnvironmentError(f'Requires python {REQUIRED_PYTHON_VERSION}, got {sys.version_info} from {sys.executable}') # noqa