omdev 0.0.0.dev416__py3-none-any.whl → 0.0.0.dev500__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/{.manifests.json → .omlish-manifests.json} +23 -47
- omdev/README.md +51 -0
- omdev/__about__.py +12 -8
- omdev/amalg/cli/main.py +1 -2
- omdev/amalg/gen/gen.py +49 -6
- omdev/amalg/gen/imports.py +1 -1
- omdev/amalg/gen/manifests.py +1 -1
- omdev/amalg/gen/resources.py +1 -1
- omdev/amalg/gen/srcfiles.py +26 -3
- omdev/amalg/gen/strip.py +1 -1
- omdev/amalg/gen/types.py +1 -1
- omdev/amalg/gen/typing.py +1 -1
- omdev/amalg/info.py +32 -0
- omdev/cache/compute/storage.py +3 -1
- omdev/cache/data/actions.py +1 -1
- omdev/cache/data/cache.py +2 -2
- omdev/cache/data/specs.py +1 -1
- omdev/cexts/_boilerplate.cc +2 -3
- omdev/cexts/_distutils/build_ext.py +5 -2
- omdev/cexts/_distutils/compilers/ccompiler.py +5 -2
- omdev/cexts/_distutils/compilers/options.py +3 -0
- omdev/cexts/_distutils/compilers/unixccompiler.py +6 -2
- omdev/cexts/_distutils/dir_util.py +6 -2
- omdev/cexts/_distutils/errors.py +3 -0
- omdev/cexts/_distutils/extension.py +3 -0
- omdev/cexts/_distutils/file_util.py +6 -2
- omdev/cexts/_distutils/modified.py +3 -0
- omdev/cexts/_distutils/spawn.py +6 -2
- omdev/cexts/_distutils/sysconfig.py +3 -0
- omdev/cexts/_distutils/util.py +6 -2
- omdev/cexts/_distutils/version.py +3 -0
- omdev/cexts/cmake.py +5 -3
- omdev/cexts/scan.py +1 -2
- omdev/ci/cache.py +7 -3
- omdev/ci/cli.py +6 -4
- omdev/ci/docker/buildcaching.py +3 -1
- omdev/ci/docker/cache.py +2 -1
- omdev/ci/docker/cacheserved/cache.py +4 -1
- omdev/ci/docker/cacheserved/manifests.py +2 -2
- omdev/ci/docker/dataserver.py +2 -2
- omdev/ci/docker/imagepulling.py +2 -1
- omdev/ci/docker/packing.py +1 -1
- omdev/ci/docker/repositories.py +2 -1
- omdev/ci/github/api/clients.py +8 -4
- omdev/ci/github/api/v1/client.py +4 -1
- omdev/ci/github/api/v2/api.py +2 -0
- omdev/ci/github/api/v2/azure.py +4 -1
- omdev/ci/github/api/v2/client.py +4 -1
- omdev/cli/clicli.py +37 -7
- omdev/clipboard/clipboard.py +1 -1
- omdev/cmake.py +2 -1
- omdev/cmdlog/cli.py +1 -2
- omdev/dataclasses/_dumping.py +1960 -0
- omdev/dataclasses/_template.py +22 -0
- omdev/dataclasses/cli.py +7 -2
- omdev/dataclasses/codegen.py +342 -62
- omdev/dataclasses/dumping.py +200 -0
- omdev/dataserver/handlers.py +3 -2
- omdev/dataserver/targets.py +2 -2
- omdev/imgur.py +2 -2
- omdev/interp/cli.py +1 -1
- omdev/interp/inspect.py +2 -1
- omdev/interp/providers/base.py +3 -2
- omdev/interp/providers/standalone.py +4 -1
- omdev/interp/providers/system.py +2 -2
- omdev/interp/pyenv/install.py +2 -1
- omdev/interp/pyenv/provider.py +2 -2
- omdev/interp/types.py +3 -2
- omdev/interp/uv/provider.py +40 -2
- omdev/interp/uv/uv.py +2 -2
- omdev/interp/venvs.py +3 -2
- omdev/irc/messages/base.py +50 -0
- omdev/irc/messages/formats.py +92 -0
- omdev/irc/messages/messages.py +775 -0
- omdev/irc/messages/parsing.py +99 -0
- omdev/irc/numerics/formats.py +97 -0
- omdev/irc/numerics/numerics.py +865 -0
- omdev/irc/numerics/types.py +59 -0
- omdev/irc/protocol/LICENSE +11 -0
- omdev/irc/protocol/__init__.py +61 -0
- omdev/irc/protocol/consts.py +6 -0
- omdev/irc/protocol/errors.py +30 -0
- omdev/irc/protocol/message.py +21 -0
- omdev/irc/protocol/nuh.py +55 -0
- omdev/irc/protocol/parsing.py +158 -0
- omdev/irc/protocol/rendering.py +153 -0
- omdev/irc/protocol/tags.py +102 -0
- omdev/irc/protocol/utils.py +30 -0
- omdev/manifests/_dumping.py +529 -136
- omdev/manifests/building.py +6 -3
- omdev/manifests/main.py +1 -1
- omdev/markdown/__init__.py +0 -0
- omdev/markdown/incparse.py +116 -0
- omdev/markdown/tokens.py +51 -0
- omdev/oci/data.py +2 -2
- omdev/oci/datarefs.py +2 -2
- omdev/oci/media.py +2 -2
- omdev/oci/repositories.py +3 -2
- omdev/packaging/marshal.py +9 -9
- omdev/packaging/requires.py +6 -6
- omdev/packaging/revisions.py +5 -2
- omdev/packaging/specifiers.py +41 -42
- omdev/packaging/versions.py +10 -10
- omdev/packaging/wheelfile.py +4 -2
- omdev/precheck/blanklines.py +66 -0
- omdev/precheck/caches.py +1 -1
- omdev/precheck/imports.py +14 -1
- omdev/precheck/lite.py +2 -2
- omdev/precheck/main.py +5 -5
- omdev/precheck/unicode.py +39 -15
- omdev/py/asts/__init__.py +0 -0
- omdev/py/asts/parents.py +28 -0
- omdev/py/asts/toplevel.py +123 -0
- omdev/py/asts/visitors.py +18 -0
- omdev/py/attrdocs.py +6 -7
- omdev/py/bracepy.py +12 -4
- omdev/py/docstrings/numpydoc.py +4 -4
- omdev/py/reprs.py +32 -0
- omdev/py/scripts/execstat.py +31 -26
- omdev/py/srcheaders.py +1 -1
- omdev/py/tokens/__init__.py +0 -0
- omdev/{tokens → py/tokens}/utils.py +2 -1
- omdev/py/tools/importscan.py +2 -2
- omdev/py/tools/mkrelimp.py +3 -4
- omdev/py/tools/pipdepup.py +686 -0
- omdev/pyproject/cli.py +1 -1
- omdev/pyproject/pkg.py +197 -48
- omdev/pyproject/reqs.py +36 -10
- omdev/pyproject/tools/__init__.py +0 -0
- omdev/pyproject/tools/aboutdeps.py +60 -0
- omdev/pyproject/venvs.py +12 -2
- omdev/rs/__init__.py +0 -0
- omdev/scripts/ci.py +9551 -6982
- omdev/scripts/interp.py +1323 -892
- omdev/scripts/lib/__init__.py +0 -0
- omdev/scripts/lib/inject.py +2086 -0
- omdev/scripts/lib/logs.py +2175 -0
- omdev/scripts/lib/marshal.py +1731 -0
- omdev/scripts/pyproject.py +4979 -1874
- omdev/tools/docker.py +19 -7
- omdev/tools/git/cli.py +56 -16
- omdev/tools/git/messages.py +2 -2
- omdev/tools/json/cli.py +6 -6
- omdev/tools/json/formats.py +2 -0
- omdev/tools/json/parsing.py +5 -5
- omdev/tools/json/processing.py +6 -3
- omdev/tools/json/rendering.py +2 -2
- omdev/tools/jsonview/cli.py +49 -65
- omdev/tools/jsonview/resources/jsonview.html.j2 +43 -0
- omdev/tools/pawk/README.md +195 -0
- omdev/tools/pawk/pawk.py +2 -2
- omdev/tools/pip.py +8 -0
- omdev/tui/__init__.py +0 -0
- omdev/tui/apps/__init__.py +0 -0
- omdev/tui/apps/edit/__init__.py +0 -0
- omdev/tui/apps/edit/main.py +167 -0
- omdev/tui/apps/irc/__init__.py +0 -0
- omdev/tui/apps/irc/__main__.py +4 -0
- omdev/tui/apps/irc/app.py +286 -0
- omdev/tui/apps/irc/client.py +187 -0
- omdev/tui/apps/irc/commands.py +175 -0
- omdev/tui/apps/irc/main.py +26 -0
- omdev/tui/apps/markdown/__init__.py +0 -0
- omdev/tui/apps/markdown/__main__.py +11 -0
- omdev/{ptk → tui/apps}/markdown/cli.py +5 -7
- omdev/tui/rich/__init__.py +46 -0
- omdev/tui/rich/console2.py +20 -0
- omdev/tui/rich/markdown2.py +186 -0
- omdev/tui/textual/__init__.py +265 -0
- omdev/tui/textual/app2.py +16 -0
- omdev/tui/textual/autocomplete/LICENSE +21 -0
- omdev/tui/textual/autocomplete/__init__.py +33 -0
- omdev/tui/textual/autocomplete/matching.py +226 -0
- omdev/tui/textual/autocomplete/paths.py +202 -0
- omdev/tui/textual/autocomplete/widget.py +612 -0
- omdev/tui/textual/debug/__init__.py +10 -0
- omdev/tui/textual/debug/dominfo.py +151 -0
- omdev/tui/textual/debug/screen.py +24 -0
- omdev/tui/textual/devtools.py +187 -0
- omdev/tui/textual/drivers2.py +55 -0
- omdev/tui/textual/logging2.py +20 -0
- omdev/tui/textual/types.py +45 -0
- {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/METADATA +18 -12
- omdev-0.0.0.dev500.dist-info/RECORD +386 -0
- omdev/ptk/__init__.py +0 -103
- omdev/ptk/apps/ncdu.py +0 -167
- omdev/ptk/confirm.py +0 -60
- omdev/ptk/markdown/LICENSE +0 -22
- omdev/ptk/markdown/__init__.py +0 -10
- omdev/ptk/markdown/__main__.py +0 -11
- omdev/ptk/markdown/border.py +0 -94
- omdev/ptk/markdown/markdown.py +0 -390
- omdev/ptk/markdown/parser.py +0 -42
- omdev/ptk/markdown/styles.py +0 -29
- omdev/ptk/markdown/tags.py +0 -299
- omdev/ptk/markdown/utils.py +0 -366
- omdev/pyproject/cexts.py +0 -110
- omdev/tools/antlr/__main__.py +0 -11
- omdev/tools/antlr/cli.py +0 -62
- omdev/tools/antlr/consts.py +0 -7
- omdev/tools/antlr/gen.py +0 -188
- omdev-0.0.0.dev416.dist-info/RECORD +0 -332
- /omdev/{ptk/apps → irc}/__init__.py +0 -0
- /omdev/{tokens → irc/messages}/__init__.py +0 -0
- /omdev/{tools/antlr → irc/numerics}/__init__.py +0 -0
- /omdev/{tokens → py/tokens}/all.py +0 -0
- /omdev/{tokens → py/tokens}/tokenizert.py +0 -0
- {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/licenses/LICENSE +0 -0
- {omdev-0.0.0.dev416.dist-info → omdev-0.0.0.dev500.dist-info}/top_level.txt +0 -0
omdev/pyproject/pkg.py
CHANGED
|
@@ -28,16 +28,19 @@ vcs+protocol://repo_url/#egg=pkg&subdirectory=pkg_dir
|
|
|
28
28
|
import abc
|
|
29
29
|
import dataclasses as dc
|
|
30
30
|
import importlib
|
|
31
|
+
import inspect
|
|
31
32
|
import os.path
|
|
32
33
|
import shutil
|
|
33
34
|
import sys
|
|
34
35
|
import tempfile
|
|
36
|
+
import textwrap
|
|
35
37
|
import types
|
|
36
38
|
import typing as ta
|
|
37
39
|
|
|
38
40
|
from omlish.formats.toml.writer import TomlWriter
|
|
41
|
+
from omlish.lite.abstract import Abstract
|
|
39
42
|
from omlish.lite.cached import cached_nullary
|
|
40
|
-
from omlish.
|
|
43
|
+
from omlish.logs.modules import get_module_logger
|
|
41
44
|
from omlish.subprocesses.sync import subprocesses
|
|
42
45
|
|
|
43
46
|
from ..cexts.magic import CextMagic
|
|
@@ -45,10 +48,13 @@ from ..magic.find import find_magic_files
|
|
|
45
48
|
from ..packaging.revisions import GitRevisionAdder
|
|
46
49
|
|
|
47
50
|
|
|
51
|
+
log = get_module_logger(globals()) # noqa
|
|
52
|
+
|
|
53
|
+
|
|
48
54
|
##
|
|
49
55
|
|
|
50
56
|
|
|
51
|
-
class BasePyprojectPackageGenerator(
|
|
57
|
+
class BasePyprojectPackageGenerator(Abstract):
|
|
52
58
|
def __init__(
|
|
53
59
|
self,
|
|
54
60
|
dir_name: str,
|
|
@@ -87,7 +93,7 @@ class BasePyprojectPackageGenerator(abc.ABC):
|
|
|
87
93
|
|
|
88
94
|
def _write_git_ignore(self) -> None:
|
|
89
95
|
with open(os.path.join(self._pkg_dir(), '.gitignore'), 'w') as f:
|
|
90
|
-
f.write('\n'.join(self._GIT_IGNORE))
|
|
96
|
+
f.write('\n'.join([*self._GIT_IGNORE, '']))
|
|
91
97
|
|
|
92
98
|
#
|
|
93
99
|
|
|
@@ -256,6 +262,7 @@ class BasePyprojectPackageGenerator(abc.ABC):
|
|
|
256
262
|
)
|
|
257
263
|
|
|
258
264
|
if output_dir is not None:
|
|
265
|
+
log.info(lambda: f'Copying {dist_dir} to {output_dir}')
|
|
259
266
|
for fn in os.listdir(dist_dir):
|
|
260
267
|
shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(output_dir, fn))
|
|
261
268
|
|
|
@@ -311,7 +318,11 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
311
318
|
st = dict(specs.setuptools)
|
|
312
319
|
pyp_dct['tool.setuptools'] = st
|
|
313
320
|
|
|
314
|
-
|
|
321
|
+
for k in [
|
|
322
|
+
'cext',
|
|
323
|
+
'rs',
|
|
324
|
+
]:
|
|
325
|
+
st.pop(k, None)
|
|
315
326
|
|
|
316
327
|
#
|
|
317
328
|
|
|
@@ -333,7 +344,7 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
333
344
|
# '*.c',
|
|
334
345
|
# '*.cc',
|
|
335
346
|
# '*.h',
|
|
336
|
-
# '.manifests.json',
|
|
347
|
+
# '.omlish-manifests.json',
|
|
337
348
|
# 'LICENSE',
|
|
338
349
|
# ],
|
|
339
350
|
# }
|
|
@@ -384,13 +395,20 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
384
395
|
def children(self) -> ta.Sequence[BasePyprojectPackageGenerator]:
|
|
385
396
|
out: ta.List[BasePyprojectPackageGenerator] = []
|
|
386
397
|
|
|
387
|
-
if self.build_specs().setuptools.get('
|
|
398
|
+
if self.build_specs().setuptools.get('cext'):
|
|
388
399
|
out.append(_PyprojectCextPackageGenerator(
|
|
389
400
|
self._dir_name,
|
|
390
401
|
self._pkgs_root,
|
|
391
402
|
pkg_suffix='-cext',
|
|
392
403
|
))
|
|
393
404
|
|
|
405
|
+
if self.build_specs().setuptools.get('rs'):
|
|
406
|
+
out.append(_PyprojectRsPackageGenerator(
|
|
407
|
+
self._dir_name,
|
|
408
|
+
self._pkgs_root,
|
|
409
|
+
pkg_suffix='-rs',
|
|
410
|
+
))
|
|
411
|
+
|
|
394
412
|
if self.build_specs().pyproject.get('cli_scripts'):
|
|
395
413
|
out.append(_PyprojectCliPackageGenerator(
|
|
396
414
|
self._dir_name,
|
|
@@ -401,10 +419,67 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
401
419
|
return out
|
|
402
420
|
|
|
403
421
|
|
|
404
|
-
|
|
422
|
+
##
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
class _PyprojectExtensionPackageGenerator(BasePyprojectPackageGenerator, Abstract):
|
|
426
|
+
#
|
|
427
|
+
|
|
428
|
+
def _build_project_dict(self) -> ta.Dict[str, ta.Any]:
|
|
429
|
+
prj = dict(self.build_specs().pyproject)
|
|
430
|
+
|
|
431
|
+
prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
|
|
432
|
+
prj['name'] += self._pkg_suffix
|
|
433
|
+
|
|
434
|
+
for k in [
|
|
435
|
+
'optional_dependencies',
|
|
436
|
+
'entry_points',
|
|
437
|
+
'scripts',
|
|
438
|
+
'cli_scripts',
|
|
439
|
+
]:
|
|
440
|
+
prj.pop(k, None)
|
|
441
|
+
|
|
442
|
+
return prj
|
|
443
|
+
|
|
444
|
+
def _build_setuptools_dict(self) -> ta.Dict[str, ta.Any]:
|
|
445
|
+
st = dict(self.build_specs().setuptools)
|
|
446
|
+
|
|
447
|
+
for k in [
|
|
448
|
+
'cext',
|
|
449
|
+
'rs',
|
|
450
|
+
|
|
451
|
+
'find_packages',
|
|
452
|
+
'package_data',
|
|
453
|
+
'manifest_in',
|
|
454
|
+
]:
|
|
455
|
+
st.pop(k, None)
|
|
456
|
+
|
|
457
|
+
return st
|
|
405
458
|
|
|
459
|
+
#
|
|
460
|
+
|
|
461
|
+
@dc.dataclass(frozen=True)
|
|
462
|
+
class FileContents:
|
|
463
|
+
pyproject_dct: ta.Mapping[str, ta.Any]
|
|
464
|
+
setup_py: str
|
|
465
|
+
|
|
466
|
+
@abc.abstractmethod
|
|
467
|
+
def file_contents(self) -> FileContents:
|
|
468
|
+
raise NotImplementedError
|
|
406
469
|
|
|
407
|
-
|
|
470
|
+
#
|
|
471
|
+
|
|
472
|
+
def _write_file_contents(self) -> None:
|
|
473
|
+
fc = self.file_contents()
|
|
474
|
+
|
|
475
|
+
with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
|
|
476
|
+
TomlWriter(f).write_root(fc.pyproject_dct)
|
|
477
|
+
|
|
478
|
+
with open(os.path.join(self._pkg_dir(), 'setup.py'), 'w') as f:
|
|
479
|
+
f.write(fc.setup_py)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
class _PyprojectCextPackageGenerator(_PyprojectExtensionPackageGenerator):
|
|
408
483
|
@cached_nullary
|
|
409
484
|
def find_cext_srcs(self) -> ta.Sequence[str]:
|
|
410
485
|
return sorted(find_magic_files(
|
|
@@ -415,14 +490,10 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
415
490
|
|
|
416
491
|
#
|
|
417
492
|
|
|
418
|
-
@dc.dataclass(frozen=True)
|
|
419
|
-
class FileContents:
|
|
420
|
-
pyproject_dct: ta.Mapping[str, ta.Any]
|
|
421
|
-
setup_py: str
|
|
422
|
-
|
|
423
493
|
@cached_nullary
|
|
424
|
-
def file_contents(self) -> FileContents:
|
|
425
|
-
|
|
494
|
+
def file_contents(self) -> _PyprojectExtensionPackageGenerator.FileContents:
|
|
495
|
+
prj = self._build_project_dict()
|
|
496
|
+
st = self._build_setuptools_dict()
|
|
426
497
|
|
|
427
498
|
#
|
|
428
499
|
|
|
@@ -433,33 +504,9 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
433
504
|
'build-backend': 'setuptools.build_meta',
|
|
434
505
|
}
|
|
435
506
|
|
|
436
|
-
prj = specs.pyproject
|
|
437
|
-
prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
|
|
438
|
-
prj['name'] += self._pkg_suffix
|
|
439
|
-
for k in [
|
|
440
|
-
'optional_dependencies',
|
|
441
|
-
'entry_points',
|
|
442
|
-
'scripts',
|
|
443
|
-
'cli_scripts',
|
|
444
|
-
]:
|
|
445
|
-
prj.pop(k, None)
|
|
446
|
-
|
|
447
507
|
pyp_dct['project'] = prj
|
|
448
|
-
|
|
449
|
-
#
|
|
450
|
-
|
|
451
|
-
st = dict(specs.setuptools)
|
|
452
508
|
pyp_dct['tool.setuptools'] = st
|
|
453
509
|
|
|
454
|
-
for k in [
|
|
455
|
-
'cexts',
|
|
456
|
-
|
|
457
|
-
'find_packages',
|
|
458
|
-
'package_data',
|
|
459
|
-
'manifest_in',
|
|
460
|
-
]:
|
|
461
|
-
st.pop(k, None)
|
|
462
|
-
|
|
463
510
|
pyp_dct['tool.setuptools.packages.find'] = {
|
|
464
511
|
'include': [],
|
|
465
512
|
}
|
|
@@ -469,12 +516,17 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
469
516
|
ext_lines = []
|
|
470
517
|
|
|
471
518
|
for ext_src in self.find_cext_srcs():
|
|
519
|
+
ext_lang = ext_src.rpartition('.')[2]
|
|
520
|
+
compile_args = {
|
|
521
|
+
'c': ['-std=c11'],
|
|
522
|
+
'cc': ['-std=c++20'],
|
|
523
|
+
}.get(ext_lang, [])
|
|
472
524
|
ext_name = ext_src.rpartition('.')[0].replace(os.sep, '.')
|
|
473
525
|
ext_lines.extend([
|
|
474
526
|
'st.Extension(',
|
|
475
527
|
f" name='{ext_name}',",
|
|
476
528
|
f" sources=['{ext_src}'],",
|
|
477
|
-
|
|
529
|
+
f' extra_compile_args={compile_args!r},',
|
|
478
530
|
'),',
|
|
479
531
|
])
|
|
480
532
|
|
|
@@ -485,7 +537,7 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
485
537
|
'st.setup(',
|
|
486
538
|
' ext_modules=[',
|
|
487
539
|
*[' ' + l for l in ext_lines],
|
|
488
|
-
' ]',
|
|
540
|
+
' ],',
|
|
489
541
|
')',
|
|
490
542
|
'',
|
|
491
543
|
])
|
|
@@ -497,14 +549,110 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
497
549
|
src,
|
|
498
550
|
)
|
|
499
551
|
|
|
500
|
-
def _write_file_contents(self) -> None:
|
|
501
|
-
fc = self.file_contents()
|
|
502
552
|
|
|
503
|
-
|
|
504
|
-
|
|
553
|
+
class _PyprojectRsPackageGenerator(_PyprojectExtensionPackageGenerator):
|
|
554
|
+
@cached_nullary
|
|
555
|
+
def find_rs_dirs(self) -> ta.Sequence[str]:
|
|
556
|
+
return sorted(
|
|
557
|
+
dp
|
|
558
|
+
for dp, dns, fns in os.walk(self._dir_name)
|
|
559
|
+
for fn in fns
|
|
560
|
+
if fn == '.omlish-rs-ext'
|
|
561
|
+
)
|
|
505
562
|
|
|
506
|
-
|
|
507
|
-
|
|
563
|
+
#
|
|
564
|
+
|
|
565
|
+
@staticmethod
|
|
566
|
+
def _sdist_patch_body() -> None:
|
|
567
|
+
def _patch_sdist():
|
|
568
|
+
def _sdist_add_defaults(old, self):
|
|
569
|
+
import os.path
|
|
570
|
+
|
|
571
|
+
old(self)
|
|
572
|
+
|
|
573
|
+
if self.distribution.rust_extensions and len(self.distribution.rust_extensions) > 0:
|
|
574
|
+
build_rust = self.get_finalized_command('build_rust') # noqa
|
|
575
|
+
for ext in build_rust.extensions:
|
|
576
|
+
ext_dir = os.path.dirname(ext.path)
|
|
577
|
+
for n in os.listdir(ext_dir):
|
|
578
|
+
if n.startswith('.') or n == 'target':
|
|
579
|
+
continue
|
|
580
|
+
p = os.path.join(ext_dir, n)
|
|
581
|
+
if os.path.isfile(p):
|
|
582
|
+
self.filelist.append(p)
|
|
583
|
+
elif os.path.isdir(p):
|
|
584
|
+
self.filelist.extend(os.path.join(dp, f) for dp, dn, fn in os.walk(p) for f in fn)
|
|
585
|
+
|
|
586
|
+
# Sadly, we can't just subclass sdist and override it via cmdclass because manifest_maker calls
|
|
587
|
+
# `sdist.add_defaults` as an unbound function, not a bound method:
|
|
588
|
+
# https://github.com/pypa/setuptools/blob/9c4d383631d3951fcae0afd73b5d08ff5a262976/setuptools/command/egg_info.py#L581
|
|
589
|
+
from setuptools.command.sdist import sdist # noqa
|
|
590
|
+
setattr(sdist, 'add_defaults', (lambda old: lambda sdist: _sdist_add_defaults(old, sdist))(sdist.add_defaults)) # noqa
|
|
591
|
+
|
|
592
|
+
_patch_sdist()
|
|
593
|
+
|
|
594
|
+
@cached_nullary
|
|
595
|
+
def sdist_patch_code(self) -> str:
|
|
596
|
+
return textwrap.dedent(''.join(inspect.getsource(self._sdist_patch_body).splitlines(keepends=True)[2:])).strip()
|
|
597
|
+
|
|
598
|
+
#
|
|
599
|
+
|
|
600
|
+
@cached_nullary
|
|
601
|
+
def file_contents(self) -> _PyprojectExtensionPackageGenerator.FileContents:
|
|
602
|
+
prj = self._build_project_dict()
|
|
603
|
+
st = self._build_setuptools_dict()
|
|
604
|
+
|
|
605
|
+
#
|
|
606
|
+
|
|
607
|
+
pyp_dct = {}
|
|
608
|
+
|
|
609
|
+
pyp_dct['build-system'] = {
|
|
610
|
+
'requires': ['setuptools', 'setuptools-rust'],
|
|
611
|
+
'build-backend': 'setuptools.build_meta',
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
pyp_dct['project'] = prj
|
|
615
|
+
pyp_dct['tool.setuptools'] = st
|
|
616
|
+
|
|
617
|
+
pyp_dct['tool.setuptools.packages.find'] = {
|
|
618
|
+
'include': [],
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
#
|
|
622
|
+
|
|
623
|
+
ext_lines: list = []
|
|
624
|
+
|
|
625
|
+
for ext_dir in self.find_rs_dirs(): # noqa
|
|
626
|
+
ext_name = ext_dir.replace(os.sep, '.')
|
|
627
|
+
ext_lines.extend([
|
|
628
|
+
'st_rs.RustExtension(',
|
|
629
|
+
f" '{ext_name}',",
|
|
630
|
+
f" path='{ext_dir}/Cargo.toml',",
|
|
631
|
+
'),',
|
|
632
|
+
])
|
|
633
|
+
|
|
634
|
+
src = '\n'.join([
|
|
635
|
+
'import setuptools as st',
|
|
636
|
+
'import setuptools_rust as st_rs',
|
|
637
|
+
'',
|
|
638
|
+
'',
|
|
639
|
+
self.sdist_patch_code(),
|
|
640
|
+
'',
|
|
641
|
+
'',
|
|
642
|
+
'st.setup(',
|
|
643
|
+
' rust_extensions=[',
|
|
644
|
+
*[' ' + l for l in ext_lines],
|
|
645
|
+
' ],',
|
|
646
|
+
')',
|
|
647
|
+
'',
|
|
648
|
+
])
|
|
649
|
+
|
|
650
|
+
#
|
|
651
|
+
|
|
652
|
+
return self.FileContents(
|
|
653
|
+
pyp_dct,
|
|
654
|
+
src,
|
|
655
|
+
)
|
|
508
656
|
|
|
509
657
|
|
|
510
658
|
##
|
|
@@ -549,7 +697,8 @@ class _PyprojectCliPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
549
697
|
pyp_dct['tool.setuptools'] = st
|
|
550
698
|
|
|
551
699
|
for k in [
|
|
552
|
-
'
|
|
700
|
+
'cext',
|
|
701
|
+
'rs',
|
|
553
702
|
|
|
554
703
|
'find_packages',
|
|
555
704
|
'package_data',
|
omdev/pyproject/reqs.py
CHANGED
|
@@ -4,11 +4,18 @@ TODO:
|
|
|
4
4
|
"""
|
|
5
5
|
# ruff: noqa: UP007 UP045
|
|
6
6
|
import os.path
|
|
7
|
+
import re
|
|
7
8
|
import tempfile
|
|
8
9
|
import typing as ta
|
|
9
10
|
|
|
10
11
|
from omlish.lite.cached import cached_nullary
|
|
11
|
-
from omlish.
|
|
12
|
+
from omlish.logs.modules import get_module_logger
|
|
13
|
+
|
|
14
|
+
from ..packaging.requires import RequiresParserSyntaxError
|
|
15
|
+
from ..packaging.requires import parse_requirement
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
log = get_module_logger(globals()) # noqa
|
|
12
19
|
|
|
13
20
|
|
|
14
21
|
##
|
|
@@ -17,11 +24,14 @@ from omlish.lite.logs import log
|
|
|
17
24
|
class RequirementsRewriter:
|
|
18
25
|
def __init__(
|
|
19
26
|
self,
|
|
27
|
+
*,
|
|
20
28
|
venv: ta.Optional[str] = None,
|
|
29
|
+
only_pats: ta.Optional[ta.Sequence[re.Pattern]] = None,
|
|
21
30
|
) -> None:
|
|
22
31
|
super().__init__()
|
|
23
32
|
|
|
24
33
|
self._venv = venv
|
|
34
|
+
self._only_pats = only_pats
|
|
25
35
|
|
|
26
36
|
@cached_nullary
|
|
27
37
|
def _tmp_dir(self) -> str:
|
|
@@ -37,17 +47,33 @@ class RequirementsRewriter:
|
|
|
37
47
|
out_lines = []
|
|
38
48
|
|
|
39
49
|
for l in in_lines:
|
|
40
|
-
if
|
|
41
|
-
lp, _, rp = l.partition(self.VENV_MAGIC)
|
|
42
|
-
rp = rp.partition('#')[0]
|
|
50
|
+
if l.split('#')[0].strip():
|
|
43
51
|
omit = False
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
|
|
53
|
+
if self.VENV_MAGIC in l:
|
|
54
|
+
lp, _, rp = l.partition(self.VENV_MAGIC)
|
|
55
|
+
rp = rp.partition('#')[0]
|
|
56
|
+
vs = set(rp.split())
|
|
57
|
+
nvs = {v[1:] for v in vs if v.startswith('!')}
|
|
58
|
+
pvs = {v for v in vs if not v.startswith('!')}
|
|
59
|
+
if (
|
|
60
|
+
(nvs and self._venv in nvs) or
|
|
61
|
+
(pvs and self._venv not in pvs)
|
|
62
|
+
):
|
|
63
|
+
omit = True
|
|
64
|
+
|
|
65
|
+
if (
|
|
66
|
+
not omit and
|
|
67
|
+
(ops := self._only_pats) is not None and
|
|
68
|
+
not l.strip().startswith('-')
|
|
69
|
+
):
|
|
70
|
+
try:
|
|
71
|
+
pr = parse_requirement(l.split('#')[0].strip())
|
|
72
|
+
except RequiresParserSyntaxError:
|
|
73
|
+
pass
|
|
49
74
|
else:
|
|
50
|
-
|
|
75
|
+
if not any(op.fullmatch(pr.name) for op in ops):
|
|
76
|
+
omit = True
|
|
51
77
|
|
|
52
78
|
if omit:
|
|
53
79
|
out_lines.append('# OMITTED: ' + l)
|
|
File without changes
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- pyproject api!
|
|
4
|
+
"""
|
|
5
|
+
import importlib.metadata
|
|
6
|
+
import re
|
|
7
|
+
import sys
|
|
8
|
+
|
|
9
|
+
from omlish.formats.toml.parser import toml_loads
|
|
10
|
+
|
|
11
|
+
from ...packaging.names import canonicalize_name
|
|
12
|
+
from ...packaging.requires import parse_requirement
|
|
13
|
+
from ...packaging.specifiers import Specifier
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _main() -> None:
|
|
20
|
+
dist_dct = {}
|
|
21
|
+
for dist in importlib.metadata.distributions(paths=sys.path):
|
|
22
|
+
dist_cn = canonicalize_name(dist.metadata['Name'], validate=True)
|
|
23
|
+
if dist_cn in dist_dct:
|
|
24
|
+
continue
|
|
25
|
+
dist_dct[dist_cn] = dist
|
|
26
|
+
|
|
27
|
+
#
|
|
28
|
+
|
|
29
|
+
with open('pyproject.toml') as f:
|
|
30
|
+
dct = toml_loads(f.read())
|
|
31
|
+
|
|
32
|
+
pkgs = dct['tool']['omlish']['pyproject']['pkgs']
|
|
33
|
+
|
|
34
|
+
for pkg in pkgs:
|
|
35
|
+
pkg_about = importlib.import_module('.'.join([pkg, '__about__']))
|
|
36
|
+
pkg_prj = pkg_about.Project
|
|
37
|
+
|
|
38
|
+
pkg_opt_deps = {d for ds in pkg_prj.optional_dependencies.values() for d in ds}
|
|
39
|
+
for opt_dep in sorted(pkg_opt_deps):
|
|
40
|
+
opt_req = parse_requirement(opt_dep)
|
|
41
|
+
|
|
42
|
+
opt_cn = canonicalize_name(opt_req.name, validate=True)
|
|
43
|
+
|
|
44
|
+
opt_spec = Specifier(opt_req.specifier)
|
|
45
|
+
if re.fullmatch(r'~=\s*\d+(\.\d+)*', str(opt_spec)):
|
|
46
|
+
opt_spec = Specifier(str(opt_spec) + '.0')
|
|
47
|
+
|
|
48
|
+
if opt_cn in pkgs:
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
opt_dist = dist_dct[opt_cn]
|
|
52
|
+
opt_ver = opt_dist.version
|
|
53
|
+
|
|
54
|
+
# print((opt_dep, opt_spec, opt_ver))
|
|
55
|
+
if not opt_spec.contains(opt_ver):
|
|
56
|
+
print(f'{pkg} :: {opt_cn} : {opt_spec} ! {opt_ver}')
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == '__main__':
|
|
60
|
+
_main()
|
omdev/pyproject/venvs.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# ruff: noqa: UP006 UP007 UP045
|
|
2
2
|
import glob
|
|
3
3
|
import os.path
|
|
4
|
+
import re
|
|
4
5
|
import typing as ta
|
|
5
6
|
|
|
6
7
|
from omlish.lite.cached import async_cached_nullary
|
|
7
8
|
from omlish.lite.cached import cached_nullary
|
|
8
|
-
from omlish.
|
|
9
|
+
from omlish.logs.modules import get_module_logger
|
|
9
10
|
|
|
10
11
|
from ..interp.venvs import InterpVenv
|
|
11
12
|
from ..interp.venvs import InterpVenvRequirementsProcessor
|
|
@@ -13,6 +14,9 @@ from .configs import VenvConfig
|
|
|
13
14
|
from .reqs import RequirementsRewriter
|
|
14
15
|
|
|
15
16
|
|
|
17
|
+
log = get_module_logger(globals()) # noqa
|
|
18
|
+
|
|
19
|
+
|
|
16
20
|
##
|
|
17
21
|
|
|
18
22
|
|
|
@@ -39,7 +43,13 @@ class Venv:
|
|
|
39
43
|
|
|
40
44
|
@cached_nullary
|
|
41
45
|
def _iv(self) -> InterpVenv:
|
|
42
|
-
rr = RequirementsRewriter(
|
|
46
|
+
rr = RequirementsRewriter(
|
|
47
|
+
venv=self._name,
|
|
48
|
+
only_pats=(
|
|
49
|
+
[re.compile(p) for p in self._cfg.requires_pats]
|
|
50
|
+
if self._cfg.requires_pats is not None else None
|
|
51
|
+
),
|
|
52
|
+
)
|
|
43
53
|
|
|
44
54
|
return InterpVenv(
|
|
45
55
|
self.dir_name,
|
omdev/rs/__init__.py
ADDED
|
File without changes
|