omdev 0.0.0.dev97__tar.gz → 0.0.0.dev98__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.
Files changed (147) hide show
  1. {omdev-0.0.0.dev97/omdev.egg-info → omdev-0.0.0.dev98}/PKG-INFO +8 -6
  2. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/.manifests.json +24 -12
  3. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/__about__.py +5 -2
  4. omdev-0.0.0.dev98/omdev/tools/doctools.py +108 -0
  5. omdev-0.0.0.dev98/omdev/tools/pawk/__init__.py +0 -0
  6. omdev-0.0.0.dev98/omdev/tools/pawk/__main__.py +4 -0
  7. omdev-0.0.0.dev98/omdev/tools/pawk/pawk.py +395 -0
  8. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98/omdev.egg-info}/PKG-INFO +8 -6
  9. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev.egg-info/SOURCES.txt +5 -2
  10. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev.egg-info/requires.txt +6 -4
  11. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/pyproject.toml +7 -5
  12. omdev-0.0.0.dev97/omdev/tools/rsttool.py +0 -60
  13. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/LICENSE +0 -0
  14. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/MANIFEST.in +0 -0
  15. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/README.rst +0 -0
  16. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/__init__.py +0 -0
  17. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/amalg/__init__.py +0 -0
  18. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/amalg/__main__.py +0 -0
  19. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/amalg/amalg.py +0 -0
  20. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/antlr/__init__.py +0 -0
  21. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/antlr/_antlr/__init__.py +0 -0
  22. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/antlr/consts.py +0 -0
  23. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/antlr/gen.py +0 -0
  24. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/bracepy.py +0 -0
  25. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/__init__.py +0 -0
  26. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/compute/__init__.py +0 -0
  27. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/compute/cache.py +0 -0
  28. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/compute/contexts.py +0 -0
  29. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/compute/currents.py +0 -0
  30. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/compute/fns.py +0 -0
  31. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/compute/resolvers.py +0 -0
  32. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/compute/storage.py +0 -0
  33. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/compute/types.py +0 -0
  34. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/data/__init__.py +0 -0
  35. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/data/actions.py +0 -0
  36. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/data/cache.py +0 -0
  37. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/data/consts.py +0 -0
  38. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/data/defaults.py +0 -0
  39. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/data/manifests.py +0 -0
  40. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cache/data/specs.py +0 -0
  41. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/__init__.py +0 -0
  42. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_boilerplate.cc +0 -0
  43. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/LICENSE +0 -0
  44. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/__init__.py +0 -0
  45. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/build_ext.py +0 -0
  46. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/compilers/__init__.py +0 -0
  47. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/compilers/ccompiler.py +0 -0
  48. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/compilers/options.py +0 -0
  49. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/compilers/unixccompiler.py +0 -0
  50. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/dir_util.py +0 -0
  51. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/errors.py +0 -0
  52. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/extension.py +0 -0
  53. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/file_util.py +0 -0
  54. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/modified.py +0 -0
  55. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/spawn.py +0 -0
  56. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/sysconfig.py +0 -0
  57. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/util.py +0 -0
  58. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/_distutils/version.py +0 -0
  59. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/build.py +0 -0
  60. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/cmake.py +0 -0
  61. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/importhook.py +0 -0
  62. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/magic.py +0 -0
  63. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cexts/scan.py +0 -0
  64. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/classdot.py +0 -0
  65. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cli/__init__.py +0 -0
  66. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cli/__main__.py +0 -0
  67. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cli/_pathhack.py +0 -0
  68. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cli/clicli.py +0 -0
  69. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cli/install.py +0 -0
  70. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cli/main.py +0 -0
  71. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cli/managers.py +0 -0
  72. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cli/types.py +0 -0
  73. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/clipboard/__init__.py +0 -0
  74. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/clipboard/clipboard.py +0 -0
  75. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/clipboard/darwin.py +0 -0
  76. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/cmake.py +0 -0
  77. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/findimports.py +0 -0
  78. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/findmagic.py +0 -0
  79. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/git.py +0 -0
  80. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/imgur.py +0 -0
  81. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/__init__.py +0 -0
  82. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/__main__.py +0 -0
  83. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/cli.py +0 -0
  84. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/inspect.py +0 -0
  85. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/providers.py +0 -0
  86. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/pyenv.py +0 -0
  87. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/resolvers.py +0 -0
  88. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/standalone.py +0 -0
  89. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/system.py +0 -0
  90. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/interp/types.py +0 -0
  91. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/manifests/__init__.py +0 -0
  92. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/manifests/build.py +0 -0
  93. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/manifests/load.py +0 -0
  94. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/manifests/types.py +0 -0
  95. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/mypy/__init__.py +0 -0
  96. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/mypy/debug.py +0 -0
  97. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/packaging/__init__.py +0 -0
  98. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/packaging/names.py +0 -0
  99. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/packaging/requires.py +0 -0
  100. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/packaging/specifiers.py +0 -0
  101. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/packaging/versions.py +0 -0
  102. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/precheck/__init__.py +0 -0
  103. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/precheck/__main__.py +0 -0
  104. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/precheck/base.py +0 -0
  105. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/precheck/git.py +0 -0
  106. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/precheck/lite.py +0 -0
  107. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/precheck/main.py +0 -0
  108. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/precheck/manifests.py +0 -0
  109. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/precheck/scripts.py +0 -0
  110. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/ptk/__init__.py +0 -0
  111. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/ptk/apps/__init__.py +0 -0
  112. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/ptk/apps/ncdu.py +0 -0
  113. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/pyproject/__init__.py +0 -0
  114. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/pyproject/__main__.py +0 -0
  115. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/pyproject/cexts.py +0 -0
  116. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/pyproject/cli.py +0 -0
  117. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/pyproject/configs.py +0 -0
  118. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/pyproject/pkg.py +0 -0
  119. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/pyproject/reqs.py +0 -0
  120. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/revisions.py +0 -0
  121. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/scripts/__init__.py +0 -0
  122. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/scripts/bumpversion.py +0 -0
  123. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/scripts/execrss.py +0 -0
  124. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/scripts/exectime.py +0 -0
  125. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/scripts/importtrace.py +0 -0
  126. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/scripts/interp.py +0 -0
  127. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/scripts/pyproject.py +0 -0
  128. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/scripts/slowcat.py +0 -0
  129. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/secrets.py +0 -0
  130. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tokens.py +0 -0
  131. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/toml/__init__.py +0 -0
  132. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/toml/parser.py +0 -0
  133. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/toml/writer.py +0 -0
  134. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/__init__.py +0 -0
  135. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/dockertools.py +0 -0
  136. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/gittools.py +0 -0
  137. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/importscan.py +0 -0
  138. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/mkrelimp.py +0 -0
  139. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/nbtools.py +0 -0
  140. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/piptools.py +0 -0
  141. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/proftools.py +0 -0
  142. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/tools/sqlrepl.py +0 -0
  143. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev/wheelfile.py +0 -0
  144. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev.egg-info/dependency_links.txt +0 -0
  145. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev.egg-info/entry_points.txt +0 -0
  146. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/omdev.egg-info/top_level.txt +0 -0
  147. {omdev-0.0.0.dev97 → omdev-0.0.0.dev98}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev97
