omdev 0.0.0.dev30__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 +53 -4
- omdev/manifests/__init__.py +2 -0
- omdev/{manifests.py → manifests/build.py} +97 -34
- 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 +2 -2
- omdev/pyproject/pkg.py +13 -2
- omdev/pyproject/reqs.py +1 -1
- omdev/scripts/interp.py +64 -9
- omdev/scripts/pyproject.py +77 -11
- omdev/secrets.py +12 -0
- 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.dev30.dist-info → omdev-0.0.0.dev32.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev30.dist-info → omdev-0.0.0.dev32.dist-info}/RECORD +38 -29
- omdev-0.0.0.dev32.dist-info/entry_points.txt +2 -0
- {omdev-0.0.0.dev30.dist-info → omdev-0.0.0.dev32.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev30.dist-info → omdev-0.0.0.dev32.dist-info}/WHEEL +0 -0
- {omdev-0.0.0.dev30.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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# @
|
|
2
|
+
# @omlish-amalg ../scripts/pyproject.py
|
|
3
3
|
# ruff: noqa: UP006 UP007
|
|
4
4
|
"""
|
|
5
5
|
TODO:
|
|
@@ -9,7 +9,7 @@ TODO:
|
|
|
9
9
|
- {pkg_name: [src_dirs]}, default excludes, generate MANIFST.in, ...
|
|
10
10
|
- env vars - PYTHONPATH
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
See:
|
|
13
13
|
- https://pdm-project.org/en/latest/
|
|
14
14
|
- https://rye.astral.sh/philosophy/
|
|
15
15
|
- https://github.com/indygreg/python-build-standalone/blob/main/pythonbuild/cpython.py
|
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,6 +1796,11 @@ 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
1806
|
"""
|
|
@@ -1892,8 +1897,33 @@ class PyenvInstallOpts:
|
|
|
1892
1897
|
)
|
|
1893
1898
|
|
|
1894
1899
|
|
|
1895
|
-
|
|
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
|
+
|
|
1896
1925
|
DEBUG_PYENV_INSTALL_OPTS = PyenvInstallOpts(opts=['-g'])
|
|
1926
|
+
|
|
1897
1927
|
THREADED_PYENV_INSTALL_OPTS = PyenvInstallOpts(conf_opts=['--disable-gil'])
|
|
1898
1928
|
|
|
1899
1929
|
|
|
@@ -1992,6 +2022,7 @@ class PyenvVersionInstaller:
|
|
|
1992
2022
|
opts: ta.Optional[PyenvInstallOpts] = None,
|
|
1993
2023
|
interp_opts: InterpOpts = InterpOpts(),
|
|
1994
2024
|
*,
|
|
2025
|
+
install_name: ta.Optional[str] = None,
|
|
1995
2026
|
no_default_opts: bool = False,
|
|
1996
2027
|
pyenv: Pyenv = Pyenv(),
|
|
1997
2028
|
) -> None:
|
|
@@ -2012,6 +2043,7 @@ class PyenvVersionInstaller:
|
|
|
2012
2043
|
self._version = version
|
|
2013
2044
|
self._opts = opts
|
|
2014
2045
|
self._interp_opts = interp_opts
|
|
2046
|
+
self._given_install_name = install_name
|
|
2015
2047
|
|
|
2016
2048
|
self._no_default_opts = no_default_opts
|
|
2017
2049
|
self._pyenv = pyenv
|
|
@@ -2026,6 +2058,8 @@ class PyenvVersionInstaller:
|
|
|
2026
2058
|
|
|
2027
2059
|
@cached_nullary
|
|
2028
2060
|
def install_name(self) -> str:
|
|
2061
|
+
if self._given_install_name is not None:
|
|
2062
|
+
return self._given_install_name
|
|
2029
2063
|
return self._version + ('-debug' if self._interp_opts.debug else '')
|
|
2030
2064
|
|
|
2031
2065
|
@cached_nullary
|
|
@@ -2045,11 +2079,26 @@ class PyenvVersionInstaller:
|
|
|
2045
2079
|
v += ' ' + os.environ[k]
|
|
2046
2080
|
env[k] = v
|
|
2047
2081
|
|
|
2048
|
-
|
|
2049
|
-
self._pyenv.exe(),
|
|
2050
|
-
'install',
|
|
2082
|
+
conf_args = [
|
|
2051
2083
|
*self._opts.opts,
|
|
2052
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,
|
|
2053
2102
|
env=env,
|
|
2054
2103
|
)
|
|
2055
2104
|
|
|
@@ -2407,9 +2456,13 @@ def _list_cmd(args) -> None:
|
|
|
2407
2456
|
|
|
2408
2457
|
|
|
2409
2458
|
def _resolve_cmd(args) -> None:
|
|
2410
|
-
|
|
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
|
|
2411
2464
|
s = InterpSpecifier.parse(args.version)
|
|
2412
|
-
print(check_not_none(r.resolve(s)).exe)
|
|
2465
|
+
print(check_not_none(r.resolve(s, install=bool(args.install))).exe)
|
|
2413
2466
|
|
|
2414
2467
|
|
|
2415
2468
|
def _build_parser() -> argparse.ArgumentParser:
|
|
@@ -2419,12 +2472,14 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
2419
2472
|
|
|
2420
2473
|
parser_list = subparsers.add_parser('list')
|
|
2421
2474
|
parser_list.add_argument('version')
|
|
2422
|
-
parser_list.add_argument('--debug', action='store_true')
|
|
2475
|
+
parser_list.add_argument('-d', '--debug', action='store_true')
|
|
2423
2476
|
parser_list.set_defaults(func=_list_cmd)
|
|
2424
2477
|
|
|
2425
2478
|
parser_resolve = subparsers.add_parser('resolve')
|
|
2426
2479
|
parser_resolve.add_argument('version')
|
|
2427
|
-
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')
|
|
2428
2483
|
parser_resolve.set_defaults(func=_resolve_cmd)
|
|
2429
2484
|
|
|
2430
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:
|
|
@@ -12,7 +12,7 @@ TODO:
|
|
|
12
12
|
- {pkg_name: [src_dirs]}, default excludes, generate MANIFST.in, ...
|
|
13
13
|
- env vars - PYTHONPATH
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
See:
|
|
16
16
|
- https://pdm-project.org/en/latest/
|
|
17
17
|
- https://rye.astral.sh/philosophy/
|
|
18
18
|
- https://github.com/indygreg/python-build-standalone/blob/main/pythonbuild/cpython.py
|
|
@@ -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,6 +4250,11 @@ 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
4260
|
"""
|
|
@@ -4329,8 +4351,33 @@ class PyenvInstallOpts:
|
|
|
4329
4351
|
)
|
|
4330
4352
|
|
|
4331
4353
|
|
|
4332
|
-
|
|
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
|
+
|
|
4333
4379
|
DEBUG_PYENV_INSTALL_OPTS = PyenvInstallOpts(opts=['-g'])
|
|
4380
|
+
|
|
4334
4381
|
THREADED_PYENV_INSTALL_OPTS = PyenvInstallOpts(conf_opts=['--disable-gil'])
|
|
4335
4382
|
|
|
4336
4383
|
|
|
@@ -4429,6 +4476,7 @@ class PyenvVersionInstaller:
|
|
|
4429
4476
|
opts: ta.Optional[PyenvInstallOpts] = None,
|
|
4430
4477
|
interp_opts: InterpOpts = InterpOpts(),
|
|
4431
4478
|
*,
|
|
4479
|
+
install_name: ta.Optional[str] = None,
|
|
4432
4480
|
no_default_opts: bool = False,
|
|
4433
4481
|
pyenv: Pyenv = Pyenv(),
|
|
4434
4482
|
) -> None:
|
|
@@ -4449,6 +4497,7 @@ class PyenvVersionInstaller:
|
|
|
4449
4497
|
self._version = version
|
|
4450
4498
|
self._opts = opts
|
|
4451
4499
|
self._interp_opts = interp_opts
|
|
4500
|
+
self._given_install_name = install_name
|
|
4452
4501
|
|
|
4453
4502
|
self._no_default_opts = no_default_opts
|
|
4454
4503
|
self._pyenv = pyenv
|
|
@@ -4463,6 +4512,8 @@ class PyenvVersionInstaller:
|
|
|
4463
4512
|
|
|
4464
4513
|
@cached_nullary
|
|
4465
4514
|
def install_name(self) -> str:
|
|
4515
|
+
if self._given_install_name is not None:
|
|
4516
|
+
return self._given_install_name
|
|
4466
4517
|
return self._version + ('-debug' if self._interp_opts.debug else '')
|
|
4467
4518
|
|
|
4468
4519
|
@cached_nullary
|
|
@@ -4482,11 +4533,26 @@ class PyenvVersionInstaller:
|
|
|
4482
4533
|
v += ' ' + os.environ[k]
|
|
4483
4534
|
env[k] = v
|
|
4484
4535
|
|
|
4485
|
-
|
|
4486
|
-
self._pyenv.exe(),
|
|
4487
|
-
'install',
|
|
4536
|
+
conf_args = [
|
|
4488
4537
|
*self._opts.opts,
|
|
4489
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,
|
|
4490
4556
|
env=env,
|
|
4491
4557
|
)
|
|
4492
4558
|
|
omdev/secrets.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import os.path
|
|
2
|
+
import typing as ta
|
|
3
|
+
|
|
4
|
+
import yaml
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
SECRETS_PATH = os.getenv('SECRETS_PATH', os.path.expanduser('~/Dropbox/.dotfiles/secrets.yml'))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def load_secrets() -> dict[str, ta.Any]:
|
|
11
|
+
with open(SECRETS_PATH) as f:
|
|
12
|
+
return yaml.safe_load(f)
|
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()()
|