omdev 0.0.0.dev31__py3-none-any.whl → 0.0.0.dev32__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.
- omdev/.manifests.json +122 -1
- omdev/__about__.py +9 -0
- omdev/amalg/__main__.py +7 -0
- omdev/amalg/amalg.py +4 -4
- omdev/cexts/_boilerplate.cc +1 -1
- omdev/cexts/cmake.py +5 -0
- omdev/cexts/magic.py +1 -1
- omdev/classdot.py +6 -0
- omdev/cli/__init__.py +1 -0
- omdev/cli/__main__.py +4 -0
- omdev/cli/main.py +59 -0
- omdev/cli/types.py +7 -0
- omdev/interp/__main__.py +7 -0
- omdev/interp/cli.py +13 -5
- omdev/interp/pyenv.py +54 -12
- omdev/manifests/__init__.py +2 -0
- omdev/{manifests.py → manifests/build.py} +27 -58
- omdev/manifests/load.py +149 -0
- omdev/manifests/types.py +16 -0
- omdev/precheck/precheck.py +6 -0
- omdev/pyproject/__main__.py +7 -0
- omdev/pyproject/cli.py +1 -1
- omdev/pyproject/pkg.py +13 -2
- omdev/pyproject/reqs.py +1 -1
- omdev/scripts/interp.py +65 -17
- omdev/scripts/pyproject.py +77 -18
- omdev/toml/writer.py +8 -1
- omdev/tools/dockertools.py +6 -0
- omdev/tools/gittools.py +6 -0
- omdev/tools/piptools.py +6 -0
- omdev/tools/sqlrepl.py +6 -0
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev32.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev32.dist-info}/RECORD +37 -29
- omdev-0.0.0.dev32.dist-info/entry_points.txt +2 -0
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev32.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev32.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev31.dist-info → omdev-0.0.0.dev32.dist-info}/top_level.txt +0 -0
omdev/manifests/load.py
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# ruff: noqa: UP006 UP007
|
|
2
|
+
import dataclasses as dc
|
|
3
|
+
import importlib.machinery
|
|
4
|
+
import importlib.metadata
|
|
5
|
+
import importlib.resources
|
|
6
|
+
import json
|
|
7
|
+
import typing as ta
|
|
8
|
+
|
|
9
|
+
from .types import Manifest
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ManifestLoader:
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
*,
|
|
19
|
+
module_remap: ta.Optional[ta.Mapping[str, str]] = None,
|
|
20
|
+
) -> None:
|
|
21
|
+
super().__init__()
|
|
22
|
+
|
|
23
|
+
self._module_remap = module_remap or {}
|
|
24
|
+
self._module_reverse_remap = {v: k for k, v in self._module_remap.items()}
|
|
25
|
+
|
|
26
|
+
self._cls_cache: ta.Dict[str, type] = {}
|
|
27
|
+
self._raw_cache: ta.Dict[str, ta.Optional[ta.Sequence[Manifest]]] = {}
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def from_entry_point(
|
|
31
|
+
cls,
|
|
32
|
+
globals: ta.Mapping[str, ta.Any], # noqa
|
|
33
|
+
*,
|
|
34
|
+
module_remap: ta.Optional[ta.Mapping[str, str]] = None,
|
|
35
|
+
**kwargs: ta.Any,
|
|
36
|
+
) -> 'ManifestLoader':
|
|
37
|
+
rm: ta.Dict[str, str] = {}
|
|
38
|
+
|
|
39
|
+
if module_remap:
|
|
40
|
+
rm.update(module_remap)
|
|
41
|
+
|
|
42
|
+
if '__name__' in globals and '__spec__' in globals:
|
|
43
|
+
name: str = globals['__name__']
|
|
44
|
+
spec: importlib.machinery.ModuleSpec = globals['__spec__']
|
|
45
|
+
if '__main__' not in rm and name == '__main__':
|
|
46
|
+
rm[spec.name] = '__main__'
|
|
47
|
+
|
|
48
|
+
return cls(module_remap=rm, **kwargs)
|
|
49
|
+
|
|
50
|
+
def load_cls(self, key: str) -> type:
|
|
51
|
+
try:
|
|
52
|
+
return self._cls_cache[key]
|
|
53
|
+
except KeyError:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
if not key.startswith('$'):
|
|
57
|
+
raise Exception(f'Bad key: {key}')
|
|
58
|
+
|
|
59
|
+
parts = key[1:].split('.')
|
|
60
|
+
pos = next(i for i, p in enumerate(parts) if p[0].isupper())
|
|
61
|
+
|
|
62
|
+
mod_name = '.'.join(parts[:pos])
|
|
63
|
+
mod_name = self._module_remap.get(mod_name, mod_name)
|
|
64
|
+
mod = importlib.import_module(mod_name)
|
|
65
|
+
|
|
66
|
+
obj: ta.Any = mod
|
|
67
|
+
for ca in parts[pos:]:
|
|
68
|
+
obj = getattr(obj, ca)
|
|
69
|
+
|
|
70
|
+
cls = obj
|
|
71
|
+
if not isinstance(cls, type):
|
|
72
|
+
raise TypeError(cls)
|
|
73
|
+
|
|
74
|
+
self._cls_cache[key] = cls
|
|
75
|
+
return cls
|
|
76
|
+
|
|
77
|
+
def load_raw(self, pkg_name: str) -> ta.Optional[ta.Sequence[Manifest]]:
|
|
78
|
+
try:
|
|
79
|
+
return self._raw_cache[pkg_name]
|
|
80
|
+
except KeyError:
|
|
81
|
+
pass
|
|
82
|
+
|
|
83
|
+
t = importlib.resources.files(pkg_name).joinpath('.manifests.json')
|
|
84
|
+
if not t.is_file():
|
|
85
|
+
self._raw_cache[pkg_name] = None
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
src = t.read_text('utf-8')
|
|
89
|
+
obj = json.loads(src)
|
|
90
|
+
if not isinstance(obj, (list, tuple)):
|
|
91
|
+
raise TypeError(obj)
|
|
92
|
+
|
|
93
|
+
lst: ta.List[Manifest] = []
|
|
94
|
+
for e in obj:
|
|
95
|
+
m = Manifest(**e)
|
|
96
|
+
|
|
97
|
+
m = dc.replace(m, module=pkg_name + m.module)
|
|
98
|
+
|
|
99
|
+
[(key, value_dct)] = m.value.items()
|
|
100
|
+
if not key.startswith('$'):
|
|
101
|
+
raise Exception(f'Bad key: {key}')
|
|
102
|
+
if key.startswith('$.'):
|
|
103
|
+
key = f'${pkg_name}{key[1:]}'
|
|
104
|
+
m = dc.replace(m, value={key: value_dct})
|
|
105
|
+
|
|
106
|
+
lst.append(m)
|
|
107
|
+
|
|
108
|
+
self._raw_cache[pkg_name] = lst
|
|
109
|
+
return lst
|
|
110
|
+
|
|
111
|
+
def load(
|
|
112
|
+
self,
|
|
113
|
+
*pkg_names: str,
|
|
114
|
+
only: ta.Optional[ta.Iterable[type]] = None,
|
|
115
|
+
) -> ta.Sequence[Manifest]:
|
|
116
|
+
only_keys: ta.Optional[ta.Set]
|
|
117
|
+
if only is not None:
|
|
118
|
+
only_keys = set()
|
|
119
|
+
for cls in only:
|
|
120
|
+
if not (isinstance(cls, type) and dc.is_dataclass(cls)):
|
|
121
|
+
raise TypeError(cls)
|
|
122
|
+
mod_name = cls.__module__
|
|
123
|
+
mod_name = self._module_reverse_remap.get(mod_name, mod_name)
|
|
124
|
+
only_keys.add(f'${mod_name}.{cls.__qualname__}')
|
|
125
|
+
else:
|
|
126
|
+
only_keys = None
|
|
127
|
+
|
|
128
|
+
lst: ta.List[Manifest] = []
|
|
129
|
+
for pn in pkg_names:
|
|
130
|
+
for manifest in (self.load_raw(pn) or []):
|
|
131
|
+
[(key, value_dct)] = manifest.value.items()
|
|
132
|
+
if only_keys is not None and key not in only_keys:
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
cls = self.load_cls(key)
|
|
136
|
+
value = cls(**value_dct)
|
|
137
|
+
|
|
138
|
+
manifest = dc.replace(manifest, value=value)
|
|
139
|
+
lst.append(manifest)
|
|
140
|
+
|
|
141
|
+
return lst
|
|
142
|
+
|
|
143
|
+
ENTRY_POINT_GROUP = 'omlish.manifests'
|
|
144
|
+
|
|
145
|
+
def discover(self) -> ta.Sequence[str]:
|
|
146
|
+
return [
|
|
147
|
+
ep.value
|
|
148
|
+
for ep in importlib.metadata.entry_points(group=self.ENTRY_POINT_GROUP)
|
|
149
|
+
]
|
omdev/manifests/types.py
ADDED
omdev/precheck/precheck.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Tiny pre-commit
|
|
3
3
|
|
|
4
4
|
TODO:
|
|
5
|
+
- ! manifests
|
|
5
6
|
- global config
|
|
6
7
|
- global analyses - FilesWithShebang
|
|
7
8
|
- shebang files have no relative imports
|
|
@@ -26,6 +27,7 @@ import typing as ta
|
|
|
26
27
|
|
|
27
28
|
from omlish import logs
|
|
28
29
|
|
|
30
|
+
from ..cli import CliModule
|
|
29
31
|
from .base import Precheck
|
|
30
32
|
from .base import PrecheckContext
|
|
31
33
|
from .git import GitBlacklistPrecheck
|
|
@@ -85,6 +87,10 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
85
87
|
return parser
|
|
86
88
|
|
|
87
89
|
|
|
90
|
+
# @omlish-manifest
|
|
91
|
+
_CLI_MODULE = CliModule('precheck', __name__)
|
|
92
|
+
|
|
93
|
+
|
|
88
94
|
def _main(argv: ta.Sequence[str] | None = None) -> None:
|
|
89
95
|
logs.configure_standard_logging('INFO')
|
|
90
96
|
|
omdev/pyproject/__main__.py
CHANGED
omdev/pyproject/cli.py
CHANGED
omdev/pyproject/pkg.py
CHANGED
|
@@ -295,7 +295,13 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
295
295
|
**extras,
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
-
|
|
298
|
+
if (eps := prj.pop('entry_points', None)):
|
|
299
|
+
pyp_dct['project.entry-points'] = {TomlWriter.Literal(f"'{k}'"): v for k, v in eps.items()} # type: ignore # noqa
|
|
300
|
+
|
|
301
|
+
if (scs := prj.pop('scripts', None)):
|
|
302
|
+
pyp_dct['project.scripts'] = scs
|
|
303
|
+
|
|
304
|
+
##
|
|
299
305
|
|
|
300
306
|
st = dict(specs.setuptools)
|
|
301
307
|
pyp_dct['tool.setuptools'] = st
|
|
@@ -420,7 +426,12 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
420
426
|
prj = specs.pyproject
|
|
421
427
|
prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
|
|
422
428
|
prj['name'] += self._pkg_suffix
|
|
423
|
-
|
|
429
|
+
for k in [
|
|
430
|
+
'optional_dependencies',
|
|
431
|
+
'entry_points',
|
|
432
|
+
'scripts',
|
|
433
|
+
]:
|
|
434
|
+
prj.pop(k, None)
|
|
424
435
|
|
|
425
436
|
pyp_dct['project'] = prj
|
|
426
437
|
|
omdev/pyproject/reqs.py
CHANGED
omdev/scripts/interp.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# noinspection DuplicatedCode
|
|
3
3
|
# @omlish-lite
|
|
4
4
|
# @omlish-script
|
|
5
|
-
# @
|
|
5
|
+
# @omlish-amalg-output ../interp/cli.py
|
|
6
6
|
# ruff: noqa: N802 UP006 UP007 UP036
|
|
7
7
|
"""
|
|
8
8
|
TODO:
|
|
@@ -1796,16 +1796,14 @@ class RunningInterpProvider(InterpProvider):
|
|
|
1796
1796
|
"""
|
|
1797
1797
|
TODO:
|
|
1798
1798
|
- custom tags
|
|
1799
|
+
- 'aliases'
|
|
1800
|
+
- https://github.com/pyenv/pyenv/pull/2966
|
|
1801
|
+
- https://github.com/pyenv/pyenv/issues/218 (lol)
|
|
1802
|
+
- probably need custom (temp?) definition file
|
|
1803
|
+
- *or* python-build directly just into the versions dir?
|
|
1799
1804
|
- optionally install / upgrade pyenv itself
|
|
1800
1805
|
- new vers dont need these custom mac opts, only run on old vers
|
|
1801
|
-
|
|
1802
|
-
TODO opts:
|
|
1803
|
-
- --enable-loadable-sqlite-extensions LDFLAGS="-L/opt/homebrew/opt/sqlite/lib" CPPFLAGS="-I/opt/homebrew/opt/sqlite/include"
|
|
1804
|
-
- --enable-shared
|
|
1805
|
-
- --enable-optimizations
|
|
1806
|
-
- --enable-profiling ?
|
|
1807
|
-
- --enable-ipv6 ?
|
|
1808
|
-
""" # noqa
|
|
1806
|
+
"""
|
|
1809
1807
|
|
|
1810
1808
|
|
|
1811
1809
|
##
|
|
@@ -1899,8 +1897,33 @@ class PyenvInstallOpts:
|
|
|
1899
1897
|
)
|
|
1900
1898
|
|
|
1901
1899
|
|
|
1902
|
-
|
|
1900
|
+
# TODO: https://github.com/pyenv/pyenv/blob/master/plugins/python-build/README.md#building-for-maximum-performance
|
|
1901
|
+
DEFAULT_PYENV_INSTALL_OPTS = PyenvInstallOpts(
|
|
1902
|
+
opts=[
|
|
1903
|
+
'-s',
|
|
1904
|
+
'-v',
|
|
1905
|
+
'-k',
|
|
1906
|
+
],
|
|
1907
|
+
conf_opts=[
|
|
1908
|
+
'--enable-loadable-sqlite-extensions',
|
|
1909
|
+
|
|
1910
|
+
# '--enable-shared',
|
|
1911
|
+
|
|
1912
|
+
'--enable-optimizations',
|
|
1913
|
+
'--with-lto',
|
|
1914
|
+
|
|
1915
|
+
# '--enable-profiling', # ?
|
|
1916
|
+
|
|
1917
|
+
# '--enable-ipv6', # ?
|
|
1918
|
+
],
|
|
1919
|
+
cflags=[
|
|
1920
|
+
# '-march=native',
|
|
1921
|
+
# '-mtune=native',
|
|
1922
|
+
],
|
|
1923
|
+
)
|
|
1924
|
+
|
|
1903
1925
|
DEBUG_PYENV_INSTALL_OPTS = PyenvInstallOpts(opts=['-g'])
|
|
1926
|
+
|
|
1904
1927
|
THREADED_PYENV_INSTALL_OPTS = PyenvInstallOpts(conf_opts=['--disable-gil'])
|
|
1905
1928
|
|
|
1906
1929
|
|
|
@@ -1999,6 +2022,7 @@ class PyenvVersionInstaller:
|
|
|
1999
2022
|
opts: ta.Optional[PyenvInstallOpts] = None,
|
|
2000
2023
|
interp_opts: InterpOpts = InterpOpts(),
|
|
2001
2024
|
*,
|
|
2025
|
+
install_name: ta.Optional[str] = None,
|
|
2002
2026
|
no_default_opts: bool = False,
|
|
2003
2027
|
pyenv: Pyenv = Pyenv(),
|
|
2004
2028
|
) -> None:
|
|
@@ -2019,6 +2043,7 @@ class PyenvVersionInstaller:
|
|
|
2019
2043
|
self._version = version
|
|
2020
2044
|
self._opts = opts
|
|
2021
2045
|
self._interp_opts = interp_opts
|
|
2046
|
+
self._given_install_name = install_name
|
|
2022
2047
|
|
|
2023
2048
|
self._no_default_opts = no_default_opts
|
|
2024
2049
|
self._pyenv = pyenv
|
|
@@ -2033,6 +2058,8 @@ class PyenvVersionInstaller:
|
|
|
2033
2058
|
|
|
2034
2059
|
@cached_nullary
|
|
2035
2060
|
def install_name(self) -> str:
|
|
2061
|
+
if self._given_install_name is not None:
|
|
2062
|
+
return self._given_install_name
|
|
2036
2063
|
return self._version + ('-debug' if self._interp_opts.debug else '')
|
|
2037
2064
|
|
|
2038
2065
|
@cached_nullary
|
|
@@ -2052,11 +2079,26 @@ class PyenvVersionInstaller:
|
|
|
2052
2079
|
v += ' ' + os.environ[k]
|
|
2053
2080
|
env[k] = v
|
|
2054
2081
|
|
|
2055
|
-
|
|
2056
|
-
self._pyenv.exe(),
|
|
2057
|
-
'install',
|
|
2082
|
+
conf_args = [
|
|
2058
2083
|
*self._opts.opts,
|
|
2059
2084
|
self._version,
|
|
2085
|
+
]
|
|
2086
|
+
|
|
2087
|
+
if self._given_install_name is not None:
|
|
2088
|
+
full_args = [
|
|
2089
|
+
os.path.join(check_not_none(self._pyenv.root()), 'plugins', 'python-build', 'bin', 'python-build'),
|
|
2090
|
+
*conf_args,
|
|
2091
|
+
self.install_dir(),
|
|
2092
|
+
]
|
|
2093
|
+
else:
|
|
2094
|
+
full_args = [
|
|
2095
|
+
self._pyenv.exe(),
|
|
2096
|
+
'install',
|
|
2097
|
+
*conf_args,
|
|
2098
|
+
]
|
|
2099
|
+
|
|
2100
|
+
subprocess_check_call(
|
|
2101
|
+
*full_args,
|
|
2060
2102
|
env=env,
|
|
2061
2103
|
)
|
|
2062
2104
|
|
|
@@ -2414,9 +2456,13 @@ def _list_cmd(args) -> None:
|
|
|
2414
2456
|
|
|
2415
2457
|
|
|
2416
2458
|
def _resolve_cmd(args) -> None:
|
|
2417
|
-
|
|
2459
|
+
if args.provider:
|
|
2460
|
+
p = INTERP_PROVIDER_TYPES_BY_NAME[args.provider]()
|
|
2461
|
+
r = InterpResolver([(p.name, p)])
|
|
2462
|
+
else:
|
|
2463
|
+
r = DEFAULT_INTERP_RESOLVER
|
|
2418
2464
|
s = InterpSpecifier.parse(args.version)
|
|
2419
|
-
print(check_not_none(r.resolve(s)).exe)
|
|
2465
|
+
print(check_not_none(r.resolve(s, install=bool(args.install))).exe)
|
|
2420
2466
|
|
|
2421
2467
|
|
|
2422
2468
|
def _build_parser() -> argparse.ArgumentParser:
|
|
@@ -2426,12 +2472,14 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
2426
2472
|
|
|
2427
2473
|
parser_list = subparsers.add_parser('list')
|
|
2428
2474
|
parser_list.add_argument('version')
|
|
2429
|
-
parser_list.add_argument('--debug', action='store_true')
|
|
2475
|
+
parser_list.add_argument('-d', '--debug', action='store_true')
|
|
2430
2476
|
parser_list.set_defaults(func=_list_cmd)
|
|
2431
2477
|
|
|
2432
2478
|
parser_resolve = subparsers.add_parser('resolve')
|
|
2433
2479
|
parser_resolve.add_argument('version')
|
|
2434
|
-
parser_resolve.add_argument('
|
|
2480
|
+
parser_resolve.add_argument('-p', '--provider')
|
|
2481
|
+
parser_resolve.add_argument('-d', '--debug', action='store_true')
|
|
2482
|
+
parser_resolve.add_argument('-i', '--install', action='store_true')
|
|
2435
2483
|
parser_resolve.set_defaults(func=_resolve_cmd)
|
|
2436
2484
|
|
|
2437
2485
|
return parser
|
omdev/scripts/pyproject.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# noinspection DuplicatedCode
|
|
3
3
|
# @omlish-lite
|
|
4
4
|
# @omlish-script
|
|
5
|
-
# @
|
|
5
|
+
# @omlish-amalg-output ../pyproject/cli.py
|
|
6
6
|
# ruff: noqa: N802 TCH003 UP006 UP007 UP036
|
|
7
7
|
"""
|
|
8
8
|
TODO:
|
|
@@ -104,7 +104,7 @@ CallableVersionOperator = ta.Callable[['Version', str], bool]
|
|
|
104
104
|
|
|
105
105
|
|
|
106
106
|
class CextMagic:
|
|
107
|
-
MAGIC = '@
|
|
107
|
+
MAGIC = '@omlish-cext'
|
|
108
108
|
MAGIC_COMMENT = f'// {MAGIC}'
|
|
109
109
|
|
|
110
110
|
FILE_EXTENSIONS = ('c', 'cc', 'cpp')
|
|
@@ -1089,6 +1089,10 @@ def toml_make_safe_parse_float(parse_float: TomlParseFloat) -> TomlParseFloat:
|
|
|
1089
1089
|
|
|
1090
1090
|
|
|
1091
1091
|
class TomlWriter:
|
|
1092
|
+
@dc.dataclass(frozen=True)
|
|
1093
|
+
class Literal:
|
|
1094
|
+
s: str
|
|
1095
|
+
|
|
1092
1096
|
def __init__(self, out: ta.TextIO) -> None:
|
|
1093
1097
|
super().__init__()
|
|
1094
1098
|
self._out = out
|
|
@@ -1170,7 +1174,9 @@ class TomlWriter:
|
|
|
1170
1174
|
self._w(']')
|
|
1171
1175
|
|
|
1172
1176
|
def write_key(self, obj: ta.Any) -> None:
|
|
1173
|
-
if isinstance(obj,
|
|
1177
|
+
if isinstance(obj, TomlWriter.Literal):
|
|
1178
|
+
self._w(obj.s)
|
|
1179
|
+
elif isinstance(obj, str):
|
|
1174
1180
|
self._w(self._maybe_quote(obj.replace('_', '-')))
|
|
1175
1181
|
elif isinstance(obj, int):
|
|
1176
1182
|
self._w(repr(str(obj)))
|
|
@@ -2022,7 +2028,7 @@ class RequirementsRewriter:
|
|
|
2022
2028
|
def _tmp_dir(self) -> str:
|
|
2023
2029
|
return tempfile.mkdtemp('-omlish-reqs')
|
|
2024
2030
|
|
|
2025
|
-
VENV_MAGIC = '# @
|
|
2031
|
+
VENV_MAGIC = '# @omlish-venv'
|
|
2026
2032
|
|
|
2027
2033
|
def rewrite_file(self, in_file: str) -> str:
|
|
2028
2034
|
with open(in_file) as f:
|
|
@@ -3977,7 +3983,13 @@ class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
3977
3983
|
**extras,
|
|
3978
3984
|
}
|
|
3979
3985
|
|
|
3980
|
-
|
|
3986
|
+
if (eps := prj.pop('entry_points', None)):
|
|
3987
|
+
pyp_dct['project.entry-points'] = {TomlWriter.Literal(f"'{k}'"): v for k, v in eps.items()} # type: ignore # noqa
|
|
3988
|
+
|
|
3989
|
+
if (scs := prj.pop('scripts', None)):
|
|
3990
|
+
pyp_dct['project.scripts'] = scs
|
|
3991
|
+
|
|
3992
|
+
##
|
|
3981
3993
|
|
|
3982
3994
|
st = dict(specs.setuptools)
|
|
3983
3995
|
pyp_dct['tool.setuptools'] = st
|
|
@@ -4102,7 +4114,12 @@ class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
|
4102
4114
|
prj = specs.pyproject
|
|
4103
4115
|
prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
|
|
4104
4116
|
prj['name'] += self._pkg_suffix
|
|
4105
|
-
|
|
4117
|
+
for k in [
|
|
4118
|
+
'optional_dependencies',
|
|
4119
|
+
'entry_points',
|
|
4120
|
+
'scripts',
|
|
4121
|
+
]:
|
|
4122
|
+
prj.pop(k, None)
|
|
4106
4123
|
|
|
4107
4124
|
pyp_dct['project'] = prj
|
|
4108
4125
|
|
|
@@ -4233,16 +4250,14 @@ class RunningInterpProvider(InterpProvider):
|
|
|
4233
4250
|
"""
|
|
4234
4251
|
TODO:
|
|
4235
4252
|
- custom tags
|
|
4253
|
+
- 'aliases'
|
|
4254
|
+
- https://github.com/pyenv/pyenv/pull/2966
|
|
4255
|
+
- https://github.com/pyenv/pyenv/issues/218 (lol)
|
|
4256
|
+
- probably need custom (temp?) definition file
|
|
4257
|
+
- *or* python-build directly just into the versions dir?
|
|
4236
4258
|
- optionally install / upgrade pyenv itself
|
|
4237
4259
|
- new vers dont need these custom mac opts, only run on old vers
|
|
4238
|
-
|
|
4239
|
-
TODO opts:
|
|
4240
|
-
- --enable-loadable-sqlite-extensions LDFLAGS="-L/opt/homebrew/opt/sqlite/lib" CPPFLAGS="-I/opt/homebrew/opt/sqlite/include"
|
|
4241
|
-
- --enable-shared
|
|
4242
|
-
- --enable-optimizations
|
|
4243
|
-
- --enable-profiling ?
|
|
4244
|
-
- --enable-ipv6 ?
|
|
4245
|
-
""" # noqa
|
|
4260
|
+
"""
|
|
4246
4261
|
|
|
4247
4262
|
|
|
4248
4263
|
##
|
|
@@ -4336,8 +4351,33 @@ class PyenvInstallOpts:
|
|
|
4336
4351
|
)
|
|
4337
4352
|
|
|
4338
4353
|
|
|
4339
|
-
|
|
4354
|
+
# TODO: https://github.com/pyenv/pyenv/blob/master/plugins/python-build/README.md#building-for-maximum-performance
|
|
4355
|
+
DEFAULT_PYENV_INSTALL_OPTS = PyenvInstallOpts(
|
|
4356
|
+
opts=[
|
|
4357
|
+
'-s',
|
|
4358
|
+
'-v',
|
|
4359
|
+
'-k',
|
|
4360
|
+
],
|
|
4361
|
+
conf_opts=[
|
|
4362
|
+
'--enable-loadable-sqlite-extensions',
|
|
4363
|
+
|
|
4364
|
+
# '--enable-shared',
|
|
4365
|
+
|
|
4366
|
+
'--enable-optimizations',
|
|
4367
|
+
'--with-lto',
|
|
4368
|
+
|
|
4369
|
+
# '--enable-profiling', # ?
|
|
4370
|
+
|
|
4371
|
+
# '--enable-ipv6', # ?
|
|
4372
|
+
],
|
|
4373
|
+
cflags=[
|
|
4374
|
+
# '-march=native',
|
|
4375
|
+
# '-mtune=native',
|
|
4376
|
+
],
|
|
4377
|
+
)
|
|
4378
|
+
|
|
4340
4379
|
DEBUG_PYENV_INSTALL_OPTS = PyenvInstallOpts(opts=['-g'])
|
|
4380
|
+
|
|
4341
4381
|
THREADED_PYENV_INSTALL_OPTS = PyenvInstallOpts(conf_opts=['--disable-gil'])
|
|
4342
4382
|
|
|
4343
4383
|
|
|
@@ -4436,6 +4476,7 @@ class PyenvVersionInstaller:
|
|
|
4436
4476
|
opts: ta.Optional[PyenvInstallOpts] = None,
|
|
4437
4477
|
interp_opts: InterpOpts = InterpOpts(),
|
|
4438
4478
|
*,
|
|
4479
|
+
install_name: ta.Optional[str] = None,
|
|
4439
4480
|
no_default_opts: bool = False,
|
|
4440
4481
|
pyenv: Pyenv = Pyenv(),
|
|
4441
4482
|
) -> None:
|
|
@@ -4456,6 +4497,7 @@ class PyenvVersionInstaller:
|
|
|
4456
4497
|
self._version = version
|
|
4457
4498
|
self._opts = opts
|
|
4458
4499
|
self._interp_opts = interp_opts
|
|
4500
|
+
self._given_install_name = install_name
|
|
4459
4501
|
|
|
4460
4502
|
self._no_default_opts = no_default_opts
|
|
4461
4503
|
self._pyenv = pyenv
|
|
@@ -4470,6 +4512,8 @@ class PyenvVersionInstaller:
|
|
|
4470
4512
|
|
|
4471
4513
|
@cached_nullary
|
|
4472
4514
|
def install_name(self) -> str:
|
|
4515
|
+
if self._given_install_name is not None:
|
|
4516
|
+
return self._given_install_name
|
|
4473
4517
|
return self._version + ('-debug' if self._interp_opts.debug else '')
|
|
4474
4518
|
|
|
4475
4519
|
@cached_nullary
|
|
@@ -4489,11 +4533,26 @@ class PyenvVersionInstaller:
|
|
|
4489
4533
|
v += ' ' + os.environ[k]
|
|
4490
4534
|
env[k] = v
|
|
4491
4535
|
|
|
4492
|
-
|
|
4493
|
-
self._pyenv.exe(),
|
|
4494
|
-
'install',
|
|
4536
|
+
conf_args = [
|
|
4495
4537
|
*self._opts.opts,
|
|
4496
4538
|
self._version,
|
|
4539
|
+
]
|
|
4540
|
+
|
|
4541
|
+
if self._given_install_name is not None:
|
|
4542
|
+
full_args = [
|
|
4543
|
+
os.path.join(check_not_none(self._pyenv.root()), 'plugins', 'python-build', 'bin', 'python-build'),
|
|
4544
|
+
*conf_args,
|
|
4545
|
+
self.install_dir(),
|
|
4546
|
+
]
|
|
4547
|
+
else:
|
|
4548
|
+
full_args = [
|
|
4549
|
+
self._pyenv.exe(),
|
|
4550
|
+
'install',
|
|
4551
|
+
*conf_args,
|
|
4552
|
+
]
|
|
4553
|
+
|
|
4554
|
+
subprocess_check_call(
|
|
4555
|
+
*full_args,
|
|
4497
4556
|
env=env,
|
|
4498
4557
|
)
|
|
4499
4558
|
|
omdev/toml/writer.py
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import dataclasses as dc
|
|
1
2
|
import string
|
|
2
3
|
import typing as ta
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class TomlWriter:
|
|
7
|
+
@dc.dataclass(frozen=True)
|
|
8
|
+
class Literal:
|
|
9
|
+
s: str
|
|
10
|
+
|
|
6
11
|
def __init__(self, out: ta.TextIO) -> None:
|
|
7
12
|
super().__init__()
|
|
8
13
|
self._out = out
|
|
@@ -84,7 +89,9 @@ class TomlWriter:
|
|
|
84
89
|
self._w(']')
|
|
85
90
|
|
|
86
91
|
def write_key(self, obj: ta.Any) -> None:
|
|
87
|
-
if isinstance(obj,
|
|
92
|
+
if isinstance(obj, TomlWriter.Literal):
|
|
93
|
+
self._w(obj.s)
|
|
94
|
+
elif isinstance(obj, str):
|
|
88
95
|
self._w(self._maybe_quote(obj.replace('_', '-')))
|
|
89
96
|
elif isinstance(obj, int):
|
|
90
97
|
self._w(repr(str(obj)))
|
omdev/tools/dockertools.py
CHANGED
|
@@ -14,6 +14,8 @@ from omlish import lang
|
|
|
14
14
|
from omlish import logs
|
|
15
15
|
from omlish.formats import yaml
|
|
16
16
|
|
|
17
|
+
from ..cli import CliModule
|
|
18
|
+
|
|
17
19
|
|
|
18
20
|
@lang.cached_function
|
|
19
21
|
def docker_exe() -> str:
|
|
@@ -178,6 +180,10 @@ class Cli(ap.Cli):
|
|
|
178
180
|
f.write(new_src)
|
|
179
181
|
|
|
180
182
|
|
|
183
|
+
# @omlish-manifest
|
|
184
|
+
_CLI_MODULE = CliModule('docker', __name__)
|
|
185
|
+
|
|
186
|
+
|
|
181
187
|
if __name__ == '__main__':
|
|
182
188
|
logs.configure_standard_logging('INFO')
|
|
183
189
|
Cli()()
|
omdev/tools/gittools.py
CHANGED
|
@@ -3,6 +3,8 @@ import subprocess
|
|
|
3
3
|
from omlish import argparse as ap
|
|
4
4
|
from omlish import logs
|
|
5
5
|
|
|
6
|
+
from ..cli import CliModule
|
|
7
|
+
|
|
6
8
|
|
|
7
9
|
class Cli(ap.Cli):
|
|
8
10
|
@ap.command()
|
|
@@ -17,6 +19,10 @@ class Cli(ap.Cli):
|
|
|
17
19
|
)
|
|
18
20
|
|
|
19
21
|
|
|
22
|
+
# @omlish-manifest
|
|
23
|
+
_CLI_MODULE = CliModule('git', __name__)
|
|
24
|
+
|
|
25
|
+
|
|
20
26
|
if __name__ == '__main__':
|
|
21
27
|
logs.configure_standard_logging('INFO')
|
|
22
28
|
Cli()()
|
omdev/tools/piptools.py
CHANGED
|
@@ -5,6 +5,8 @@ import xml.etree.ElementTree as ET # noqa
|
|
|
5
5
|
from omlish import argparse as ap
|
|
6
6
|
from omlish import check
|
|
7
7
|
|
|
8
|
+
from ..cli import CliModule
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
PYPI_URL = 'https://pypi.org/'
|
|
10
12
|
|
|
@@ -46,5 +48,9 @@ class Cli(ap.Cli):
|
|
|
46
48
|
f.write(new_src)
|
|
47
49
|
|
|
48
50
|
|
|
51
|
+
# @omlish-manifest
|
|
52
|
+
_CLI_MODULE = CliModule('pip', __name__)
|
|
53
|
+
|
|
54
|
+
|
|
49
55
|
if __name__ == '__main__':
|
|
50
56
|
Cli()()
|
omdev/tools/sqlrepl.py
CHANGED
|
@@ -13,6 +13,8 @@ from omlish import check
|
|
|
13
13
|
from omlish import lang
|
|
14
14
|
from omlish import logs
|
|
15
15
|
|
|
16
|
+
from ..cli import CliModule
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
@dc.dataclass(frozen=True)
|
|
18
20
|
class ServerSpec:
|
|
@@ -188,6 +190,10 @@ class Cli(ap.Cli):
|
|
|
188
190
|
raise Exception(f'unhandled dialect: {dialect=}')
|
|
189
191
|
|
|
190
192
|
|
|
193
|
+
# @omlish-manifest
|
|
194
|
+
_CLI_MODULE = CliModule('sqlrepl', __name__)
|
|
195
|
+
|
|
196
|
+
|
|
191
197
|
if __name__ == '__main__':
|
|
192
198
|
logs.configure_standard_logging('INFO')
|
|
193
199
|
Cli()()
|