3
+ Version: 0.0.0.dev98
4
4
  Summary: omdev
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,13 +12,14 @@ 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.dev97
15
+ Requires-Dist: omlish==0.0.0.dev98
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=24.10; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
19
- Requires-Dist: cffi~=1.17; extra == "all"
20
19
  Requires-Dist: pcpp~=1.30; extra == "all"
20
+ Requires-Dist: cffi~=1.17; extra == "all"
21
21
  Requires-Dist: docutils~=0.21; extra == "all"
22
+ Requires-Dist: markdown~=3.7; extra == "all"
22
23
  Requires-Dist: mypy~=1.11; extra == "all"
23
24
  Requires-Dist: gprof2dot~=2024.6; extra == "all"
24
25
  Requires-Dist: prompt-toolkit~=3.0; extra == "all"
@@ -28,10 +29,11 @@ Provides-Extra: black
28
29
  Requires-Dist: black~=24.10; extra == "black"
29
30
  Provides-Extra: c
30
31
  Requires-Dist: pycparser~=2.22; extra == "c"
31
- Requires-Dist: cffi~=1.17; extra == "c"
32
32
  Requires-Dist: pcpp~=1.30; extra == "c"
33
- Provides-Extra: docutils
34
- Requires-Dist: docutils~=0.21; extra == "docutils"
33
+ Requires-Dist: cffi~=1.17; extra == "c"
34
+ Provides-Extra: doc
35
+ Requires-Dist: docutils~=0.21; extra == "doc"
36
+ Requires-Dist: markdown~=3.7; extra == "doc"
35
37
  Provides-Extra: mypy
