omdev 0.0.0.dev11__tar.gz → 0.0.0.dev12__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.
Potentially problematic release.
This version of omdev might be problematic. Click here for more details.
- {omdev-0.0.0.dev11/omdev.egg-info → omdev-0.0.0.dev12}/PKG-INFO +5 -2
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/__about__.py +4 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/cmake.py +1 -2
- omdev-0.0.0.dev12/omdev/exts/cmake.py +342 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/scan.py +2 -2
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/scripts/findmagic.py +5 -2
- omdev-0.0.0.dev12/omdev/tools/revisions.py +173 -0
- omdev-0.0.0.dev12/omdev/wheelfile.py +246 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12/omdev.egg-info}/PKG-INFO +5 -2
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev.egg-info/SOURCES.txt +2 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev.egg-info/requires.txt +5 -1
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/pyproject.toml +6 -2
- omdev-0.0.0.dev11/omdev/exts/cmake.py +0 -208
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/LICENSE +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/MANIFEST.in +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/README.rst +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/amalg/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/amalg/__main__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/amalg/amalg.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/classdot.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/build_ext.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/compilers/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/compilers/ccompiler.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/compilers/options.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/compilers/unixccompiler.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/dir_util.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/errors.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/extension.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/file_util.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/modified.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/spawn.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/sysconfig.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/util.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/_distutils/version.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/build.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/exts/importhook.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/__main__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/cli.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/inspect.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/providers.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/pyenv.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/resolvers.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/standalone.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/system.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/interp/types.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/mypy/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/mypy/debug.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/pyproject/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/pyproject/__main__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/pyproject/cli.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/pyproject/configs.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/pyproject/ext.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/pyproject/pkg.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/scripts/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/scripts/bracepy.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/scripts/execrss.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/scripts/findimports.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/scripts/interp.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/scripts/pyproject.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/scripts/traceimport.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/tokens.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/toml/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/toml/parser.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/toml/writer.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/tools/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/tools/dockertools.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/tools/gittools.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/tools/sqlrepl.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/versioning/__init__.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/versioning/specifiers.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev/versioning/versions.py +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev.egg-info/dependency_links.txt +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/omdev.egg-info/top_level.txt +0 -0
- {omdev-0.0.0.dev11 → omdev-0.0.0.dev12}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev12
|
|
4
4
|
Summary: omdev
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -12,13 +12,14 @@ Classifier: Operating System :: OS Independent
|
|
|
12
12
|
Classifier: Operating System :: POSIX
|
|
13
13
|
Requires-Python: >=3.12
|
|
14
14
|
License-File: LICENSE
|
|
15
|
-
Requires-Dist: omlish==0.0.0.
|
|
15
|
+
Requires-Dist: omlish==0.0.0.dev12
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: pycparser>=2.22; extra == "all"
|
|
18
18
|
Requires-Dist: cffi>=1.17; extra == "all"
|
|
19
19
|
Requires-Dist: pcpp>=1.30; extra == "all"
|
|
20
20
|
Requires-Dist: mypy>=1.11; extra == "all"
|
|
21
21
|
Requires-Dist: tokenize_rt>=6; extra == "all"
|
|
22
|
+
Requires-Dist: wheel>=0.44; extra == "all"
|
|
22
23
|
Provides-Extra: c
|
|
23
24
|
Requires-Dist: pycparser>=2.22; extra == "c"
|
|
24
25
|
Requires-Dist: cffi>=1.17; extra == "c"
|
|
@@ -27,3 +28,5 @@ Provides-Extra: mypy
|
|
|
27
28
|
Requires-Dist: mypy>=1.11; extra == "mypy"
|
|
28
29
|
Provides-Extra: tokens
|
|
29
30
|
Requires-Dist: tokenize_rt>=6; extra == "tokens"
|
|
31
|
+
Provides-Extra: wheel
|
|
32
|
+
Requires-Dist: wheel>=0.44; extra == "wheel"
|
|
@@ -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(os.path.dirname(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)
|
|
@@ -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()
|