omdev 0.0.0.dev439__py3-none-any.whl → 0.0.0.dev486__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/.omlish-manifests.json +18 -30
- omdev/__about__.py +9 -7
- 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 +13 -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/data/actions.py +1 -1
- omdev/cache/data/specs.py +1 -1
- omdev/cexts/_boilerplate.cc +2 -3
- omdev/cexts/cmake.py +4 -1
- omdev/ci/cli.py +1 -2
- omdev/ci/github/api/v2/api.py +2 -0
- omdev/cmdlog/cli.py +1 -2
- omdev/dataclasses/_dumping.py +1960 -0
- omdev/dataclasses/_template.py +22 -0
- omdev/dataclasses/cli.py +6 -1
- omdev/dataclasses/codegen.py +340 -60
- omdev/dataclasses/dumping.py +200 -0
- omdev/interp/uv/provider.py +1 -0
- omdev/interp/venvs.py +1 -0
- 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/__init__.py +0 -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 +125 -25
- omdev/markdown/__init__.py +0 -0
- omdev/markdown/incparse.py +116 -0
- omdev/markdown/tokens.py +51 -0
- omdev/packaging/marshal.py +8 -8
- omdev/packaging/requires.py +6 -6
- omdev/packaging/specifiers.py +2 -1
- omdev/packaging/versions.py +4 -4
- omdev/packaging/wheelfile.py +2 -0
- omdev/precheck/blanklines.py +66 -0
- omdev/precheck/caches.py +1 -1
- omdev/precheck/imports.py +14 -1
- omdev/precheck/main.py +4 -3
- 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/reprs.py +32 -0
- omdev/py/srcheaders.py +1 -1
- omdev/py/tokens/__init__.py +0 -0
- omdev/py/tools/mkrelimp.py +1 -1
- omdev/py/tools/pipdepup.py +629 -0
- omdev/pyproject/pkg.py +190 -45
- omdev/pyproject/reqs.py +31 -9
- omdev/pyproject/tools/__init__.py +0 -0
- omdev/pyproject/tools/aboutdeps.py +55 -0
- omdev/pyproject/venvs.py +8 -1
- omdev/rs/__init__.py +0 -0
- omdev/scripts/ci.py +400 -80
- omdev/scripts/interp.py +193 -35
- omdev/scripts/lib/__init__.py +0 -0
- omdev/scripts/{inject.py → lib/inject.py} +75 -28
- omdev/scripts/lib/logs.py +2079 -0
- omdev/scripts/{marshal.py → lib/marshal.py} +68 -26
- omdev/scripts/pyproject.py +941 -90
- omdev/tools/git/cli.py +12 -1
- omdev/tools/json/processing.py +5 -2
- omdev/tools/jsonview/cli.py +31 -5
- 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 +163 -0
- omdev/tui/apps/irc/__init__.py +0 -0
- omdev/tui/apps/irc/__main__.py +4 -0
- omdev/tui/apps/irc/app.py +278 -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 +34 -0
- omdev/tui/rich/console2.py +20 -0
- omdev/tui/rich/markdown2.py +186 -0
- omdev/tui/textual/__init__.py +226 -0
- omdev/tui/textual/app2.py +11 -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/drivers2.py +55 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/METADATA +11 -9
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/RECORD +121 -73
- 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/{ptk/apps → irc}/__init__.py +0 -0
- /omdev/{tokens → irc/messages}/__init__.py +0 -0
- /omdev/{tokens → py/tokens}/all.py +0 -0
- /omdev/{tokens → py/tokens}/tokenizert.py +0 -0
- /omdev/{tokens → py/tokens}/utils.py +0 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/entry_points.txt +0 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/licenses/LICENSE +0 -0
- {omdev-0.0.0.dev439.dist-info → omdev-0.0.0.dev486.dist-info}/top_level.txt +0 -0
omdev/pyproject/pkg.py
CHANGED
|
@@ -28,10 +28,12 @@ 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
|
|
|
@@ -91,7 +93,7 @@ class BasePyprojectPackageGenerator(Abstract):
|
|
|
91
93
|
|
|
92
94
|
def _write_git_ignore(self) -> None:
|
|
93
95
|
with open(os.path.join(self._pkg_dir(), '.gitignore'), 'w') as f:
|
|
94
|
-
f.write('\n'.join(self._GIT_IGNORE))
|
|
96
|
+
f.write('\n'.join([*self._GIT_IGNORE, '']))
|
|
95
97
|
|
|
96
98
|
#
|
|
97
99
|
|
|
@@ -260,6 +262,7 @@ class BasePyprojectPackageGenerator(Abstract):
|
|
|
260
262
|
)
|
|
261
263
|
|
|
262
264
|
if output_dir is not None:
|
|
265
|
+
log.info(lambda: f'Copying {dist_dir} to {output_dir}')
|
|
263
266
|
for fn in os.listdir(dist_dir):
|
|
264
267
|
shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(output_dir, fn))
|
|
265
268
|
|
|
@@ -315,7 +318,11 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
315
318
|
st = dict(specs.setuptools)
|
|
316
319
|
pyp_dct['tool.setuptools'] = st
|
|
317
320
|
|
|
318
|
-
|
|
321
|
+
for k in [
|
|
322
|
+
'cext',
|
|
323
|
+
'rs',
|
|
324
|
+
]:
|
|
325
|
+
st.pop(k, None)
|
|
319
326
|
|
|
320
327
|
#
|
|
321
328
|
|
|
@@ -388,13 +395,20 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
388
395
|
def children(self) -> ta.Sequence[BasePyprojectPackageGenerator]:
|
|
389
396
|
out: ta.List[BasePyprojectPackageGenerator] = []
|
|
390
397
|
|
|
391
|
-
if self.build_specs().setuptools.get('
|
|
398
|
+
if self.build_specs().setuptools.get('cext'):
|
|
392
399
|
out.append(_PyprojectCextPackageGenerator(
|
|
393
400
|
self._dir_name,
|
|
394
401
|
self._pkgs_root,
|
|
395
402
|
pkg_suffix='-cext',
|
|
396
403
|
))
|
|
397
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
|
+
|
|
398
412
|
if self.build_specs().pyproject.get('cli_scripts'):
|
|
399
413
|
out.append(_PyprojectCliPackageGenerator(
|
|
400
414
|
self._dir_name,
|
|
@@ -405,10 +419,67 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
405
419
|
return out
|
|
406
420
|
|
|
407
421
|
|
|
408
|
-
|
|
422
|
+
##
|
|
409
423
|
|
|
410
424
|
|
|
411
|
-
class
|
|
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
|
|
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
|
|
469
|
+
|
|
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):
|
|
412
483
|
@cached_nullary
|
|
413
484
|
def find_cext_srcs(self) -> ta.Sequence[str]:
|
|
414
485
|
return sorted(find_magic_files(
|
|
@@ -419,14 +490,10 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
419
490
|
|
|
420
491
|
#
|
|
421
492
|
|
|
422
|
-
@dc.dataclass(frozen=True)
|
|
423
|
-
class FileContents:
|
|
424
|
-
pyproject_dct: ta.Mapping[str, ta.Any]
|
|
425
|
-
setup_py: str
|
|
426
|
-
|
|
427
493
|
@cached_nullary
|
|
428
|
-
def file_contents(self) -> FileContents:
|
|
429
|
-
|
|
494
|
+
def file_contents(self) -> _PyprojectExtensionPackageGenerator.FileContents:
|
|
495
|
+
prj = self._build_project_dict()
|
|
496
|
+
st = self._build_setuptools_dict()
|
|
430
497
|
|
|
431
498
|
#
|
|
432
499
|
|
|
@@ -437,33 +504,9 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
437
504
|
'build-backend': 'setuptools.build_meta',
|
|
438
505
|
}
|
|
439
506
|
|
|
440
|
-
prj = specs.pyproject
|
|
441
|
-
prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
|
|
442
|
-
prj['name'] += self._pkg_suffix
|
|
443
|
-
for k in [
|
|
444
|
-
'optional_dependencies',
|
|
445
|
-
'entry_points',
|
|
446
|
-
'scripts',
|
|
447
|
-
'cli_scripts',
|
|
448
|
-
]:
|
|
449
|
-
prj.pop(k, None)
|
|
450
|
-
|
|
451
507
|
pyp_dct['project'] = prj
|
|
452
|
-
|
|
453
|
-
#
|
|
454
|
-
|
|
455
|
-
st = dict(specs.setuptools)
|
|
456
508
|
pyp_dct['tool.setuptools'] = st
|
|
457
509
|
|
|
458
|
-
for k in [
|
|
459
|
-
'cexts',
|
|
460
|
-
|
|
461
|
-
'find_packages',
|
|
462
|
-
'package_data',
|
|
463
|
-
'manifest_in',
|
|
464
|
-
]:
|
|
465
|
-
st.pop(k, None)
|
|
466
|
-
|
|
467
510
|
pyp_dct['tool.setuptools.packages.find'] = {
|
|
468
511
|
'include': [],
|
|
469
512
|
}
|
|
@@ -473,12 +516,17 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
473
516
|
ext_lines = []
|
|
474
517
|
|
|
475
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, [])
|
|
476
524
|
ext_name = ext_src.rpartition('.')[0].replace(os.sep, '.')
|
|
477
525
|
ext_lines.extend([
|
|
478
526
|
'st.Extension(',
|
|
479
527
|
f" name='{ext_name}',",
|
|
480
528
|
f" sources=['{ext_src}'],",
|
|
481
|
-
|
|
529
|
+
f' extra_compile_args={compile_args!r},',
|
|
482
530
|
'),',
|
|
483
531
|
])
|
|
484
532
|
|
|
@@ -489,7 +537,7 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
489
537
|
'st.setup(',
|
|
490
538
|
' ext_modules=[',
|
|
491
539
|
*[' ' + l for l in ext_lines],
|
|
492
|
-
' ]',
|
|
540
|
+
' ],',
|
|
493
541
|
')',
|
|
494
542
|
'',
|
|
495
543
|
])
|
|
@@ -501,14 +549,110 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
501
549
|
src,
|
|
502
550
|
)
|
|
503
551
|
|
|
504
|
-
def _write_file_contents(self) -> None:
|
|
505
|
-
fc = self.file_contents()
|
|
506
552
|
|
|
507
|
-
|
|
508
|
-
|
|
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
|
+
)
|
|
509
562
|
|
|
510
|
-
|
|
511
|
-
|
|
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
|
+
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
|
+
)
|
|
512
656
|
|
|
513
657
|
|
|
514
658
|
##
|
|
@@ -553,7 +697,8 @@ class _PyprojectCliPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
553
697
|
pyp_dct['tool.setuptools'] = st
|
|
554
698
|
|
|
555
699
|
for k in [
|
|
556
|
-
'
|
|
700
|
+
'cext',
|
|
701
|
+
'rs',
|
|
557
702
|
|
|
558
703
|
'find_packages',
|
|
559
704
|
'package_data',
|
omdev/pyproject/reqs.py
CHANGED
|
@@ -4,12 +4,16 @@ 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
12
|
from omlish.logs.modules import get_module_logger
|
|
12
13
|
|
|
14
|
+
from ..packaging.requires import RequiresParserSyntaxError
|
|
15
|
+
from ..packaging.requires import parse_requirement
|
|
16
|
+
|
|
13
17
|
|
|
14
18
|
log = get_module_logger(globals()) # noqa
|
|
15
19
|
|
|
@@ -20,11 +24,14 @@ log = get_module_logger(globals()) # noqa
|
|
|
20
24
|
class RequirementsRewriter:
|
|
21
25
|
def __init__(
|
|
22
26
|
self,
|
|
27
|
+
*,
|
|
23
28
|
venv: ta.Optional[str] = None,
|
|
29
|
+
only_pats: ta.Optional[ta.Sequence[re.Pattern]] = None,
|
|
24
30
|
) -> None:
|
|
25
31
|
super().__init__()
|
|
26
32
|
|
|
27
33
|
self._venv = venv
|
|
34
|
+
self._only_pats = only_pats
|
|
28
35
|
|
|
29
36
|
@cached_nullary
|
|
30
37
|
def _tmp_dir(self) -> str:
|
|
@@ -40,17 +47,32 @@ class RequirementsRewriter:
|
|
|
40
47
|
out_lines = []
|
|
41
48
|
|
|
42
49
|
for l in in_lines:
|
|
43
|
-
if
|
|
44
|
-
lp, _, rp = l.partition(self.VENV_MAGIC)
|
|
45
|
-
rp = rp.partition('#')[0]
|
|
50
|
+
if l.split('#')[0].strip():
|
|
46
51
|
omit = False
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
|
|
53
|
+
if self.VENV_MAGIC in l:
|
|
54
|
+
lp, _, rp = l.partition(self.VENV_MAGIC)
|
|
55
|
+
rp = rp.partition('#')[0]
|
|
56
|
+
for v in rp.split():
|
|
57
|
+
if v[0] == '!':
|
|
58
|
+
if self._venv is not None and self._venv == v[1:]:
|
|
59
|
+
omit = True
|
|
60
|
+
break
|
|
61
|
+
else:
|
|
62
|
+
raise NotImplementedError
|
|
63
|
+
|
|
64
|
+
if (
|
|
65
|
+
not omit and
|
|
66
|
+
(ops := self._only_pats) is not None and
|
|
67
|
+
not l.strip().startswith('-')
|
|
68
|
+
):
|
|
69
|
+
try:
|
|
70
|
+
pr = parse_requirement(l.split('#')[0].strip())
|
|
71
|
+
except RequiresParserSyntaxError:
|
|
72
|
+
pass
|
|
52
73
|
else:
|
|
53
|
-
|
|
74
|
+
if not any(op.fullmatch(pr.name) for op in ops):
|
|
75
|
+
omit = True
|
|
54
76
|
|
|
55
77
|
if omit:
|
|
56
78
|
out_lines.append('# OMITTED: ' + l)
|
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
opt_cn = canonicalize_name(opt_req.name, validate=True)
|
|
42
|
+
opt_spec = Specifier(opt_req.specifier)
|
|
43
|
+
if re.fullmatch(r'~=\s*\d+(\.\d+)*', str(opt_spec)):
|
|
44
|
+
opt_spec = Specifier(str(opt_spec) + '.0')
|
|
45
|
+
|
|
46
|
+
opt_dist = dist_dct[opt_cn]
|
|
47
|
+
opt_ver = opt_dist.version
|
|
48
|
+
|
|
49
|
+
# print((opt_dep, opt_spec, opt_ver))
|
|
50
|
+
if not opt_spec.contains(opt_ver):
|
|
51
|
+
print(f'{pkg} :: {opt_cn} : {opt_spec} ! {opt_ver}')
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if __name__ == '__main__':
|
|
55
|
+
_main()
|
omdev/pyproject/venvs.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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
|
|
@@ -42,7 +43,13 @@ class Venv:
|
|
|
42
43
|
|
|
43
44
|
@cached_nullary
|
|
44
45
|
def _iv(self) -> InterpVenv:
|
|
45
|
-
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
|
+
)
|
|
46
53
|
|
|
47
54
|
return InterpVenv(
|
|
48
55
|
self.dir_name,
|
omdev/rs/__init__.py
ADDED
|
File without changes
|