36
38
  Requires-Dist: mypy~=1.11; extra == "mypy"
37
39
  Provides-Extra: prof
@@ -203,6 +203,18 @@
203
203
  }
204
204
  }
205
205
  },
206
+ {
207
+ "module": ".tools.doctools",
208
+ "attr": "_CLI_MODULE",
209
+ "file": "omdev/tools/doctools.py",
210
+ "line": 103,
211
+ "value": {
212
+ "$.cli.types.CliModule": {
213
+ "cmd_name": "doc",
214
+ "mod_name": "omdev.tools.doctools"
215
+ }
216
+ }
217
+ },
206
218
  {
207
219
  "module": ".tools.gittools",
208
220
  "attr": "_CLI_MODULE",
@@ -254,6 +266,18 @@
254
266
  }
255
267
  }
256
268
  },
269
+ {
270
+ "module": ".tools.pawk.pawk",
271
+ "attr": "_CLI_MODULE",
272
+ "file": "omdev/tools/pawk/pawk.py",
273
+ "line": 390,
274
+ "value": {
275
+ "$.cli.types.CliModule": {
276
+ "cmd_name": "pawk",
277
+ "mod_name": "omdev.tools.pawk.pawk"
278
+ }
279
+ }
280
+ },
257
281
  {
258
282
  "module": ".tools.piptools",
259
283
  "attr": "_CLI_MODULE",
@@ -278,18 +302,6 @@
278
302
  }
279
303
  }
280
304
  },
