omdev 0.0.0.dev11__tar.gz → 0.0.0.dev13__tar.gz
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-0.0.0.dev13/PKG-INFO +32 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/__about__.py +9 -5
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/amalg/amalg.py +13 -1
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/cmake.py +1 -2
- omdev-0.0.0.dev13/omdev/exts/cmake.py +342 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/scan.py +2 -2
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/scripts/findmagic.py +5 -2
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/scripts/interp.py +5 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/scripts/pyproject.py +7 -0
- omdev-0.0.0.dev13/omdev/tools/revisions.py +173 -0
- omdev-0.0.0.dev13/omdev/wheelfile.py +246 -0
- omdev-0.0.0.dev13/omdev.egg-info/PKG-INFO +32 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev.egg-info/SOURCES.txt +2 -0
- omdev-0.0.0.dev13/omdev.egg-info/requires.txt +23 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/pyproject.toml +17 -13
- omdev-0.0.0.dev11/PKG-INFO +0 -29
- omdev-0.0.0.dev11/omdev/exts/cmake.py +0 -208
- omdev-0.0.0.dev11/omdev.egg-info/PKG-INFO +0 -29
- omdev-0.0.0.dev11/omdev.egg-info/requires.txt +0 -19
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/LICENSE +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/MANIFEST.in +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/README.rst +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/amalg/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/amalg/__main__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/classdot.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/build_ext.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/compilers/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/compilers/ccompiler.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/compilers/options.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/compilers/unixccompiler.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/dir_util.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/errors.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/extension.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/file_util.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/modified.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/spawn.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/sysconfig.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/util.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/_distutils/version.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/build.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/exts/importhook.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/__main__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/cli.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/inspect.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/providers.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/pyenv.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/resolvers.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/standalone.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/system.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/interp/types.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/mypy/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/mypy/debug.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/pyproject/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/pyproject/__main__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/pyproject/cli.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/pyproject/configs.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/pyproject/ext.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/pyproject/pkg.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/scripts/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/scripts/bracepy.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/scripts/execrss.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/scripts/findimports.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/scripts/traceimport.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/tokens.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/toml/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/toml/parser.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/toml/writer.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/tools/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/tools/dockertools.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/tools/gittools.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/tools/sqlrepl.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/versioning/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/versioning/specifiers.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev/versioning/versions.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev.egg-info/dependency_links.txt +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/omdev.egg-info/top_level.txt +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev13}/setup.cfg +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: omdev
|
|
3
|
+
Version: 0.0.0.dev13
|
|
4
|
+
Summary: omdev
|
|
5
|
+
Author: wrmsr
|
|
6
|
+
License: BSD-3-Clause
|
|
7
|
+
Project-URL: source, https://github.com/wrmsr/omlish
|
|
8
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
9
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Operating System :: POSIX
|
|
13
|
+
Requires-Python: ~=3.12
|
|
14
|
+
License-File: LICENSE
|
|
15
|
+
Requires-Dist: omlish==0.0.0.dev13
|
|
16
|
+
Provides-Extra: all
|
|
17
|
+
Requires-Dist: pycparser~=2.22; extra == "all"
|
|
18
|
+
Requires-Dist: cffi~=1.17; extra == "all"
|
|
19
|
+
Requires-Dist: pcpp~=1.30; extra == "all"
|
|
20
|
+
Requires-Dist: mypy~=1.11; extra == "all"
|
|
21
|
+
Requires-Dist: tokenize_rt~=6.0; extra == "all"
|
|
22
|
+
Requires-Dist: wheel~=0.44; extra == "all"
|
|
23
|
+
Provides-Extra: c
|
|
24
|
+
Requires-Dist: pycparser~=2.22; extra == "c"
|
|
25
|
+
Requires-Dist: cffi~=1.17; extra == "c"
|
|
26
|
+
Requires-Dist: pcpp~=1.30; extra == "c"
|
|
27
|
+
Provides-Extra: mypy
|
|
28
|
+
Requires-Dist: mypy~=1.11; extra == "mypy"
|
|
29
|
+
Provides-Extra: tokens
|
|
30
|
+
Requires-Dist: tokenize_rt~=6.0; extra == "tokens"
|
|
31
|
+
Provides-Extra: wheel
|
|
32
|
+
Requires-Dist: wheel~=0.44; extra == "wheel"
|
|
@@ -13,17 +13,21 @@ class Project(ProjectBase):
|
|
|
13
13
|
|
|
14
14
|
optional_dependencies = {
|
|
15
15
|
'c': [
|
|
16
|
-
'pycparser
|
|
17
|
-
'cffi
|
|
18
|
-
'pcpp
|
|
16
|
+
'pycparser ~= 2.22',
|
|
17
|
+
'cffi ~= 1.17',
|
|
18
|
+
'pcpp ~= 1.30',
|
|
19
19
|
],
|
|
20
20
|
|
|
21
21
|
'mypy': [
|
|
22
|
-
'mypy
|
|
22
|
+
'mypy ~= 1.11',
|
|
23
23
|
],
|
|
24
24
|
|
|
25
25
|
'tokens': [
|
|
26
|
-
'tokenize_rt
|
|
26
|
+
'tokenize_rt ~= 6.0',
|
|
27
|
+
],
|
|
28
|
+
|
|
29
|
+
'wheel': [
|
|
30
|
+
'wheel ~= 0.44',
|
|
27
31
|
],
|
|
28
32
|
}
|
|
29
33
|
|
|
@@ -363,13 +363,25 @@ def gen_amalg(
|
|
|
363
363
|
|
|
364
364
|
##
|
|
365
365
|
|
|
366
|
+
tyd: dict[str, list[Typing]] = {}
|
|
366
367
|
tys = set()
|
|
367
368
|
for sf in sfs:
|
|
368
369
|
f = src_files[sf]
|
|
369
370
|
for ty in f.typings:
|
|
370
371
|
if ty.src not in tys:
|
|
371
|
-
|
|
372
|
+
tyd.setdefault(f.path, []).append(ty)
|
|
372
373
|
tys.add(ty.src)
|
|
374
|
+
for i, (sf, ftys) in enumerate(tyd.items()):
|
|
375
|
+
f = src_files[sf]
|
|
376
|
+
if i:
|
|
377
|
+
out.write('\n')
|
|
378
|
+
if f is not mf:
|
|
379
|
+
rp = os.path.relpath(f.path, mf.path)
|
|
380
|
+
else:
|
|
381
|
+
rp = os.path.basename(f.path)
|
|
382
|
+
out.write(f'# {rp}\n')
|
|
383
|
+
for ty in ftys:
|
|
384
|
+
out.write(ty.src)
|
|
373
385
|
if tys:
|
|
374
386
|
out.write('\n\n')
|
|
375
387
|
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- symlink headers, included src files (hamt_impl, ...)
|
|
4
|
+
- point / copy output to dst dirs
|
|
5
|
+
- libs
|
|
6
|
+
- ..
|
|
7
|
+
- pybind
|
|
8
|
+
- catch2?
|
|
9
|
+
- json? https://github.com/nlohmann/json
|
|
10
|
+
- FindPackages? FetchContent? built_ext won't have that
|
|
11
|
+
- move omml git / data retriever stuff into omdev, get just the one header file from git via sha?
|
|
12
|
+
- support local built pys
|
|
13
|
+
|
|
14
|
+
==
|
|
15
|
+
|
|
16
|
+
Done:
|
|
17
|
+
- https://intellij-support.jetbrains.com/hc/en-us/community/posts/206608485-Multiple-Jetbrain-IDE-sharing-the-same-project-directory really?
|
|
18
|
+
- aight, generate a whole cmake subdir with symlinks to src files lol
|
|
19
|
+
|
|
20
|
+
""" # noqa
|
|
21
|
+
import argparse
|
|
22
|
+
import dataclasses as dc
|
|
23
|
+
import io
|
|
24
|
+
import logging
|
|
25
|
+
import os.path
|
|
26
|
+
import shutil
|
|
27
|
+
import sys
|
|
28
|
+
import sysconfig
|
|
29
|
+
import typing as ta
|
|
30
|
+
|
|
31
|
+
from omlish import check
|
|
32
|
+
from omlish import lang
|
|
33
|
+
from omlish import logs
|
|
34
|
+
|
|
35
|
+
from .. import cmake
|
|
36
|
+
from ..scripts import findmagic
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
log = logging.getLogger(__name__)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
MAGIC = '@omdev-ext'
|
|
46
|
+
MAGIC_COMMENT = f'// {MAGIC}'
|
|
47
|
+
|
|
48
|
+
FILE_EXTENSIONS = ('c', 'cc', 'cpp')
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _sep_str_grps(*ls: ta.Sequence[str]) -> list[str]:
|
|
52
|
+
o = []
|
|
53
|
+
for i, l in enumerate(ls):
|
|
54
|
+
if not l:
|
|
55
|
+
continue
|
|
56
|
+
if i:
|
|
57
|
+
o.append('')
|
|
58
|
+
o.extend(check.not_isinstance(l, str))
|
|
59
|
+
return o
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class CmakeProjectGen:
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
exts: ta.Sequence[str],
|
|
66
|
+
prj_root: str | None = None,
|
|
67
|
+
) -> None:
|
|
68
|
+
super().__init__()
|
|
69
|
+
self._exts = check.not_isinstance(exts, str)
|
|
70
|
+
self._prj_root = os.path.abspath(prj_root) if prj_root is not None else os.getcwd()
|
|
71
|
+
|
|
72
|
+
#
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def prj_root(self) -> str:
|
|
76
|
+
return self._prj_root
|
|
77
|
+
|
|
78
|
+
@lang.cached_function
|
|
79
|
+
def prj_name(self) -> str:
|
|
80
|
+
return os.path.basename(self.prj_root)
|
|
81
|
+
|
|
82
|
+
@lang.cached_function
|
|
83
|
+
def cmake_dir(self) -> str:
|
|
84
|
+
cmake_dir = os.path.join(self.prj_root, 'cmake')
|
|
85
|
+
if os.path.exists(cmake_dir):
|
|
86
|
+
for e in os.listdir(cmake_dir):
|
|
87
|
+
if e == '.idea':
|
|
88
|
+
continue
|
|
89
|
+
ep = os.path.join(cmake_dir, e)
|
|
90
|
+
if os.path.isfile(ep):
|
|
91
|
+
os.unlink(ep)
|
|
92
|
+
else:
|
|
93
|
+
shutil.rmtree(ep)
|
|
94
|
+
else:
|
|
95
|
+
os.mkdir(cmake_dir)
|
|
96
|
+
return cmake_dir
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
|
|
100
|
+
def write_git_ignore(self) -> None:
|
|
101
|
+
with open(os.path.join(self.cmake_dir(), '.gitignore'), 'w') as f:
|
|
102
|
+
f.write('\n'.join(sorted(['/cmake-*', '/build'])))
|
|
103
|
+
|
|
104
|
+
#
|
|
105
|
+
|
|
106
|
+
def write_idea_name(self) -> None:
|
|
107
|
+
idea_dir = os.path.join(self.cmake_dir(), '.idea')
|
|
108
|
+
if not os.path.isdir(idea_dir):
|
|
109
|
+
os.mkdir(idea_dir)
|
|
110
|
+
idea_name_file = os.path.join(idea_dir, '.name')
|
|
111
|
+
if not os.path.isfile(idea_name_file):
|
|
112
|
+
with open(idea_name_file, 'w') as f:
|
|
113
|
+
f.write(self.prj_name())
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
|
|
117
|
+
@dc.dataclass(frozen=True, kw_only=True)
|
|
118
|
+
class PyInfo:
|
|
119
|
+
venv_exe: str
|
|
120
|
+
venv_root: str
|
|
121
|
+
real_exe: str
|
|
122
|
+
root: str
|
|
123
|
+
suffix: str
|
|
124
|
+
|
|
125
|
+
@lang.cached_function
|
|
126
|
+
def py_info(self) -> PyInfo:
|
|
127
|
+
venv_exe = sys.executable
|
|
128
|
+
real_exe = os.path.realpath(venv_exe)
|
|
129
|
+
return self.PyInfo(
|
|
130
|
+
venv_exe=venv_exe,
|
|
131
|
+
venv_root=os.path.abspath(os.path.join(os.path.dirname(venv_exe), '..')),
|
|
132
|
+
real_exe=real_exe,
|
|
133
|
+
root=os.path.abspath(os.path.join(os.path.dirname(real_exe), '..')),
|
|
134
|
+
suffix='.'.join(map(str, sys.version_info[:2])),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
#
|
|
138
|
+
|
|
139
|
+
@lang.cached_function
|
|
140
|
+
def ext_files(self) -> ta.Sequence[str]:
|
|
141
|
+
out = []
|
|
142
|
+
for e in self._exts:
|
|
143
|
+
e = os.path.abspath(e)
|
|
144
|
+
if os.path.isfile(e):
|
|
145
|
+
out.append(e)
|
|
146
|
+
elif os.path.isdir(e):
|
|
147
|
+
out.extend(
|
|
148
|
+
findmagic.find_magic(
|
|
149
|
+
[e],
|
|
150
|
+
[MAGIC_COMMENT],
|
|
151
|
+
FILE_EXTENSIONS,
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
else:
|
|
155
|
+
raise KeyError(e)
|
|
156
|
+
return out
|
|
157
|
+
|
|
158
|
+
#
|
|
159
|
+
|
|
160
|
+
class _CmakeListsGen:
|
|
161
|
+
def __init__(
|
|
162
|
+
self,
|
|
163
|
+
p: 'CmakeProjectGen',
|
|
164
|
+
out: ta.TextIO,
|
|
165
|
+
) -> None:
|
|
166
|
+
super().__init__()
|
|
167
|
+
self.p = p
|
|
168
|
+
self.g = cmake.CmakeGen(out)
|
|
169
|
+
|
|
170
|
+
@lang.cached_property
|
|
171
|
+
def var_prefix(self) -> str:
|
|
172
|
+
return self.p.prj_name().upper()
|
|
173
|
+
|
|
174
|
+
@lang.cached_property
|
|
175
|
+
def py(self) -> 'CmakeProjectGen.PyInfo':
|
|
176
|
+
return self.p.py_info()
|
|
177
|
+
|
|
178
|
+
def _add_ext(self, ext_src: str) -> None:
|
|
179
|
+
ext_name = ext_src.rpartition('.')[0].replace('/', '__')
|
|
180
|
+
|
|
181
|
+
log.info('Adding cmake c extension: %s -> %s', ext_src, ext_name)
|
|
182
|
+
|
|
183
|
+
so_name = ''.join([
|
|
184
|
+
os.path.basename(ext_src).split('.')[0],
|
|
185
|
+
'.',
|
|
186
|
+
sysconfig.get_config_var('SOABI'),
|
|
187
|
+
sysconfig.get_config_var('SHLIB_SUFFIX'),
|
|
188
|
+
])
|
|
189
|
+
|
|
190
|
+
sl = os.path.join(self.p.cmake_dir(), ext_src)
|
|
191
|
+
sal = os.path.abspath(sl)
|
|
192
|
+
sd = os.path.dirname(sal)
|
|
193
|
+
os.makedirs(sd, exist_ok=True)
|
|
194
|
+
rp = os.path.relpath(os.path.abspath(ext_src), sd)
|
|
195
|
+
os.symlink(rp, sal)
|
|
196
|
+
|
|
197
|
+
ml = cmake.ModuleLibrary(
|
|
198
|
+
ext_name,
|
|
199
|
+
src_files=[
|
|
200
|
+
sl,
|
|
201
|
+
],
|
|
202
|
+
include_dirs=[
|
|
203
|
+
f'${{{self.var_prefix}_INCLUDE_DIRECTORIES}}',
|
|
204
|
+
],
|
|
205
|
+
compile_opts=[
|
|
206
|
+
f'${{{self.var_prefix}_COMPILE_OPTIONS}}',
|
|
207
|
+
],
|
|
208
|
+
link_dirs=[
|
|
209
|
+
f'${{{self.var_prefix}_LINK_DIRECTORIES}}',
|
|
210
|
+
],
|
|
211
|
+
link_libs=[
|
|
212
|
+
f'${{{self.var_prefix}_LINK_LIBRARIES}}',
|
|
213
|
+
],
|
|
214
|
+
extra_cmds=[
|
|
215
|
+
cmake.Command(
|
|
216
|
+
'add_custom_command',
|
|
217
|
+
['TARGET', ext_name, 'POST_BUILD'],
|
|
218
|
+
[
|
|
219
|
+
' '.join([
|
|
220
|
+
'COMMAND ${CMAKE_COMMAND} -E ',
|
|
221
|
+
f'copy $<TARGET_FILE_NAME:{ext_name}> ../../{os.path.dirname(ext_src)}/{so_name}',
|
|
222
|
+
]),
|
|
223
|
+
'COMMAND_EXPAND_LISTS',
|
|
224
|
+
],
|
|
225
|
+
),
|
|
226
|
+
],
|
|
227
|
+
)
|
|
228
|
+
self.g.write_target(ml)
|
|
229
|
+
|
|
230
|
+
def run(self) -> None:
|
|
231
|
+
self.g.write(self.g.preamble)
|
|
232
|
+
self.g.write('')
|
|
233
|
+
|
|
234
|
+
self.g.write(f'project({self.p.prj_name()})')
|
|
235
|
+
self.g.write('')
|
|
236
|
+
|
|
237
|
+
self.g.write_var(cmake.Var(
|
|
238
|
+
f'{self.var_prefix}_INCLUDE_DIRECTORIES',
|
|
239
|
+
_sep_str_grps(
|
|
240
|
+
[f'{self.py.venv_root}/include'],
|
|
241
|
+
[f'{self.py.root}/include/python{self.py.suffix}'],
|
|
242
|
+
[
|
|
243
|
+
# $ENV{HOME}/src/python/cpython
|
|
244
|
+
# $ENV{HOME}/src/python/cpython/include
|
|
245
|
+
],
|
|
246
|
+
),
|
|
247
|
+
))
|
|
248
|
+
|
|
249
|
+
self.g.write_var(cmake.Var(
|
|
250
|
+
f'{self.var_prefix}_COMPILE_OPTIONS',
|
|
251
|
+
_sep_str_grps(
|
|
252
|
+
[
|
|
253
|
+
'-Wsign-compare',
|
|
254
|
+
'-Wunreachable-code',
|
|
255
|
+
'-DNDEBUG',
|
|
256
|
+
'-g',
|
|
257
|
+
'-fwrapv',
|
|
258
|
+
'-O3',
|
|
259
|
+
'-Wall',
|
|
260
|
+
],
|
|
261
|
+
[
|
|
262
|
+
'-g',
|
|
263
|
+
'-c',
|
|
264
|
+
],
|
|
265
|
+
['-std=c++20'],
|
|
266
|
+
),
|
|
267
|
+
))
|
|
268
|
+
|
|
269
|
+
self.g.write_var(cmake.Var(
|
|
270
|
+
f'{self.var_prefix}_LINK_DIRECTORIES',
|
|
271
|
+
_sep_str_grps(
|
|
272
|
+
[f'{self.py.root}/lib'],
|
|
273
|
+
# ['$ENV{HOME}/src/python/cpython'],
|
|
274
|
+
),
|
|
275
|
+
))
|
|
276
|
+
|
|
277
|
+
self.g.write_var(cmake.Var(
|
|
278
|
+
f'{self.var_prefix}_LINK_LIBRARIES',
|
|
279
|
+
_sep_str_grps(
|
|
280
|
+
*([[
|
|
281
|
+
'-bundle',
|
|
282
|
+
'"-undefined dynamic_lookup"',
|
|
283
|
+
]] if sys.platform == 'darwin' else []),
|
|
284
|
+
),
|
|
285
|
+
))
|
|
286
|
+
|
|
287
|
+
for ext_src in self.p.ext_files():
|
|
288
|
+
self._add_ext(os.path.relpath(ext_src, self.p.prj_root))
|
|
289
|
+
|
|
290
|
+
#
|
|
291
|
+
|
|
292
|
+
def run(self) -> None:
|
|
293
|
+
if not os.path.isfile(os.path.join(self._prj_root, 'pyproject.toml')):
|
|
294
|
+
raise Exception('Must be run in project root')
|
|
295
|
+
|
|
296
|
+
self.ext_files()
|
|
297
|
+
|
|
298
|
+
log.info('Generating cmake project %s', self.prj_name())
|
|
299
|
+
|
|
300
|
+
self.cmake_dir()
|
|
301
|
+
self.write_git_ignore()
|
|
302
|
+
self.write_idea_name()
|
|
303
|
+
|
|
304
|
+
out = io.StringIO()
|
|
305
|
+
clg = self._CmakeListsGen(self, out)
|
|
306
|
+
clg.run()
|
|
307
|
+
|
|
308
|
+
with open(os.path.join(self.cmake_dir(), 'CMakeLists.txt'), 'w') as f:
|
|
309
|
+
f.write(out.getvalue())
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
##
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
def _gen_cmd(args) -> None:
|
|
316
|
+
if not args.exts:
|
|
317
|
+
raise Exception('must specify exts')
|
|
318
|
+
|
|
319
|
+
cpg = CmakeProjectGen(args.exts)
|
|
320
|
+
cpg.run()
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def _main(argv=None) -> None:
|
|
324
|
+
logs.configure_standard_logging('INFO')
|
|
325
|
+
|
|
326
|
+
parser = argparse.ArgumentParser()
|
|
327
|
+
|
|
328
|
+
subparsers = parser.add_subparsers()
|
|
329
|
+
|
|
330
|
+
parser_gen = subparsers.add_parser('gen')
|
|
331
|
+
parser_gen.add_argument('exts', nargs='*')
|
|
332
|
+
parser_gen.set_defaults(func=_gen_cmd)
|
|
333
|
+
|
|
334
|
+
args = parser.parse_args(argv)
|
|
335
|
+
if not getattr(args, 'func', None):
|
|
336
|
+
parser.print_help()
|
|
337
|
+
else:
|
|
338
|
+
args.func(args)
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
if __name__ == '__main__':
|
|
342
|
+
_main()
|
|
@@ -12,7 +12,7 @@ log = logging.getLogger(__name__)
|
|
|
12
12
|
SCAN_COMMENT = '// @omdev-ext'
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
def
|
|
15
|
+
def scan_one(
|
|
16
16
|
input_path: str,
|
|
17
17
|
**kwargs: ta.Any,
|
|
18
18
|
) -> None:
|
|
@@ -42,7 +42,7 @@ def _scan_cmd(args) -> None:
|
|
|
42
42
|
log.info('Scanning %s', i)
|
|
43
43
|
for we_dirpath, we_dirnames, we_filenames in os.walk(i): # noqa
|
|
44
44
|
for fname in we_filenames:
|
|
45
|
-
|
|
45
|
+
scan_one(
|
|
46
46
|
os.path.abspath(os.path.join(we_dirpath, fname)),
|
|
47
47
|
)
|
|
48
48
|
|
|
@@ -28,8 +28,11 @@ def find_magic(
|
|
|
28
28
|
continue
|
|
29
29
|
|
|
30
30
|
fp = os.path.join(dp, fn)
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
try:
|
|
32
|
+
with open(fp) as f:
|
|
33
|
+
src = f.read()
|
|
34
|
+
except UnicodeDecodeError:
|
|
35
|
+
continue
|
|
33
36
|
|
|
34
37
|
if not any(
|
|
35
38
|
any(pat.fullmatch(l) for pat in pats)
|
|
@@ -29,13 +29,18 @@ import threading
|
|
|
29
29
|
import typing as ta
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
# ../../versioning/versions.py
|
|
32
33
|
VersionLocalType = ta.Tuple[ta.Union[int, str], ...]
|
|
33
34
|
VersionCmpPrePostDevType = ta.Union['InfinityVersionType', 'NegativeInfinityVersionType', ta.Tuple[str, int]]
|
|
34
35
|
_VersionCmpLocalType0 = ta.Tuple[ta.Union[ta.Tuple[int, str], ta.Tuple['NegativeInfinityVersionType', ta.Union[int, str]]], ...] # noqa
|
|
35
36
|
VersionCmpLocalType = ta.Union['NegativeInfinityVersionType', _VersionCmpLocalType0]
|
|
36
37
|
VersionCmpKey = ta.Tuple[int, ta.Tuple[int, ...], VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpLocalType] # noqa
|
|
37
38
|
VersionComparisonMethod = ta.Callable[[VersionCmpKey, VersionCmpKey], bool]
|
|
39
|
+
|
|
40
|
+
# ../../../omlish/lite/check.py
|
|
38
41
|
T = ta.TypeVar('T')
|
|
42
|
+
|
|
43
|
+
# ../../versioning/specifiers.py
|
|
39
44
|
UnparsedVersion = ta.Union['Version', str]
|
|
40
45
|
UnparsedVersionVar = ta.TypeVar('UnparsedVersionVar', bound=UnparsedVersion)
|
|
41
46
|
CallableVersionOperator = ta.Callable[['Version', str], bool]
|
|
@@ -55,16 +55,23 @@ import uuid
|
|
|
55
55
|
import weakref # noqa
|
|
56
56
|
|
|
57
57
|
|
|
58
|
+
# ../../toml/parser.py
|
|
58
59
|
TomlParseFloat = ta.Callable[[str], ta.Any]
|
|
59
60
|
TomlKey = ta.Tuple[str, ...]
|
|
60
61
|
TomlPos = int # ta.TypeAlias
|
|
62
|
+
|
|
63
|
+
# ../../versioning/versions.py
|
|
61
64
|
VersionLocalType = ta.Tuple[ta.Union[int, str], ...]
|
|
62
65
|
VersionCmpPrePostDevType = ta.Union['InfinityVersionType', 'NegativeInfinityVersionType', ta.Tuple[str, int]]
|
|
63
66
|
_VersionCmpLocalType0 = ta.Tuple[ta.Union[ta.Tuple[int, str], ta.Tuple['NegativeInfinityVersionType', ta.Union[int, str]]], ...] # noqa
|
|
64
67
|
VersionCmpLocalType = ta.Union['NegativeInfinityVersionType', _VersionCmpLocalType0]
|
|
65
68
|
VersionCmpKey = ta.Tuple[int, ta.Tuple[int, ...], VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpPrePostDevType, VersionCmpLocalType] # noqa
|
|
66
69
|
VersionComparisonMethod = ta.Callable[[VersionCmpKey, VersionCmpKey], bool]
|
|
70
|
+
|
|
71
|
+
# ../../../omlish/lite/check.py
|
|
67
72
|
T = ta.TypeVar('T')
|
|
73
|
+
|
|
74
|
+
# ../../versioning/specifiers.py
|
|
68
75
|
UnparsedVersion = ta.Union['Version', str]
|
|
69
76
|
UnparsedVersionVar = ta.TypeVar('UnparsedVersionVar', bound=UnparsedVersion)
|
|
70
77
|
CallableVersionOperator = ta.Callable[['Version', str], bool]
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TODO:
|
|
3
|
+
- omlish-lite, move to pyproject/
|
|
4
|
+
- vendor-lite wheel.wheelfile
|
|
5
|
+
"""
|
|
6
|
+
# ruff: noqa: TCH003 UP006 UP007
|
|
7
|
+
# @omlish-lite
|
|
8
|
+
import argparse
|
|
9
|
+
import io
|
|
10
|
+
import os.path
|
|
11
|
+
import subprocess
|
|
12
|
+
import tarfile
|
|
13
|
+
import typing as ta
|
|
14
|
+
import zipfile
|
|
15
|
+
|
|
16
|
+
from omlish.lite.logs import configure_standard_logging
|
|
17
|
+
from omlish.lite.logs import log
|
|
18
|
+
|
|
19
|
+
from ..wheelfile import WheelFile
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class RevisionAdder:
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
revision: str,
|
|
26
|
+
output_suffix: ta.Optional[str] = None,
|
|
27
|
+
) -> None:
|
|
28
|
+
super().__init__()
|
|
29
|
+
self._revision = revision
|
|
30
|
+
self._output_suffix = output_suffix
|
|
31
|
+
|
|
32
|
+
REVISION_ATTR = '__revision__'
|
|
33
|
+
|
|
34
|
+
def add_to_contents(self, dct: ta.Dict[str, bytes]) -> bool:
|
|
35
|
+
changed = False
|
|
36
|
+
for n in dct:
|
|
37
|
+
if not n.endswith('__about__.py'):
|
|
38
|
+
continue
|
|
39
|
+
src = dct[n].decode('utf-8')
|
|
40
|
+
lines = src.splitlines(keepends=True)
|
|
41
|
+
for i, l in enumerate(lines):
|
|
42
|
+
if l != f'{self.REVISION_ATTR} = None\n':
|
|
43
|
+
continue
|
|
44
|
+
lines[i] = f"{self.REVISION_ATTR} = '{self._revision}'\n"
|
|
45
|
+
changed = True
|
|
46
|
+
dct[n] = ''.join(lines).encode('utf-8')
|
|
47
|
+
return changed
|
|
48
|
+
|
|
49
|
+
def add_to_wheel(self, f: str) -> None:
|
|
50
|
+
if not f.endswith('.whl'):
|
|
51
|
+
raise Exception(f)
|
|
52
|
+
log.info('Scanning wheel %s', f)
|
|
53
|
+
|
|
54
|
+
zis: ta.Dict[str, zipfile.ZipInfo] = {}
|
|
55
|
+
dct: ta.Dict[str, bytes] = {}
|
|
56
|
+
with WheelFile(f) as wf:
|
|
57
|
+
for zi in wf.filelist:
|
|
58
|
+
if zi.filename == wf.record_path:
|
|
59
|
+
continue
|
|
60
|
+
zis[zi.filename] = zi
|
|
61
|
+
dct[zi.filename] = wf.read(zi.filename)
|
|
62
|
+
|
|
63
|
+
if self.add_to_contents(dct):
|
|
64
|
+
of = f[:-4] + (self._output_suffix or '') + '.whl'
|
|
65
|
+
log.info('Repacking wheel %s', of)
|
|
66
|
+
with WheelFile(of, 'w') as wf:
|
|
67
|
+
for n, d in dct.items():
|
|
68
|
+
log.info('Adding zipinfo %s', n)
|
|
69
|
+
wf.writestr(zis[n], d)
|
|
70
|
+
|
|
71
|
+
def add_to_tgz(self, f: str) -> None:
|
|
72
|
+
if not f.endswith('.tar.gz'):
|
|
73
|
+
raise Exception(f)
|
|
74
|
+
log.info('Scanning tgz %s', f)
|
|
75
|
+
|
|
76
|
+
tis: ta.Dict[str, tarfile.TarInfo] = {}
|
|
77
|
+
dct: ta.Dict[str, bytes] = {}
|
|
78
|
+
with tarfile.open(f, 'r:gz') as tf:
|
|
79
|
+
for ti in tf:
|
|
80
|
+
tis[ti.name] = ti
|
|
81
|
+
if ti.type == tarfile.REGTYPE:
|
|
82
|
+
with tf.extractfile(ti.name) as tif: # type: ignore
|
|
83
|
+
dct[ti.name] = tif.read()
|
|
84
|
+
|
|
85
|
+
if self.add_to_contents(dct):
|
|
86
|
+
of = f[:-7] + (self._output_suffix or '') + '.tar.gz'
|
|
87
|
+
log.info('Repacking tgz %s', of)
|
|
88
|
+
with tarfile.open(of, 'w:gz') as tf:
|
|
89
|
+
for n, ti in tis.items():
|
|
90
|
+
log.info('Adding tarinfo %s', n)
|
|
91
|
+
if n in dct:
|
|
92
|
+
data = dct[n]
|
|
93
|
+
ti.size = len(data)
|
|
94
|
+
fo = io.BytesIO(data)
|
|
95
|
+
else:
|
|
96
|
+
fo = None
|
|
97
|
+
tf.addfile(ti, fileobj=fo)
|
|
98
|
+
|
|
99
|
+
EXTS = ('.tar.gz', '.whl')
|
|
100
|
+
|
|
101
|
+
def add_to_file(self, f: str) -> None:
|
|
102
|
+
if f.endswith('.whl'):
|
|
103
|
+
self.add_to_wheel(f)
|
|
104
|
+
|
|
105
|
+
elif f.endswith('.tar.gz'):
|
|
106
|
+
self.add_to_tgz(f)
|
|
107
|
+
|
|
108
|
+
def add_to(self, tgt: str) -> None:
|
|
109
|
+
if os.path.isfile(tgt):
|
|
110
|
+
self.add_to_file(tgt)
|
|
111
|
+
|
|
112
|
+
elif os.path.isdir(tgt):
|
|
113
|
+
for dp, dns, fns in os.walk(tgt): # noqa
|
|
114
|
+
for f in fns:
|
|
115
|
+
if any(f.endswith(ext) for ext in self.EXTS):
|
|
116
|
+
self.add_to_file(os.path.join(dp, f))
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
#
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def get_revision() -> str:
|
|
123
|
+
return subprocess.check_output([
|
|
124
|
+
'git',
|
|
125
|
+
'describe',
|
|
126
|
+
'--match=NeVeRmAtCh',
|
|
127
|
+
'--always',
|
|
128
|
+
'--abbrev=40',
|
|
129
|
+
'--dirty',
|
|
130
|
+
]).decode().strip()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _add_cmd(args) -> None:
|
|
137
|
+
if (revision := args.revision) is None:
|
|
138
|
+
revision = get_revision()
|
|
139
|
+
log.info('Using revision %s', revision)
|
|
140
|
+
|
|
141
|
+
if not args.targets:
|
|
142
|
+
raise Exception('must specify targets')
|
|
143
|
+
|
|
144
|
+
ra = RevisionAdder(
|
|
145
|
+
revision,
|
|
146
|
+
output_suffix=args.suffix,
|
|
147
|
+
)
|
|
148
|
+
for tgt in args.targets:
|
|
149
|
+
ra.add_to(tgt)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def _main(argv=None) -> None:
|
|
153
|
+
configure_standard_logging('INFO')
|
|
154
|
+
|
|
155
|
+
parser = argparse.ArgumentParser()
|
|
156
|
+
|
|
157
|
+
subparsers = parser.add_subparsers()
|
|
158
|
+
|
|
159
|
+
parser_add = subparsers.add_parser('add')
|
|
160
|
+
parser_add.add_argument('-r', '--revision')
|
|
161
|
+
parser_add.add_argument('-s', '--suffix')
|
|
162
|
+
parser_add.add_argument('targets', nargs='*')
|
|
163
|
+
parser_add.set_defaults(func=_add_cmd)
|
|
164
|
+
|
|
165
|
+
args = parser.parse_args(argv)
|
|
166
|
+
if not getattr(args, 'func', None):
|
|
167
|
+
parser.print_help()
|
|
168
|
+
else:
|
|
169
|
+
args.func(args)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
if __name__ == '__main__':
|
|
173
|
+
_main()
|