omdev 0.0.0.dev28__py3-none-any.whl → 0.0.0.dev30__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of omdev might be problematic. Click here for more details.
- omdev/cache/compute/cache.py +120 -0
- omdev/cache/compute/contexts.py +137 -0
- omdev/cache/compute/currents.py +78 -0
- omdev/cache/compute/fns.py +157 -0
- omdev/cache/compute/resolvers.py +23 -0
- omdev/cache/compute/storage.py +39 -0
- omdev/cache/compute/types.py +144 -0
- omdev/cache/data/__init__.py +10 -6
- omdev/cache/data/actions.py +8 -2
- omdev/cache/data/cache.py +67 -32
- omdev/cache/data/defaults.py +3 -3
- omdev/cache/data/manifests.py +3 -3
- omdev/cache/data/specs.py +9 -6
- omdev/manifests.py +1 -1
- omdev/precheck/base.py +37 -0
- omdev/precheck/git.py +34 -0
- omdev/precheck/lite.py +135 -0
- omdev/precheck/precheck.py +5 -221
- omdev/precheck/scripts.py +42 -0
- omdev/pyproject/cli.py +5 -1
- omdev/scripts/interp.py +20 -5
- omdev/scripts/pyproject.py +25 -6
- omdev/tools/piptools.py +50 -0
- {omdev-0.0.0.dev28.dist-info → omdev-0.0.0.dev30.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev28.dist-info → omdev-0.0.0.dev30.dist-info}/RECORD +29 -22
- omdev/cache/comp/cache.py +0 -137
- omdev/cache/comp/contexts.py +0 -136
- omdev/cache/comp/fns.py +0 -115
- omdev/cache/comp/resolvers.py +0 -23
- omdev/cache/comp/types.py +0 -92
- /omdev/cache/{comp → compute}/__init__.py +0 -0
- {omdev-0.0.0.dev28.dist-info → omdev-0.0.0.dev30.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev28.dist-info → omdev-0.0.0.dev30.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev28.dist-info → omdev-0.0.0.dev30.dist-info}/top_level.txt +0 -0
omdev/precheck/precheck.py
CHANGED
|
@@ -17,28 +17,20 @@ TODO:
|
|
|
17
17
|
- https://github.com/pre-commit/pre-commit-hooks?tab=readme-ov-file#forbid-new-submodules
|
|
18
18
|
- don't check in .o's (omdev.ext import hook is dumb w build dir)
|
|
19
19
|
"""
|
|
20
|
-
import abc
|
|
21
20
|
import argparse
|
|
22
21
|
import asyncio
|
|
23
|
-
import dataclasses as dc
|
|
24
|
-
import glob
|
|
25
|
-
import inspect
|
|
26
22
|
import logging
|
|
27
23
|
import os.path
|
|
28
|
-
import stat
|
|
29
|
-
import subprocess
|
|
30
24
|
import sys
|
|
31
|
-
import textwrap
|
|
32
25
|
import typing as ta
|
|
33
26
|
|
|
34
|
-
from omdev import findimports
|
|
35
|
-
from omdev import findmagic
|
|
36
|
-
from omlish import cached
|
|
37
27
|
from omlish import logs
|
|
38
28
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
from .base import Precheck
|
|
30
|
+
from .base import PrecheckContext
|
|
31
|
+
from .git import GitBlacklistPrecheck
|
|
32
|
+
from .lite import LitePython8Precheck
|
|
33
|
+
from .scripts import ScriptDepsPrecheck
|
|
42
34
|
|
|
43
35
|
|
|
44
36
|
log = logging.getLogger(__name__)
|
|
@@ -47,214 +39,6 @@ log = logging.getLogger(__name__)
|
|
|
47
39
|
##
|
|
48
40
|
|
|
49
41
|
|
|
50
|
-
@dc.dataclass(frozen=True, kw_only=True)
|
|
51
|
-
class PrecheckContext:
|
|
52
|
-
src_roots: ta.Sequence[str]
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
##
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class Precheck(abc.ABC, ta.Generic[PrecheckConfigT]):
|
|
59
|
-
@dc.dataclass(frozen=True)
|
|
60
|
-
class Config:
|
|
61
|
-
pass
|
|
62
|
-
|
|
63
|
-
def __init__(self, context: PrecheckContext, config: PrecheckConfigT) -> None:
|
|
64
|
-
super().__init__()
|
|
65
|
-
self._context = context
|
|
66
|
-
self._config = config
|
|
67
|
-
|
|
68
|
-
@dc.dataclass(frozen=True)
|
|
69
|
-
class Violation:
|
|
70
|
-
pc: 'Precheck'
|
|
71
|
-
msg: str
|
|
72
|
-
|
|
73
|
-
@abc.abstractmethod
|
|
74
|
-
def run(self) -> ta.AsyncIterator[Violation]:
|
|
75
|
-
raise NotImplementedError
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
##
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class GitBlacklistPrecheck(Precheck['GitBlacklistPrecheck.Config']):
|
|
82
|
-
"""
|
|
83
|
-
TODO:
|
|
84
|
-
- globs
|
|
85
|
-
- regex
|
|
86
|
-
"""
|
|
87
|
-
|
|
88
|
-
@dc.dataclass(frozen=True)
|
|
89
|
-
class Config(Precheck.Config):
|
|
90
|
-
files: ta.Sequence[str] = (
|
|
91
|
-
'.env',
|
|
92
|
-
'secrets.yml',
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
def __init__(self, context: PrecheckContext, config: Config = Config()) -> None:
|
|
96
|
-
super().__init__(context, config)
|
|
97
|
-
|
|
98
|
-
async def run(self) -> ta.AsyncGenerator[Precheck.Violation, None]:
|
|
99
|
-
for f in self._config.files:
|
|
100
|
-
proc = await asyncio.create_subprocess_exec('git', 'status', '-s', f)
|
|
101
|
-
await proc.communicate()
|
|
102
|
-
if proc.returncode:
|
|
103
|
-
yield Precheck.Violation(self, f)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
##
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
class ScriptDepsPrecheck(Precheck['ScriptDepsPrecheck.Config']):
|
|
110
|
-
@dc.dataclass(frozen=True)
|
|
111
|
-
class Config(Precheck.Config):
|
|
112
|
-
pass
|
|
113
|
-
|
|
114
|
-
def __init__(self, context: PrecheckContext, config: Config = Config()) -> None:
|
|
115
|
-
super().__init__(context, config)
|
|
116
|
-
|
|
117
|
-
async def run(self) -> ta.AsyncGenerator[Precheck.Violation, None]:
|
|
118
|
-
for fp in findmagic.find_magic(
|
|
119
|
-
self._context.src_roots,
|
|
120
|
-
['# @omlish-script'],
|
|
121
|
-
['py'],
|
|
122
|
-
):
|
|
123
|
-
if not (stat.S_IXUSR & os.stat(fp).st_mode):
|
|
124
|
-
yield Precheck.Violation(self, f'script {fp} is not executable')
|
|
125
|
-
|
|
126
|
-
with open(fp) as f: # noqa # FIXME
|
|
127
|
-
src = f.read()
|
|
128
|
-
|
|
129
|
-
if not src.startswith('#!/usr/bin/env python3\n'):
|
|
130
|
-
yield Precheck.Violation(self, f'script {fp} lacks correct shebang')
|
|
131
|
-
|
|
132
|
-
imps = findimports.find_imports(fp)
|
|
133
|
-
deps = findimports.get_import_deps(imps)
|
|
134
|
-
if deps:
|
|
135
|
-
yield Precheck.Violation(self, f'script {fp} has deps: {deps}')
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
##
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
class LitePython8Precheck(Precheck['LitePython8Precheck.Config']):
|
|
142
|
-
@dc.dataclass(frozen=True)
|
|
143
|
-
class Config(Precheck.Config):
|
|
144
|
-
pass
|
|
145
|
-
|
|
146
|
-
def __init__(self, context: PrecheckContext, config: Config = Config()) -> None:
|
|
147
|
-
super().__init__(context, config)
|
|
148
|
-
|
|
149
|
-
#
|
|
150
|
-
|
|
151
|
-
@staticmethod
|
|
152
|
-
def _load_file_module(fp: str) -> None:
|
|
153
|
-
import os.path # noqa
|
|
154
|
-
import types # noqa
|
|
155
|
-
|
|
156
|
-
fp = os.path.abspath(fp)
|
|
157
|
-
|
|
158
|
-
with open(fp) as f:
|
|
159
|
-
src = f.read()
|
|
160
|
-
|
|
161
|
-
mn = os.path.basename(fp).rpartition('.')[0]
|
|
162
|
-
|
|
163
|
-
mod = types.ModuleType(mn)
|
|
164
|
-
mod.__name__ = mn
|
|
165
|
-
mod.__file__ = fp
|
|
166
|
-
mod.__builtins__ = __builtins__ # type: ignore
|
|
167
|
-
mod.__spec__ = None
|
|
168
|
-
|
|
169
|
-
code = compile(src, fp, 'exec')
|
|
170
|
-
exec(code, mod.__dict__, mod.__dict__)
|
|
171
|
-
|
|
172
|
-
@cached.function
|
|
173
|
-
def _load_file_module_payload(self) -> str:
|
|
174
|
-
return '\n'.join([
|
|
175
|
-
'import sys',
|
|
176
|
-
'fp = sys.argv[-1]',
|
|
177
|
-
'',
|
|
178
|
-
textwrap.dedent('\n'.join(inspect.getsource(LitePython8Precheck._load_file_module).splitlines()[2:])),
|
|
179
|
-
])
|
|
180
|
-
|
|
181
|
-
#
|
|
182
|
-
|
|
183
|
-
async def _run_script(self, fp: str) -> list[Precheck.Violation]:
|
|
184
|
-
log.debug('%s: loading script %s', self.__class__.__name__, fp)
|
|
185
|
-
|
|
186
|
-
vs: list[Precheck.Violation] = []
|
|
187
|
-
|
|
188
|
-
proc = await asyncio.create_subprocess_exec(
|
|
189
|
-
'.venvs/8/bin/python',
|
|
190
|
-
'-c',
|
|
191
|
-
self._load_file_module_payload(),
|
|
192
|
-
fp,
|
|
193
|
-
stderr=subprocess.PIPE,
|
|
194
|
-
)
|
|
195
|
-
|
|
196
|
-
_, stderr = await proc.communicate()
|
|
197
|
-
if proc.returncode != 0:
|
|
198
|
-
vs.append(Precheck.Violation(self, f'lite script {fp} failed to load in python8: {stderr.decode()}'))
|
|
199
|
-
|
|
200
|
-
return vs
|
|
201
|
-
|
|
202
|
-
async def _run_one_module(self, fp: str) -> list[Precheck.Violation]:
|
|
203
|
-
vs: list[Precheck.Violation] = []
|
|
204
|
-
|
|
205
|
-
mod = fp.rpartition('.')[0].replace(os.sep, '.')
|
|
206
|
-
|
|
207
|
-
log.debug('%s: loading module %s', self.__class__.__name__, mod)
|
|
208
|
-
|
|
209
|
-
proc = await asyncio.create_subprocess_exec(
|
|
210
|
-
'.venvs/8/bin/python',
|
|
211
|
-
'-c',
|
|
212
|
-
f'import {mod}',
|
|
213
|
-
stderr=subprocess.PIPE,
|
|
214
|
-
)
|
|
215
|
-
|
|
216
|
-
_, stderr = await proc.communicate()
|
|
217
|
-
if proc.returncode != 0:
|
|
218
|
-
vs.append(Precheck.Violation(self, f'lite module {fp} failed to import in python8: {stderr.decode()}')) # noqa
|
|
219
|
-
|
|
220
|
-
return vs
|
|
221
|
-
|
|
222
|
-
async def _run_module(self, fp: str) -> list[Precheck.Violation]:
|
|
223
|
-
vs: list[Precheck.Violation] = []
|
|
224
|
-
|
|
225
|
-
if fp.endswith('__init__.py'):
|
|
226
|
-
pfps = glob.glob(os.path.join(os.path.dirname(fp), '**/*.py'), recursive=True)
|
|
227
|
-
else:
|
|
228
|
-
pfps = [fp]
|
|
229
|
-
|
|
230
|
-
for pfp in pfps:
|
|
231
|
-
vs.extend(await self._run_one_module(pfp))
|
|
232
|
-
|
|
233
|
-
return vs
|
|
234
|
-
|
|
235
|
-
async def run(self) -> ta.AsyncGenerator[Precheck.Violation, None]:
|
|
236
|
-
for fp in findmagic.find_magic(
|
|
237
|
-
self._context.src_roots,
|
|
238
|
-
['# @omlish-lite'],
|
|
239
|
-
['py'],
|
|
240
|
-
):
|
|
241
|
-
with open(fp) as f: # noqa # FIXME
|
|
242
|
-
src = f.read()
|
|
243
|
-
|
|
244
|
-
is_script = '# @omlish-script' in src.splitlines()
|
|
245
|
-
|
|
246
|
-
if is_script:
|
|
247
|
-
for v in await self._run_script(fp):
|
|
248
|
-
yield v
|
|
249
|
-
|
|
250
|
-
else:
|
|
251
|
-
for v in await self._run_module(fp):
|
|
252
|
-
yield v
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
##
|
|
256
|
-
|
|
257
|
-
|
|
258
42
|
def _check_cmd(args) -> None:
|
|
259
43
|
if not os.path.isfile('pyproject.toml'):
|
|
260
44
|
raise RuntimeError('must run in project root')
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import dataclasses as dc
|
|
2
|
+
import os
|
|
3
|
+
import stat
|
|
4
|
+
import typing as ta
|
|
5
|
+
|
|
6
|
+
from omdev import findimports
|
|
7
|
+
from omdev import findmagic
|
|
8
|
+
|
|
9
|
+
from .base import Precheck
|
|
10
|
+
from .base import PrecheckContext
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ScriptDepsPrecheck(Precheck['ScriptDepsPrecheck.Config']):
|
|
17
|
+
@dc.dataclass(frozen=True)
|
|
18
|
+
class Config(Precheck.Config):
|
|
19
|
+
pass
|
|
20
|
+
|
|
21
|
+
def __init__(self, context: PrecheckContext, config: Config = Config()) -> None:
|
|
22
|
+
super().__init__(context, config)
|
|
23
|
+
|
|
24
|
+
async def run(self) -> ta.AsyncGenerator[Precheck.Violation, None]:
|
|
25
|
+
for fp in findmagic.find_magic(
|
|
26
|
+
self._context.src_roots,
|
|
27
|
+
['# @omlish-script'],
|
|
28
|
+
['py'],
|
|
29
|
+
):
|
|
30
|
+
if not (stat.S_IXUSR & os.stat(fp).st_mode):
|
|
31
|
+
yield Precheck.Violation(self, f'script {fp} is not executable')
|
|
32
|
+
|
|
33
|
+
with open(fp) as f: # noqa # FIXME
|
|
34
|
+
src = f.read()
|
|
35
|
+
|
|
36
|
+
if not src.startswith('#!/usr/bin/env python3\n'):
|
|
37
|
+
yield Precheck.Violation(self, f'script {fp} lacks correct shebang')
|
|
38
|
+
|
|
39
|
+
imps = findimports.find_imports(fp)
|
|
40
|
+
deps = findimports.get_import_deps(imps)
|
|
41
|
+
if deps:
|
|
42
|
+
yield Precheck.Violation(self, f'script {fp} has deps: {deps}')
|
omdev/pyproject/cli.py
CHANGED
|
@@ -8,7 +8,6 @@ TODO:
|
|
|
8
8
|
- build / package / publish / version roll
|
|
9
9
|
- {pkg_name: [src_dirs]}, default excludes, generate MANIFST.in, ...
|
|
10
10
|
- env vars - PYTHONPATH
|
|
11
|
-
- optional uv backend
|
|
12
11
|
|
|
13
12
|
lookit:
|
|
14
13
|
- https://pdm-project.org/en/latest/
|
|
@@ -158,6 +157,11 @@ class Venv:
|
|
|
158
157
|
if (sr := self._cfg.requires):
|
|
159
158
|
rr = RequirementsRewriter(self._name)
|
|
160
159
|
reqs = [rr.rewrite(req) for req in sr]
|
|
160
|
+
|
|
161
|
+
# TODO: automatically try slower uv download when it fails? lol
|
|
162
|
+
# Caused by: Failed to download distribution due to network timeout. Try increasing UV_HTTP_TIMEOUT (current value: 30s). # noqa
|
|
163
|
+
# UV_CONCURRENT_DOWNLOADS=4 UV_HTTP_TIMEOUT=3600
|
|
164
|
+
|
|
161
165
|
subprocess_check_call(
|
|
162
166
|
ve,
|
|
163
167
|
'-m',
|
omdev/scripts/interp.py
CHANGED
|
@@ -13,6 +13,7 @@ TODO:
|
|
|
13
13
|
import abc
|
|
14
14
|
import argparse
|
|
15
15
|
import collections
|
|
16
|
+
import contextlib
|
|
16
17
|
import dataclasses as dc
|
|
17
18
|
import datetime
|
|
18
19
|
import functools
|
|
@@ -1352,6 +1353,24 @@ class StandardLogHandler(ProxyLogHandler):
|
|
|
1352
1353
|
##
|
|
1353
1354
|
|
|
1354
1355
|
|
|
1356
|
+
@contextlib.contextmanager
|
|
1357
|
+
def _locking_logging_module_lock() -> ta.Iterator[None]:
|
|
1358
|
+
if hasattr(logging, '_acquireLock'):
|
|
1359
|
+
logging._acquireLock() # noqa
|
|
1360
|
+
try:
|
|
1361
|
+
yield
|
|
1362
|
+
finally:
|
|
1363
|
+
logging._releaseLock() # type: ignore # noqa
|
|
1364
|
+
|
|
1365
|
+
elif hasattr(logging, '_lock'):
|
|
1366
|
+
# https://github.com/python/cpython/commit/74723e11109a320e628898817ab449b3dad9ee96
|
|
1367
|
+
with logging._lock: # noqa
|
|
1368
|
+
yield
|
|
1369
|
+
|
|
1370
|
+
else:
|
|
1371
|
+
raise Exception("Can't find lock in logging module")
|
|
1372
|
+
|
|
1373
|
+
|
|
1355
1374
|
def configure_standard_logging(
|
|
1356
1375
|
level: ta.Union[int, str] = logging.INFO,
|
|
1357
1376
|
*,
|
|
@@ -1359,8 +1378,7 @@ def configure_standard_logging(
|
|
|
1359
1378
|
target: ta.Optional[logging.Logger] = None,
|
|
1360
1379
|
force: bool = False,
|
|
1361
1380
|
) -> ta.Optional[StandardLogHandler]:
|
|
1362
|
-
|
|
1363
|
-
try:
|
|
1381
|
+
with _locking_logging_module_lock():
|
|
1364
1382
|
if target is None:
|
|
1365
1383
|
target = logging.root
|
|
1366
1384
|
|
|
@@ -1400,9 +1418,6 @@ def configure_standard_logging(
|
|
|
1400
1418
|
|
|
1401
1419
|
return StandardLogHandler(handler)
|
|
1402
1420
|
|
|
1403
|
-
finally:
|
|
1404
|
-
logging._releaseLock() # type: ignore # noqa
|
|
1405
|
-
|
|
1406
1421
|
|
|
1407
1422
|
########################################
|
|
1408
1423
|
# ../../../omlish/lite/runtime.py
|
omdev/scripts/pyproject.py
CHANGED
|
@@ -11,7 +11,6 @@ TODO:
|
|
|
11
11
|
- build / package / publish / version roll
|
|
12
12
|
- {pkg_name: [src_dirs]}, default excludes, generate MANIFST.in, ...
|
|
13
13
|
- env vars - PYTHONPATH
|
|
14
|
-
- optional uv backend
|
|
15
14
|
|
|
16
15
|
lookit:
|
|
17
16
|
- https://pdm-project.org/en/latest/
|
|
@@ -30,6 +29,7 @@ import base64
|
|
|
30
29
|
import collections
|
|
31
30
|
import collections.abc
|
|
32
31
|
import concurrent.futures as cf
|
|
32
|
+
import contextlib
|
|
33
33
|
import csv
|
|
34
34
|
import dataclasses as dc
|
|
35
35
|
import datetime
|
|
@@ -2800,6 +2800,24 @@ class StandardLogHandler(ProxyLogHandler):
|
|
|
2800
2800
|
##
|
|
2801
2801
|
|
|
2802
2802
|
|
|
2803
|
+
@contextlib.contextmanager
|
|
2804
|
+
def _locking_logging_module_lock() -> ta.Iterator[None]:
|
|
2805
|
+
if hasattr(logging, '_acquireLock'):
|
|
2806
|
+
logging._acquireLock() # noqa
|
|
2807
|
+
try:
|
|
2808
|
+
yield
|
|
2809
|
+
finally:
|
|
2810
|
+
logging._releaseLock() # type: ignore # noqa
|
|
2811
|
+
|
|
2812
|
+
elif hasattr(logging, '_lock'):
|
|
2813
|
+
# https://github.com/python/cpython/commit/74723e11109a320e628898817ab449b3dad9ee96
|
|
2814
|
+
with logging._lock: # noqa
|
|
2815
|
+
yield
|
|
2816
|
+
|
|
2817
|
+
else:
|
|
2818
|
+
raise Exception("Can't find lock in logging module")
|
|
2819
|
+
|
|
2820
|
+
|
|
2803
2821
|
def configure_standard_logging(
|
|
2804
2822
|
level: ta.Union[int, str] = logging.INFO,
|
|
2805
2823
|
*,
|
|
@@ -2807,8 +2825,7 @@ def configure_standard_logging(
|
|
|
2807
2825
|
target: ta.Optional[logging.Logger] = None,
|
|
2808
2826
|
force: bool = False,
|
|
2809
2827
|
) -> ta.Optional[StandardLogHandler]:
|
|
2810
|
-
|
|
2811
|
-
try:
|
|
2828
|
+
with _locking_logging_module_lock():
|
|
2812
2829
|
if target is None:
|
|
2813
2830
|
target = logging.root
|
|
2814
2831
|
|
|
@@ -2848,9 +2865,6 @@ def configure_standard_logging(
|
|
|
2848
2865
|
|
|
2849
2866
|
return StandardLogHandler(handler)
|
|
2850
2867
|
|
|
2851
|
-
finally:
|
|
2852
|
-
logging._releaseLock() # type: ignore # noqa
|
|
2853
|
-
|
|
2854
2868
|
|
|
2855
2869
|
########################################
|
|
2856
2870
|
# ../../../omlish/lite/marshal.py
|
|
@@ -4929,6 +4943,11 @@ class Venv:
|
|
|
4929
4943
|
if (sr := self._cfg.requires):
|
|
4930
4944
|
rr = RequirementsRewriter(self._name)
|
|
4931
4945
|
reqs = [rr.rewrite(req) for req in sr]
|
|
4946
|
+
|
|
4947
|
+
# TODO: automatically try slower uv download when it fails? lol
|
|
4948
|
+
# Caused by: Failed to download distribution due to network timeout. Try increasing UV_HTTP_TIMEOUT (current value: 30s). # noqa
|
|
4949
|
+
# UV_CONCURRENT_DOWNLOADS=4 UV_HTTP_TIMEOUT=3600
|
|
4950
|
+
|
|
4932
4951
|
subprocess_check_call(
|
|
4933
4952
|
ve,
|
|
4934
4953
|
'-m',
|
omdev/tools/piptools.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import urllib.request
|
|
3
|
+
import xml.etree.ElementTree as ET # noqa
|
|
4
|
+
|
|
5
|
+
from omlish import argparse as ap
|
|
6
|
+
from omlish import check
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
PYPI_URL = 'https://pypi.org/'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Cli(ap.Cli):
|
|
13
|
+
@ap.command(
|
|
14
|
+
ap.arg('package'),
|
|
15
|
+
)
|
|
16
|
+
def lookup_latest_version(self) -> None:
|
|
17
|
+
pkg_name = check.non_empty_str(self.args.package)
|
|
18
|
+
with urllib.request.urlopen(f'{PYPI_URL}rss/project/{pkg_name}/releases.xml') as resp: # noqa
|
|
19
|
+
rss = resp.read()
|
|
20
|
+
doc = ET.parse(io.BytesIO(rss)) # noqa
|
|
21
|
+
latest = check.not_none(doc.find('./channel/item/title')).text
|
|
22
|
+
print(latest)
|
|
23
|
+
|
|
24
|
+
@ap.command(
|
|
25
|
+
ap.arg('file'),
|
|
26
|
+
ap.arg('-w', '--write', action='store_true'),
|
|
27
|
+
ap.arg('-q', '--quiet', action='store_true'),
|
|
28
|
+
)
|
|
29
|
+
def filter_dev_deps(self) -> None:
|
|
30
|
+
with open(self.args.file) as f:
|
|
31
|
+
src = f.read()
|
|
32
|
+
|
|
33
|
+
out = []
|
|
34
|
+
for l in src.splitlines(keepends=True):
|
|
35
|
+
if l.startswith('-e'):
|
|
36
|
+
continue
|
|
37
|
+
out.append(l)
|
|
38
|
+
|
|
39
|
+
new_src = ''.join(out)
|
|
40
|
+
|
|
41
|
+
if not self.args.quiet:
|
|
42
|
+
print(new_src)
|
|
43
|
+
|
|
44
|
+
if self.args.write:
|
|
45
|
+
with open(self.args.file, 'w') as f:
|
|
46
|
+
f.write(new_src)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == '__main__':
|
|
50
|
+
Cli()()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev30
|
|
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.dev30
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: pycparser ~=2.22 ; extra == 'all'
|
|
18
18
|
Requires-Dist: cffi ~=1.17 ; extra == 'all'
|
|
@@ -7,7 +7,7 @@ omdev/cmake.py,sha256=Diy2ry65806dQP125DAstD3w46z_wszMH7PwC2-6iik,4578
|
|
|
7
7
|
omdev/findimports.py,sha256=P8v4I1tm6g-PEWJiNwAKxErvWwL-Nop83vAuwq1kR5A,2246
|
|
8
8
|
omdev/findmagic.py,sha256=DhBYHHP_dzwM5pIh21xnQPnkZ2YmAXCjithsr7X0ScU,2357
|
|
9
9
|
omdev/git.py,sha256=OzP4xHVboaa7GhS-mg4F3lYWf3HLa5aMm6V6PtIw_3U,2137
|
|
10
|
-
omdev/manifests.py,sha256=
|
|
10
|
+
omdev/manifests.py,sha256=jGqG3u8AQwaGUga449SA1-HwfWyEbrj2MCHQP5jqpO4,6580
|
|
11
11
|
omdev/revisions.py,sha256=U657hf4zeEN32y3g4CzqCAodx_HlfkHj2cIIKALNFDo,5009
|
|
12
12
|
omdev/tokens.py,sha256=GusxQ1Cd_eiScuR8XTTtc9QFhOgYviYGBZmFnn3Hj7s,756
|
|
13
13
|
omdev/wheelfile.py,sha256=yfupGcGkbFlmzGzKU64k_vmOKpaKnUlDWxeGn2KdekU,10005
|
|
@@ -15,19 +15,21 @@ omdev/amalg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
15
15
|
omdev/amalg/__main__.py,sha256=OE1udULO1g4McUbeg1CoHbSm4hbQ2kcE3ffEGxlnPh4,69
|
|
16
16
|
omdev/amalg/amalg.py,sha256=g7wwcPE2G9qmzh8M9eZAscOYWKo3ldI8bNxEXFnmzLE,14064
|
|
17
17
|
omdev/cache/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
omdev/cache/
|
|
19
|
-
omdev/cache/
|
|
20
|
-
omdev/cache/
|
|
21
|
-
omdev/cache/
|
|
22
|
-
omdev/cache/
|
|
23
|
-
omdev/cache/
|
|
24
|
-
omdev/cache/
|
|
25
|
-
omdev/cache/
|
|
26
|
-
omdev/cache/data/
|
|
18
|
+
omdev/cache/compute/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
omdev/cache/compute/cache.py,sha256=pEbcTSQavhX7M0olzR8AOCtHx7tMnMnEDEfTPQVY5uE,3602
|
|
20
|
+
omdev/cache/compute/contexts.py,sha256=OKOHOIj8JSEHmCKMY9G_zpKkLAkGuXcFXvzY5SXqCMA,3231
|
|
21
|
+
omdev/cache/compute/currents.py,sha256=D1Ls5Sd7FX2aPO5wpyEwTSmkz50sxkwCs37Amb0urH8,1425
|
|
22
|
+
omdev/cache/compute/fns.py,sha256=_1xU7qw1O57OsTp17RFjFTBO1M2t54RL-CGdl-0cTBk,4175
|
|
23
|
+
omdev/cache/compute/resolvers.py,sha256=9dq0mt__emp8CdNDWPVUr_dCkTOn7ar6nw0F2QH6XpQ,566
|
|
24
|
+
omdev/cache/compute/storage.py,sha256=woCUqHg8ZrwLEejRG3zu1L5ZXxGNNXveh3E8FnlEkjc,941
|
|
25
|
+
omdev/cache/compute/types.py,sha256=NpCTTJHDmpERjrbO6dh9TEzHuP6-vOuoX3ym9sA0ukc,2639
|
|
26
|
+
omdev/cache/data/__init__.py,sha256=SQXtugLceRif463rcoklpQ33pxYLgEIm0xiI6NvOI6M,301
|
|
27
|
+
omdev/cache/data/actions.py,sha256=TX6DPbOzQY6S2MSTPnsG53BQ61NNPWuLeCXa-MF-W2g,1109
|
|
28
|
+
omdev/cache/data/cache.py,sha256=WSsbFyFRT_IQFYQCrmUpaTvs9DRglLmCnhguOzdJ6p4,5753
|
|
27
29
|
omdev/cache/data/consts.py,sha256=d6W_aeMqgah6PmPYi9RA8Be54oQ4BcNCy8kDQ7FlB_Q,26
|
|
28
|
-
omdev/cache/data/defaults.py,sha256=
|
|
29
|
-
omdev/cache/data/manifests.py,sha256=
|
|
30
|
-
omdev/cache/data/specs.py,sha256=
|
|
30
|
+
omdev/cache/data/defaults.py,sha256=HrapVUIf9Ozu3qSfRPyQj-vx-dz6Yyedjb-k3yV4CW8,277
|
|
31
|
+
omdev/cache/data/manifests.py,sha256=CupK71fL3_PnDzUqjrWLNt64KfGKF-K4ycMkT5p0gPA,979
|
|
32
|
+
omdev/cache/data/specs.py,sha256=EB_JLIFe47ETCtAk8BD6oY6qhM7U_nOkILJfnLaVafI,2351
|
|
31
33
|
omdev/cexts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
34
|
omdev/cexts/_boilerplate.cc,sha256=aOWF_5C2pqnIrkT1ykEaL7N2pIpamW6pdXriRbd3lvs,1725
|
|
33
35
|
omdev/cexts/build.py,sha256=F3z1-CjDlEM-Gzi5IunKUBO52qdH_pMsFylobTdGJnI,2654
|
|
@@ -65,19 +67,23 @@ omdev/mypy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
65
67
|
omdev/mypy/debug.py,sha256=WcZw-3Z1njg_KFGqi3DB6RuqbBa3dLArJnjVCuY1Mn0,3003
|
|
66
68
|
omdev/precheck/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
69
|
omdev/precheck/__main__.py,sha256=wKF_2KP2Yn1hKDEOCGR_fm5zu9UHMWCZtuEmWjpprrU,72
|
|
68
|
-
omdev/precheck/
|
|
70
|
+
omdev/precheck/base.py,sha256=a_lGoFM-QhL8u8XDUYFhb-feEyfPbP4j8lcmNO51sHY,732
|
|
71
|
+
omdev/precheck/git.py,sha256=APC5Ln7x0zDrQiGPRWPsBcVJK3vWhbU-brqR5M63JQA,849
|
|
72
|
+
omdev/precheck/lite.py,sha256=MLeDZP2UexNZzYTcSx4-LrhA97kCKn8tXrGkhsJb6I0,3649
|
|
73
|
+
omdev/precheck/precheck.py,sha256=LUqh501TpLgBL_ZBW-enEMqaYnWzPMViECpnHGKaCIc,2462
|
|
74
|
+
omdev/precheck/scripts.py,sha256=qq6MXkxgrYngPg5pWnXH4uRSuRkP3mFqbeml1UmvGBc,1265
|
|
69
75
|
omdev/pyproject/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
70
76
|
omdev/pyproject/__main__.py,sha256=gFhR9DikwDZk0LqgdR3qq_aXQHThUOPllDmHDOfnFAU,67
|
|
71
77
|
omdev/pyproject/cexts.py,sha256=x13piOOnNrYbA17qZLDVuR0p1sqhgEwpk4FtImX-klM,4281
|
|
72
|
-
omdev/pyproject/cli.py,sha256=
|
|
78
|
+
omdev/pyproject/cli.py,sha256=UKheeQ8E1vZpR2My3ykelDxD_Mcu3O0zA1HqkkAH0cs,10911
|
|
73
79
|
omdev/pyproject/configs.py,sha256=K9H5cGwVLgHi8wKwtYvlXHZ9ThtmnI4jo8JAb-t1-70,2859
|
|
74
80
|
omdev/pyproject/pkg.py,sha256=GlZvDcLbo7HmiV2SgQnJdgAswr9IoJpy5gOeTRXG2RM,12576
|
|
75
81
|
omdev/pyproject/reqs.py,sha256=coq21cdWQIPs06-iuRnwc6F2Sf-IxpqoT6DEMhol2kA,2298
|
|
76
82
|
omdev/scripts/__init__.py,sha256=MKCvUAEQwsIvwLixwtPlpBqmkMXLCnjjXyAXvVpDwVk,91
|
|
77
83
|
omdev/scripts/bumpversion.py,sha256=Kn7fo73Hs8uJh3Hi3EIyLOlzLPWAC6dwuD_lZ3cIzuY,1064
|
|
78
84
|
omdev/scripts/execrss.py,sha256=HzDNmwXOO8fMwIRXw9q8CUnVfLFCQASyU2tfY_y2Vf8,324
|
|
79
|
-
omdev/scripts/interp.py,sha256=
|
|
80
|
-
omdev/scripts/pyproject.py,sha256=
|
|
85
|
+
omdev/scripts/interp.py,sha256=cJ1iprqgMZONNTJeXQ3gvyp7-UQqKiRstdRw-jR3xFI,69254
|
|
86
|
+
omdev/scripts/pyproject.py,sha256=01U-hNp4NTU-OnNOYE8UK_2T_1Ai3-fbyOvOdCbzdsw,153367
|
|
81
87
|
omdev/toml/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
82
88
|
omdev/toml/parser.py,sha256=84bn09uhYHwQGyfww6Rw6y1RxPAE_HDltODOSakcqDM,29186
|
|
83
89
|
omdev/toml/writer.py,sha256=dwz_Qw8z5Z_nmWpXqch63W6S_j6n256erb7AGFTVzB4,2872
|
|
@@ -86,13 +92,14 @@ omdev/tools/dockertools.py,sha256=0RoUThTqv4ySJZX0aufYeQWD2bp-BMplQ8Y4WvDpguA,52
|
|
|
86
92
|
omdev/tools/gittools.py,sha256=zPy2D5WDs-CbwT86_T_hbaq5yCuss5e-ouUccXC6xlg,578
|
|
87
93
|
omdev/tools/importscan.py,sha256=XRLiasVSaTIp-jnO0-Nfhi0t6gnv_hVy5j2nVfEvuMI,3831
|
|
88
94
|
omdev/tools/importtrace.py,sha256=oDry9CwIv5h96wSaTVKJ0qQ5vMGxYE5oBtfF-GYNLJs,13430
|
|
95
|
+
omdev/tools/piptools.py,sha256=P2Nq8OzRuLxay1uQgqaWf3Iz6PFVhFKmVaBwxNbbzwU,1274
|
|
89
96
|
omdev/tools/rst.py,sha256=6dWk8QZHoGiLSuBw3TKsXZjjFK6wWBEtPi9krdCLKKg,977
|
|
90
97
|
omdev/tools/sqlrepl.py,sha256=v9uVQ4nvquSXcQVYIFq34ikumSILvKqzD6lUKLcncCE,5646
|
|
91
98
|
omdev/versioning/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
92
99
|
omdev/versioning/specifiers.py,sha256=6Odf9e6farwlPRsD_YqwTfYKG-BXn_dIcKtqfkhfodI,17432
|
|
93
100
|
omdev/versioning/versions.py,sha256=ei2eopEsJq3zSMJmezK1nzZgikgCdxFtnF3f69nCRZQ,12246
|
|
94
|
-
omdev-0.0.0.
|
|
95
|
-
omdev-0.0.0.
|
|
96
|
-
omdev-0.0.0.
|
|
97
|
-
omdev-0.0.0.
|
|
98
|
-
omdev-0.0.0.
|
|
101
|
+
omdev-0.0.0.dev30.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
|
102
|
+
omdev-0.0.0.dev30.dist-info/METADATA,sha256=D_vc3bQN6-PBXjlDMj_rVGwp8a_XeyCDGtcJVLihokw,1252
|
|
103
|
+
omdev-0.0.0.dev30.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
104
|
+
omdev-0.0.0.dev30.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
|
105
|
+
omdev-0.0.0.dev30.dist-info/RECORD,,
|