281
- {
282
- "module": ".tools.rsttool",
283
- "attr": "_CLI_MODULE",
284
- "file": "omdev/tools/rsttool.py",
285
- "line": 55,
286
- "value": {
287
- "$.cli.types.CliModule": {
288
- "cmd_name": "rst",
289
- "mod_name": "omdev.tools.rsttool"
290
- }
291
- }
292
- },
293
305
  {
294
306
  "module": ".tools.sqlrepl",
295
307
  "attr": "_CLI_MODULE",
@@ -18,12 +18,15 @@ class Project(ProjectBase):
18
18
 
19
19
  'c': [
20
20
  'pycparser ~= 2.22',
21
- 'cffi ~= 1.17',
22
21
  'pcpp ~= 1.30',
22
+
23
+ 'cffi ~= 1.17',
23
24
  ],
24
25
 
25
- 'docutils': [
26
+ 'doc': [
26
27
  'docutils ~= 0.21',
28
+
29
+ 'markdown ~= 3.7',
27
30
  ],
28
31
 
29
32
  'mypy': [
@@ -0,0 +1,108 @@
1
+ """
2
+ TODO:
3
+ - omdev/rst.py *and* rsttool.py, when we want extracted helpers
4
+ """
5
+ import contextlib
6
+ import io
7
+ import os.path
8
+ import subprocess
9
+ import sys
10
+ import tempfile
11
+ import typing as ta
12
+
13
+ from omlish import argparse as ap
14
+ from omlish import check
15
+ from omlish import lang
16
+
17
+ from ..cli import CliModule
18
+
19
+
20
+ if ta.TYPE_CHECKING:
21
+ import docutils.core
22
+ import markdown
23
+ else:
24
+ docutils = lang.proxy_import('docutils', extras=['core'])
25
+ markdown = lang.proxy_import('markdown')
26
+
27
+
28
+ def rst2html(rst, report_level=None):
29
+ kwargs = {
30
+ 'writer_name': 'html',
31
+ 'settings_overrides': {
32
+ '_disable_config': True,
33
+ 'report_level': int(report_level) if report_level else 0,
34
+ },
35
+ }
36
+
37
+ target = io.StringIO()
38
+ with contextlib.redirect_stderr(target):
39
+ parts = docutils.core.publish_parts(rst, **kwargs) # type: ignore
40
+ html = parts['html_body']
41
+ warning = target.getvalue().strip()
42
+ return html, warning
43
+
44
+
45
+ def open_html(src: str, name: str) -> None:
46
+ check.non_empty_str(name)
47
+ out_dir = tempfile.mkdtemp()
48
+ out_file = os.path.join(out_dir, name + '.html')
49
+ with open(out_file, 'w') as f:
50
+ f.write(src)
51
+ subprocess.check_call(['open', out_file])
52
+
53
+
54
+ class Cli(ap.Cli):
55
+ def _read_file(self, input_file: str | None) -> tuple[str, str]:
56
+ if input_file is not None:
57
+ with open(input_file) as f:
58
+ src = f.read()
59
+ name = os.path.basename(input_file)
60
+
61
+ else:
62
+ src = sys.stdin.read()
63
+ name = 'stdin'
64
+
65
+ return src, name
66
+
67
+ @ap.command(
68
+ ap.arg('input-file', nargs='?'),
69
+ ap.arg('--report-level', type=int),
70
+ ap.arg('-O', '--open', action='store_true'),
71
+ )
72
+ def rst(self) -> None:
73
+ src, name = self._read_file(self.args.input_file)
74
+
75
+ html, warning = rst2html(
76
+ src,
77
+ report_level=self.args.report_level,
78
+ )
79
+
80
+ if warning:
81
+ sys.stderr.write(warning)
82
+
83
+ if self.args.open:
84
+ open_html(html, name)
85
+ else:
86
+ print(html)
87
+
88
+ @ap.command(
89
+ ap.arg('input-file', nargs='?'),
90
+ ap.arg('-O', '--open', action='store_true'),
91
+ )
92
+ def md(self):
93
+ src, name = self._read_file(self.args.input_file)
94
+
95
+ html = markdown.markdown(src)
96
+
97
+ if self.args.open:
98
+ open_html(html, name)
99
+ else:
100
+ print(html)
101
+
102
+
103
+ # @omlish-manifest
104
+ _CLI_MODULE = CliModule('doc', __name__)
105
+
106
+
107
+ if __name__ == '__main__':
108
+ Cli().call_and_exit()
File without changes
@@ -0,0 +1,4 @@
1
+ if __name__ == '__main__':
2
+ from .pawk import main
3
+
4
+ main()
@@ -0,0 +1,395 @@
1
+ #!/usr/bin/env python
2
+ # Copyright (C) 2018 Alec Thomas
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
5
+ # documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
6
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
7
+ # persons to whom the Software is furnished to do so, subject to the following conditions:
8
+ #
9
+ # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
10
+ # Software.
11
+ #
12
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13
+ # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
14
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
15
+ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16
+ # https://github.com/alecthomas/pawk/blob/d60f78399e8a01857ebd73415a00e7eb424043ab/pawk.py
17
+ """cat input | pawk [<options>] <expr>
18
+
19
+ A Python line-processor (like awk).
20
+
21
+ See https://github.com/alecthomas/pawk for details. Based on
22
+ http://code.activestate.com/recipes/437932/.
23
+ """
24
+ import argparse
25
+ import ast
26
+ import codecs
27
+ import contextlib
28
+ import inspect
29
+ import itertools
30
+ import os
31
+ import re
32
+ import sys
33
+ import types
34
+ import typing as ta
35
+
36
+ from omlish import check
37
+
38
+ from ...cli import CliModule
39
+
40
+
41
+ RESULT_VAR_NAME = '__result'
42
+
43
+ STRING_ESCAPE = 'unicode_escape'
44
+
45
+
46
+ # Store the last expression, if present, into variable var_name.
47
+ def save_last_expression(
48
+ tree: ast.Module,
49
+ var_name: str = RESULT_VAR_NAME,
50
+ ) -> ast.Module:
51
+ body = tree.body
52
+
53
+ node: ast.AST | None = body[-1] if len(body) else None
54
+
55
+ body.insert(
56
+ 0,
57
+ ast.Assign(
58
+ targets=[
59
+ ast.Name(
60
+ id=var_name,
61
+ ctx=ast.Store(),
62
+ ),
63
+ ],
64
+ value=ast.Constant(None),
65
+ ),
66
+ )
67
+
68
+ if node is not None and isinstance(node, ast.Expr):
69
+ body[-1] = ast.copy_location(
70
+ ast.Assign(
71
+ targets=[
72
+ ast.Name(
73
+ id=var_name,
74
+ ctx=ast.Store(),
75
+ ),
76
+ ],
77
+ value=node.value,
78
+ ),
79
+ node, # noqa
80
+ )
81
+
82
+ return ast.fix_missing_locations(tree)
83
+
84
+
85
+ def compile_command(text: str) -> types.CodeType:
86
+ mod = check.isinstance(compile(text, 'EXPR', 'exec', flags=ast.PyCF_ONLY_AST), ast.Module)
87
+ tree = save_last_expression(mod)
88
+ return compile(tree, 'EXPR', 'exec')
89
+
90
+
91
+ def eval_in_context(
92
+ codeobj: types.CodeType,
93
+ context: 'Context',
94
+ var_name: str = RESULT_VAR_NAME,
95
+ ) -> ta.Any:
96
+ exec(codeobj, globals(), context)
97
+ return context.pop(var_name, None)
98
+
99
+
100
+ class Action:
101
+ """Represents a single action to be applied to each line."""
102
+
103
+ def __init__(
104
+ self,
105
+ pattern: str | None = None,
106
+ cmd: str = 'l',
107
+ have_end_statement: bool = False,
108
+ negate: bool = False,
109
+ strict: bool = False,
110
+ ) -> None:
111
+ super().__init__()
112
+
113
+ self.delim = None
114
+ self.odelim = ' '
115
+ self.negate = negate
116
+ self.pattern = None if pattern is None else re.compile(pattern)
117
+ self.cmd = cmd
118
+ self.strict = strict
119
+ self._compile(have_end_statement)
120
+
121
+ @classmethod
122
+ def from_options(cls, options: ta.Any, arg: str) -> 'Action':
123
+ negate, pattern, cmd = Action._parse_command(arg)
124
+ return cls(
125
+ pattern=pattern,
126
+ cmd=cmd,
127
+ have_end_statement=(options.end is not None),
128
+ negate=negate,
129
+ strict=options.strict,
130
+ )
131
+
132
+ def _compile(self, have_end_statement: bool) -> None:
133
+ if not self.cmd:
134
+ if have_end_statement:
135
+ self.cmd = 't += line'
136
+ else:
137
+ self.cmd = 'l'
138
+ self._codeobj = compile_command(self.cmd)
139
+
140
+ def apply(self, context: 'Context', line: str) -> ta.Any:
141
+ """
142
+ Apply action to line.
143
+
144
+ :return: Line text or None.
145
+ """
146
+
147
+ match = self._match(line)
148
+ if match is None:
149
+ return None
150
+ context['m'] = match
151
+ try:
152
+ return eval_in_context(self._codeobj, context)
153
+ except Exception: # noqa
154
+ if not self.strict:
155
+ return None
156
+ raise
157
+
158
+ def _match(self, line: str) -> ta.Any:
159
+ if self.pattern is None:
160
+ return self.negate
161
+ match = self.pattern.search(line)
162
+ if match is not None:
163
+ return None if self.negate else match.groups()
164
+ elif self.negate:
165
+ return ()
166
+ else:
167
+ return None
168
+
169
+ @staticmethod
170
+ def _parse_command(arg: str) -> tuple[bool, str | None, str]:
171
+ match = re.match(r'(?ms)(?:(!)?/((?:\\.|[^/])+)/)?(.*)', arg)
172
+ negate, pattern, cmd = check.not_none(match).groups()
173
+ cmd = cmd.strip()
174
+ negate = bool(negate)
175
+ return negate, pattern, cmd
176
+
177
+
178
+ class Context(dict):
179
+ def apply(
180
+ self,
181
+ numz: int,
182
+ line: str,
183
+ headers: ta.Sequence[str] | None = None,
184
+ ) -> None:
185
+ l = line.rstrip()
186
+ f = l.split(self.delim)
187
+ self.update(line=line, l=l, n=numz + 1, f=f, nf=len(f))
188
+ if headers:
189
+ self.update(itertools.zip_longest(headers, f))
190
+
191
+ delim: str | None
192
+ odelim: str
193
+ line_separator: str
194
+
195
+ @classmethod
196
+ def from_options(
197
+ cls,
198
+ options: ta.Any,
199
+ modules: ta.Sequence[str],
200
+ ) -> 'Context':
201
+ self = cls()
202
+ self['t'] = ''
203
+ self['m'] = ()
204
+ if options.imports:
205
+ for imp in options.imports.split(','):
206
+ mod = __import__(imp.strip(), fromlist=['.'])
207
+ self.update((k, v) for k, v in inspect.getmembers(mod) if k[0] != '_')
208
+
209
+ self.delim = codecs.decode(options.delim, STRING_ESCAPE) if options.delim else None
210
+ self.odelim = codecs.decode(options.delim_out, STRING_ESCAPE)
211
+ self.line_separator = codecs.decode(options.line_separator, STRING_ESCAPE)
212
+
213
+ for m in modules:
214
+ try:
215
+ key = m.split('.')[0]
216
+ self[key] = __import__(m)
217
+ except Exception: # noqa
218
+ pass
219
+ return self
220
+
221
+
222
+ def process(
223
+ context: Context,
224
+ input: ta.TextIO, # noqa
225
+ output: ta.TextIO,
226
+ begin_statement: str | None,
227
+ actions: ta.Sequence[Action],
228
+ end_statement: str | None,
229
+ strict: bool,
230
+ header: bool,
231
+ ):
232
+ """Process a stream."""
233
+
234
+ # Override "print"
235
+ old_stdout = sys.stdout
236
+ sys.stdout = output
237
+ write = output.write
238
+
239
+ def write_result(result, when_true=None):
240
+ if result is True:
241
+ result = when_true
242
+ elif isinstance(result, (list, tuple)):
243
+ result = context.odelim.join(map(str, result))
244
+
245
+ if result is not None and result is not False:
246
+ result = str(result)
247
+ if not result.endswith(context.line_separator):
248
+ result = result.rstrip('\n') + context.line_separator
249
+ write(result)
250
+
251
+ try:
252
+ headers = None
253
+ if header:
254
+ line = input.readline()
255
+ context.apply(-1, line)
256
+ headers = context['f']
257
+
258
+ if begin_statement:
259
+ write_result(eval_in_context(compile_command(begin_statement), context))
260
+
261
+ for numz, line in enumerate(input):
262
+ context.apply(numz, line, headers=headers)
263
+ for action in actions:
264
+ write_result(action.apply(context, line), when_true=line)
265
+
266
+ if end_statement:
267
+ write_result(eval_in_context(compile_command(end_statement), context))
268
+
269
+ finally:
270
+ sys.stdout = old_stdout
271
+
272
+
273
+ def parse_commandline(argv: ta.Sequence[str]) -> tuple[ta.Any, ta.Sequence[str]]:
274
+ parser = argparse.ArgumentParser()
275
+ # parser.set_usage(__doc__.strip())
276
+ parser.add_argument(
277
+ '-I',
278
+ '--in_place',
279
+ dest='in_place',
280
+ help='modify given input file in-place',
281
+ metavar='<filename>',
282
+ )
283
+ parser.add_argument(
284
+ '-i',
285
+ '--import',
286
+ dest='imports',
287
+ help='comma-separated list of modules to "from x import *" from',
288
+ metavar='<modules>',
289
+ )
290
+ parser.add_argument(
291
+ '-F',
292
+ dest='delim',
293
+ help='input delimiter',
294
+ metavar='<delim>',
295
+ default=None,
296
+ )
297
+ parser.add_argument(
298
+ '-O',
299
+ dest='delim_out',
300
+ help='output delimiter',
301
+ metavar='<delim>',
302
+ default=' ',
303
+ )
304
+ parser.add_argument(
305
+ '-L',
306
+ dest='line_separator',
307
+ help='output line separator',
308
+ metavar='<delim>',
309
+ default='\n',
310
+ )
311
+ parser.add_argument(
312
+ '-B',
313
+ '--begin',
314
+ help='begin statement',
315
+ metavar='<statement>',
316
+ )
317
+ parser.add_argument(
318
+ '-E',
319
+ '--end',
320
+ help='end statement',
321
+ metavar='<statement>',
322
+ )
323
+ parser.add_argument(
324
+ '-s',
325
+ '--statement',
326
+ action='store_true',
327
+ help='DEPRECATED. retained for backward compatibility',
328
+ )
329
+ parser.add_argument(
330
+ '-H',
331
+ '--header',
332
+ action='store_true',
333
+ help='use first row as field variable names in subsequent rows',
334
+ )
335
+ parser.add_argument(
336
+ '--strict',
337
+ action='store_true',
338
+ help='abort on exceptions',
339
+ )
340
+ return parser.parse_known_args(argv[1:])
341
+
342
+
343
+ # For integration tests.
344
+ def run(
345
+ argv: ta.Sequence[str],
346
+ input: ta.TextIO, # noqa
347
+ output: ta.TextIO,
348
+ ) -> None:
349
+ options, args = parse_commandline(argv)
350
+
351
+ with contextlib.ExitStack() as es:
352
+ if options.in_place:
353
+ os.rename(options.in_place, options.in_place + '~')
354
+ input = es.enter_context(open(options.in_place + '~')) # noqa
355
+ output = es.enter_context(open(options.in_place, 'w'))
356
+
357
+ # Auto-import. This is not smart.
358
+ all_text = ' '.join([(options.begin or ''), ' '.join(args), (options.end or '')])
359
+ modules = re.findall(r'([\w.]+)+(?=\.\w+)\b', all_text)
360
+
361
+ context = Context.from_options(options, modules)
362
+ actions = [Action.from_options(options, arg) for arg in args]
363
+ if not actions:
364
+ actions = [Action.from_options(options, '')]
365
+
366
+ process(
367
+ context,
368
+ input,
369
+ output,
370
+ options.begin,
371
+ actions,
372
+ options.end,
373
+ options.strict,
374
+ options.header,
375
+ )
376
+
377
+
378
+ def main() -> None:
379
+ try:
380
+ run(sys.argv, sys.stdin, sys.stdout)
381
+ except OSError as e:
382
+ # Workaround for close failed in file object destructor: sys.excepthook is missing lost sys.stderr
383
+ # http://stackoverflow.com/questions/7955138/addressing-sys-excepthook-error-in-bash-script
384
+ sys.stderr.write(str(e) + '\n')
385
+ sys.exit(1)
386
+ except KeyboardInterrupt:
387
+ sys.exit(1)
388
+
389
+
390
+ # @omlish-manifest
391
+ _CLI_MODULE = CliModule('pawk', __name__)
392
+
393
+
394
+ if __name__ == '__main__':
395
+ main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: omdev
3
- Version: 0.0.0.dev97
3
+ Version: 0.0.0.dev98
4
4
  Summary: omdev
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,13 +12,14 @@ 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.dev97
15
+ Requires-Dist: omlish==0.0.0.dev98
16
16
  Provides-Extra: all
17
17
  Requires-Dist: black~=24.10; extra == "all"
18
18
  Requires-Dist: pycparser~=2.22; extra == "all"
19
- Requires-Dist: cffi~=1.17; extra == "all"
20
19
  Requires-Dist: pcpp~=1.30; extra == "all"
20
+ Requires-Dist: cffi~=1.17; extra == "all"
21
21
  Requires-Dist: docutils~=0.21; extra == "all"
22
+ Requires-Dist: markdown~=3.7; extra == "all"
22
23
  Requires-Dist: mypy~=1.11; extra == "all"
23
24
  Requires-Dist: gprof2dot~=2024.6; extra == "all"
24
25
  Requires-Dist: prompt-toolkit~=3.0; extra == "all"
@@ -28,10 +29,11 @@ Provides-Extra: black
28
29
  Requires-Dist: black~=24.10; extra == "black"
29
30
  Provides-Extra: c
30
31
  Requires-Dist: pycparser~=2.22; extra == "c"
31
- Requires-Dist: cffi~=1.17; extra == "c"
32
32
  Requires-Dist: pcpp~=1.30; extra == "c"
33
- Provides-Extra: docutils
34
- Requires-Dist: docutils~=0.21; extra == "docutils"
33
+ Requires-Dist: cffi~=1.17; extra == "c"
34
+ Provides-Extra: doc
35
+ Requires-Dist: docutils~=0.21; extra == "doc"
36
+ Requires-Dist: markdown~=3.7; extra == "doc"
35
37
  Provides-Extra: mypy
36
38
  Requires-Dist: mypy~=1.11; extra == "mypy"
37
39
  Provides-Extra: prof
@@ -131,11 +131,14 @@ omdev/toml/parser.py
131
131
  omdev/toml/writer.py
132
132
  omdev/tools/__init__.py
133
133
  omdev/tools/dockertools.py
134
+ omdev/tools/doctools.py
134
135
  omdev/tools/gittools.py
135
136
  omdev/tools/importscan.py
136
137
  omdev/tools/mkrelimp.py
137
138
  omdev/tools/nbtools.py
138
139
  omdev/tools/piptools.py
139
140
  omdev/tools/proftools.py
140
- omdev/tools/rsttool.py
141
- omdev/tools/sqlrepl.py
141
+ omdev/tools/sqlrepl.py
142
+ omdev/tools/pawk/__init__.py
143
+ omdev/tools/pawk/__main__.py
144
+ omdev/tools/pawk/pawk.py