omdev 0.0.0.dev16__py3-none-any.whl → 0.0.0.dev18__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/__about__.py +2 -0
- omdev/{exts → cexts}/cmake.py +7 -23
- omdev/cexts/magic.py +7 -0
- omdev/{exts → cexts}/scan.py +5 -6
- omdev/pyproject/cli.py +9 -7
- omdev/pyproject/pkg.py +235 -82
- omdev/scripts/pyproject.py +310 -90
- omdev/toml/writer.py +4 -1
- {omdev-0.0.0.dev16.dist-info → omdev-0.0.0.dev18.dist-info}/METADATA +2 -2
- {omdev-0.0.0.dev16.dist-info → omdev-0.0.0.dev18.dist-info}/RECORD +32 -31
- {omdev-0.0.0.dev16.dist-info → omdev-0.0.0.dev18.dist-info}/WHEEL +1 -1
- /omdev/{exts → cexts}/__init__.py +0 -0
- /omdev/{exts → cexts}/_distutils/__init__.py +0 -0
- /omdev/{exts → cexts}/_distutils/build_ext.py +0 -0
- /omdev/{exts → cexts}/_distutils/compilers/__init__.py +0 -0
- /omdev/{exts → cexts}/_distutils/compilers/ccompiler.py +0 -0
- /omdev/{exts → cexts}/_distutils/compilers/options.py +0 -0
- /omdev/{exts → cexts}/_distutils/compilers/unixccompiler.py +0 -0
- /omdev/{exts → cexts}/_distutils/dir_util.py +0 -0
- /omdev/{exts → cexts}/_distutils/errors.py +0 -0
- /omdev/{exts → cexts}/_distutils/extension.py +0 -0
- /omdev/{exts → cexts}/_distutils/file_util.py +0 -0
- /omdev/{exts → cexts}/_distutils/modified.py +0 -0
- /omdev/{exts → cexts}/_distutils/spawn.py +0 -0
- /omdev/{exts → cexts}/_distutils/sysconfig.py +0 -0
- /omdev/{exts → cexts}/_distutils/util.py +0 -0
- /omdev/{exts → cexts}/_distutils/version.py +0 -0
- /omdev/{exts → cexts}/build.py +0 -0
- /omdev/{exts → cexts}/importhook.py +0 -0
- /omdev/pyproject/{ext.py → cexts.py} +0 -0
- {omdev-0.0.0.dev16.dist-info → omdev-0.0.0.dev18.dist-info}/LICENSE +0 -0
- {omdev-0.0.0.dev16.dist-info → omdev-0.0.0.dev18.dist-info}/top_level.txt +0 -0
omdev/__about__.py
CHANGED
omdev/{exts → cexts}/cmake.py
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
FIXME:
|
|
3
3
|
- debug tables don't handle symlinks
|
|
4
|
+
- use relapths in cml.txt
|
|
4
5
|
|
|
5
6
|
TODO:
|
|
6
7
|
- symlink headers, included src files (hamt_impl, ...)
|
|
@@ -37,6 +38,7 @@ from omlish import logs
|
|
|
37
38
|
|
|
38
39
|
from .. import cmake
|
|
39
40
|
from .. import findmagic
|
|
41
|
+
from .magic import CextMagic
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
log = logging.getLogger(__name__)
|
|
@@ -45,12 +47,6 @@ log = logging.getLogger(__name__)
|
|
|
45
47
|
##
|
|
46
48
|
|
|
47
49
|
|
|
48
|
-
MAGIC = '@omdev-ext'
|
|
49
|
-
MAGIC_COMMENT = f'// {MAGIC}'
|
|
50
|
-
|
|
51
|
-
FILE_EXTENSIONS = ('c', 'cc', 'cpp')
|
|
52
|
-
|
|
53
|
-
|
|
54
50
|
def _sep_str_grps(*ls: ta.Sequence[str]) -> list[str]:
|
|
55
51
|
o = []
|
|
56
52
|
for i, l in enumerate(ls):
|
|
@@ -87,7 +83,7 @@ class CmakeProjectGen:
|
|
|
87
83
|
|
|
88
84
|
@lang.cached_function
|
|
89
85
|
def cmake_dir(self) -> str:
|
|
90
|
-
cmake_dir = os.path.join(self.prj_root, 'cmake')
|
|
86
|
+
cmake_dir = os.path.join(self.prj_root, 'cmake', self.prj_name())
|
|
91
87
|
if os.path.exists(cmake_dir):
|
|
92
88
|
for e in os.listdir(cmake_dir):
|
|
93
89
|
if e == '.idea':
|
|
@@ -98,7 +94,7 @@ class CmakeProjectGen:
|
|
|
98
94
|
else:
|
|
99
95
|
shutil.rmtree(ep)
|
|
100
96
|
else:
|
|
101
|
-
os.
|
|
97
|
+
os.makedirs(cmake_dir)
|
|
102
98
|
return cmake_dir
|
|
103
99
|
|
|
104
100
|
#
|
|
@@ -109,17 +105,6 @@ class CmakeProjectGen:
|
|
|
109
105
|
|
|
110
106
|
#
|
|
111
107
|
|
|
112
|
-
def write_idea_name(self) -> None:
|
|
113
|
-
idea_dir = os.path.join(self.cmake_dir(), '.idea')
|
|
114
|
-
if not os.path.isdir(idea_dir):
|
|
115
|
-
os.mkdir(idea_dir)
|
|
116
|
-
idea_name_file = os.path.join(idea_dir, '.name')
|
|
117
|
-
if not os.path.isfile(idea_name_file):
|
|
118
|
-
with open(idea_name_file, 'w') as f:
|
|
119
|
-
f.write(self.prj_name())
|
|
120
|
-
|
|
121
|
-
#
|
|
122
|
-
|
|
123
108
|
@dc.dataclass(frozen=True, kw_only=True)
|
|
124
109
|
class PyInfo:
|
|
125
110
|
venv_exe: str
|
|
@@ -153,8 +138,8 @@ class CmakeProjectGen:
|
|
|
153
138
|
out.extend(
|
|
154
139
|
findmagic.find_magic(
|
|
155
140
|
[e],
|
|
156
|
-
[MAGIC_COMMENT],
|
|
157
|
-
FILE_EXTENSIONS,
|
|
141
|
+
[CextMagic.MAGIC_COMMENT],
|
|
142
|
+
CextMagic.FILE_EXTENSIONS,
|
|
158
143
|
),
|
|
159
144
|
)
|
|
160
145
|
else:
|
|
@@ -224,7 +209,7 @@ class CmakeProjectGen:
|
|
|
224
209
|
[
|
|
225
210
|
' '.join([
|
|
226
211
|
'COMMAND ${CMAKE_COMMAND} -E ',
|
|
227
|
-
f'copy $<TARGET_FILE_NAME:{ext_name}>
|
|
212
|
+
f'copy $<TARGET_FILE_NAME:{ext_name}> ../../../{os.path.dirname(ext_src)}/{so_name}',
|
|
228
213
|
]),
|
|
229
214
|
'COMMAND_EXPAND_LISTS',
|
|
230
215
|
],
|
|
@@ -311,7 +296,6 @@ class CmakeProjectGen:
|
|
|
311
296
|
|
|
312
297
|
self.cmake_dir()
|
|
313
298
|
self.write_git_ignore()
|
|
314
|
-
self.write_idea_name()
|
|
315
299
|
|
|
316
300
|
out = io.StringIO()
|
|
317
301
|
clg = self._CmakeListsGen(self, out)
|
omdev/cexts/magic.py
ADDED
omdev/{exts → cexts}/scan.py
RENAMED
|
@@ -5,18 +5,17 @@ import typing as ta
|
|
|
5
5
|
|
|
6
6
|
from omlish import logs
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
log = logging.getLogger(__name__)
|
|
8
|
+
from .magic import CextMagic
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
log = logging.getLogger(__name__)
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
def scan_one(
|
|
16
15
|
input_path: str,
|
|
17
16
|
**kwargs: ta.Any,
|
|
18
17
|
) -> None:
|
|
19
|
-
if not any(input_path.endswith(fx) for fx in
|
|
18
|
+
if not any(input_path.endswith('.' + fx) for fx in CextMagic.FILE_EXTENSIONS):
|
|
20
19
|
return
|
|
21
20
|
|
|
22
21
|
with open(input_path, 'rb') as f:
|
|
@@ -27,9 +26,9 @@ def scan_one(
|
|
|
27
26
|
except UnicodeDecodeError:
|
|
28
27
|
return
|
|
29
28
|
|
|
30
|
-
sls = [l for l in src.splitlines() if l.startswith(
|
|
29
|
+
sls = [l for l in src.splitlines() if l.startswith(CextMagic.MAGIC_COMMENT)]
|
|
31
30
|
for sl in sls:
|
|
32
|
-
sas = sl[len(
|
|
31
|
+
sas = sl[len(CextMagic.MAGIC_COMMENT):].split() # noqa
|
|
33
32
|
|
|
34
33
|
log.info('Found ext: %s', input_path)
|
|
35
34
|
|
omdev/pyproject/cli.py
CHANGED
|
@@ -301,10 +301,10 @@ def _pkg_cmd(args) -> None:
|
|
|
301
301
|
raise Exception('must specify command')
|
|
302
302
|
|
|
303
303
|
elif cmd == 'gen':
|
|
304
|
-
|
|
304
|
+
pkgs_root = os.path.join('.pkg')
|
|
305
305
|
|
|
306
|
-
if os.path.exists(
|
|
307
|
-
shutil.rmtree(
|
|
306
|
+
if os.path.exists(pkgs_root):
|
|
307
|
+
shutil.rmtree(pkgs_root)
|
|
308
308
|
|
|
309
309
|
build_output_dir = 'dist'
|
|
310
310
|
run_build = bool(args.build)
|
|
@@ -319,11 +319,13 @@ def _pkg_cmd(args) -> None:
|
|
|
319
319
|
ex.submit(functools.partial(
|
|
320
320
|
PyprojectPackageGenerator(
|
|
321
321
|
dir_name,
|
|
322
|
-
|
|
322
|
+
pkgs_root,
|
|
323
323
|
).gen,
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
324
|
+
PyprojectPackageGenerator.GenOpts(
|
|
325
|
+
run_build=run_build,
|
|
326
|
+
build_output_dir=build_output_dir,
|
|
327
|
+
add_revision=add_revision,
|
|
328
|
+
),
|
|
327
329
|
))
|
|
328
330
|
for dir_name in run.cfg().pkgs
|
|
329
331
|
]
|
omdev/pyproject/pkg.py
CHANGED
|
@@ -17,6 +17,7 @@ vcs+protocol://repo_url/#egg=pkg&subdirectory=pkg_dir
|
|
|
17
17
|
'git+https://github.com/wrmsr/omlish@master#subdirectory=.pip/omlish'
|
|
18
18
|
"""
|
|
19
19
|
# ruff: noqa: UP006 UP007
|
|
20
|
+
import abc
|
|
20
21
|
import dataclasses as dc
|
|
21
22
|
import importlib
|
|
22
23
|
import os.path
|
|
@@ -29,19 +30,27 @@ import typing as ta
|
|
|
29
30
|
from omlish.lite.cached import cached_nullary
|
|
30
31
|
from omlish.lite.logs import log
|
|
31
32
|
|
|
33
|
+
from ..cexts.magic import CextMagic
|
|
34
|
+
from ..findmagic import find_magic
|
|
32
35
|
from ..toml.writer import TomlWriter
|
|
33
36
|
from ..tools.revisions import GitRevisionAdder
|
|
34
37
|
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
#
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class BasePyprojectPackageGenerator(abc.ABC):
|
|
37
43
|
def __init__(
|
|
38
44
|
self,
|
|
39
45
|
dir_name: str,
|
|
40
|
-
|
|
46
|
+
pkgs_root: str,
|
|
47
|
+
*,
|
|
48
|
+
pkg_suffix: str = '',
|
|
41
49
|
) -> None:
|
|
42
50
|
super().__init__()
|
|
43
51
|
self._dir_name = dir_name
|
|
44
|
-
self.
|
|
52
|
+
self._pkgs_root = pkgs_root
|
|
53
|
+
self._pkg_suffix = pkg_suffix
|
|
45
54
|
|
|
46
55
|
#
|
|
47
56
|
|
|
@@ -49,48 +58,44 @@ class PyprojectPackageGenerator:
|
|
|
49
58
|
def about(self) -> types.ModuleType:
|
|
50
59
|
return importlib.import_module(f'{self._dir_name}.__about__')
|
|
51
60
|
|
|
52
|
-
@cached_nullary
|
|
53
|
-
def project_cls(self) -> type:
|
|
54
|
-
return self.about().Project
|
|
55
|
-
|
|
56
|
-
@cached_nullary
|
|
57
|
-
def setuptools_cls(self) -> type:
|
|
58
|
-
return self.about().Setuptools
|
|
59
|
-
|
|
60
61
|
#
|
|
61
62
|
|
|
62
63
|
@cached_nullary
|
|
63
|
-
def
|
|
64
|
-
|
|
65
|
-
if os.path.isdir(
|
|
66
|
-
shutil.rmtree(
|
|
67
|
-
os.makedirs(
|
|
68
|
-
return
|
|
64
|
+
def _pkg_dir(self) -> str:
|
|
65
|
+
pkg_dir: str = os.path.join(self._pkgs_root, self._dir_name + self._pkg_suffix)
|
|
66
|
+
if os.path.isdir(pkg_dir):
|
|
67
|
+
shutil.rmtree(pkg_dir)
|
|
68
|
+
os.makedirs(pkg_dir)
|
|
69
|
+
return pkg_dir
|
|
69
70
|
|
|
70
71
|
#
|
|
71
72
|
|
|
73
|
+
_GIT_IGNORE: ta.Sequence[str] = [
|
|
74
|
+
'/*.egg-info/',
|
|
75
|
+
'/dist',
|
|
76
|
+
]
|
|
77
|
+
|
|
72
78
|
def _write_git_ignore(self) -> None:
|
|
73
|
-
|
|
74
|
-
'
|
|
75
|
-
'/dist',
|
|
76
|
-
]
|
|
77
|
-
with open(os.path.join(self._build_dir(), '.gitignore'), 'w') as f:
|
|
78
|
-
f.write('\n'.join(git_ignore))
|
|
79
|
+
with open(os.path.join(self._pkg_dir(), '.gitignore'), 'w') as f:
|
|
80
|
+
f.write('\n'.join(self._GIT_IGNORE))
|
|
79
81
|
|
|
80
82
|
#
|
|
81
83
|
|
|
82
84
|
def _symlink_source_dir(self) -> None:
|
|
83
85
|
os.symlink(
|
|
84
|
-
os.path.relpath(self._dir_name, self.
|
|
85
|
-
os.path.join(self.
|
|
86
|
+
os.path.relpath(self._dir_name, self._pkg_dir()),
|
|
87
|
+
os.path.join(self._pkg_dir(), self._dir_name),
|
|
86
88
|
)
|
|
87
89
|
|
|
88
90
|
#
|
|
89
91
|
|
|
90
|
-
@
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
@cached_nullary
|
|
93
|
+
def project_cls(self) -> type:
|
|
94
|
+
return self.about().Project
|
|
95
|
+
|
|
96
|
+
@cached_nullary
|
|
97
|
+
def setuptools_cls(self) -> type:
|
|
98
|
+
return self.about().Setuptools
|
|
94
99
|
|
|
95
100
|
@staticmethod
|
|
96
101
|
def _build_cls_dct(cls: type) -> ta.Dict[str, ta.Any]: # noqa
|
|
@@ -112,18 +117,115 @@ class PyprojectPackageGenerator:
|
|
|
112
117
|
if sk in sd:
|
|
113
118
|
dd[dk] = sd.pop(sk)
|
|
114
119
|
|
|
120
|
+
@dc.dataclass(frozen=True)
|
|
121
|
+
class Specs:
|
|
122
|
+
pyproject: ta.Dict[str, ta.Any]
|
|
123
|
+
setuptools: ta.Dict[str, ta.Any]
|
|
124
|
+
|
|
125
|
+
def build_specs(self) -> Specs:
|
|
126
|
+
return self.Specs(
|
|
127
|
+
self._build_cls_dct(self.project_cls()),
|
|
128
|
+
self._build_cls_dct(self.setuptools_cls()),
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
#
|
|
132
|
+
|
|
133
|
+
@abc.abstractmethod
|
|
134
|
+
def _write_file_contents(self) -> None:
|
|
135
|
+
raise NotImplementedError
|
|
136
|
+
|
|
137
|
+
#
|
|
138
|
+
|
|
139
|
+
_STANDARD_FILES: ta.Sequence[str] = [
|
|
140
|
+
'LICENSE',
|
|
141
|
+
'README.rst',
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
def _symlink_standard_files(self) -> None:
|
|
145
|
+
for fn in self._STANDARD_FILES:
|
|
146
|
+
if os.path.exists(fn):
|
|
147
|
+
os.symlink(os.path.relpath(fn, self._pkg_dir()), os.path.join(self._pkg_dir(), fn))
|
|
148
|
+
|
|
149
|
+
#
|
|
150
|
+
|
|
151
|
+
def _run_build(
|
|
152
|
+
self,
|
|
153
|
+
build_output_dir: ta.Optional[str] = None,
|
|
154
|
+
*,
|
|
155
|
+
add_revision: bool = False,
|
|
156
|
+
) -> None:
|
|
157
|
+
subprocess.check_call(
|
|
158
|
+
[
|
|
159
|
+
sys.executable,
|
|
160
|
+
'-m',
|
|
161
|
+
'build',
|
|
162
|
+
],
|
|
163
|
+
cwd=self._pkg_dir(),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
dist_dir = os.path.join(self._pkg_dir(), 'dist')
|
|
167
|
+
|
|
168
|
+
if add_revision:
|
|
169
|
+
GitRevisionAdder().add_to(dist_dir)
|
|
170
|
+
|
|
171
|
+
if build_output_dir is not None:
|
|
172
|
+
for fn in os.listdir(dist_dir):
|
|
173
|
+
shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(build_output_dir, fn))
|
|
174
|
+
|
|
175
|
+
#
|
|
176
|
+
|
|
177
|
+
@dc.dataclass(frozen=True)
|
|
178
|
+
class GenOpts:
|
|
179
|
+
run_build: bool = False
|
|
180
|
+
build_output_dir: ta.Optional[str] = None
|
|
181
|
+
add_revision: bool = False
|
|
182
|
+
|
|
183
|
+
def gen(self, opts: GenOpts = GenOpts()) -> str:
|
|
184
|
+
log.info('Generating pyproject package: %s -> %s (%s)', self._dir_name, self._pkgs_root, self._pkg_suffix)
|
|
185
|
+
|
|
186
|
+
self._pkg_dir()
|
|
187
|
+
self._write_git_ignore()
|
|
188
|
+
self._symlink_source_dir()
|
|
189
|
+
self._write_file_contents()
|
|
190
|
+
self._symlink_standard_files()
|
|
191
|
+
|
|
192
|
+
if opts.run_build:
|
|
193
|
+
self._run_build(
|
|
194
|
+
opts.build_output_dir,
|
|
195
|
+
add_revision=opts.add_revision,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
return self._pkg_dir()
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
#
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
205
|
+
|
|
206
|
+
#
|
|
207
|
+
|
|
208
|
+
@dc.dataclass(frozen=True)
|
|
209
|
+
class FileContents:
|
|
210
|
+
pyproject_dct: ta.Mapping[str, ta.Any]
|
|
211
|
+
manifest_in: ta.Optional[ta.Sequence[str]]
|
|
212
|
+
|
|
115
213
|
@cached_nullary
|
|
116
214
|
def file_contents(self) -> FileContents:
|
|
117
|
-
|
|
215
|
+
specs = self.build_specs()
|
|
118
216
|
|
|
119
217
|
#
|
|
120
218
|
|
|
219
|
+
pyp_dct = {}
|
|
220
|
+
|
|
121
221
|
pyp_dct['build-system'] = {
|
|
122
222
|
'requires': ['setuptools'],
|
|
123
223
|
'build-backend': 'setuptools.build_meta',
|
|
124
224
|
}
|
|
125
225
|
|
|
126
|
-
prj =
|
|
226
|
+
prj = specs.pyproject
|
|
227
|
+
prj['name'] += self._pkg_suffix
|
|
228
|
+
|
|
127
229
|
pyp_dct['project'] = prj
|
|
128
230
|
|
|
129
231
|
self._move_dict_key(prj, 'optional_dependencies', pyp_dct, extrask := 'project.optional-dependencies')
|
|
@@ -139,9 +241,11 @@ class PyprojectPackageGenerator:
|
|
|
139
241
|
|
|
140
242
|
#
|
|
141
243
|
|
|
142
|
-
st =
|
|
244
|
+
st = specs.setuptools
|
|
143
245
|
pyp_dct['tool.setuptools'] = st
|
|
144
246
|
|
|
247
|
+
st.pop('cexts', None)
|
|
248
|
+
|
|
145
249
|
self._move_dict_key(st, 'find_packages', pyp_dct, 'tool.setuptools.packages.find')
|
|
146
250
|
|
|
147
251
|
mani_in = st.pop('manifest_in', None)
|
|
@@ -156,72 +260,121 @@ class PyprojectPackageGenerator:
|
|
|
156
260
|
def _write_file_contents(self) -> None:
|
|
157
261
|
fc = self.file_contents()
|
|
158
262
|
|
|
159
|
-
with open(os.path.join(self.
|
|
263
|
+
with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
|
|
160
264
|
TomlWriter(f).write_root(fc.pyproject_dct)
|
|
161
265
|
|
|
162
266
|
if fc.manifest_in:
|
|
163
|
-
with open(os.path.join(self.
|
|
267
|
+
with open(os.path.join(self._pkg_dir(), 'MANIFEST.in'), 'w') as f:
|
|
164
268
|
f.write('\n'.join(fc.manifest_in)) # noqa
|
|
165
269
|
|
|
166
270
|
#
|
|
167
271
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
'README.rst',
|
|
171
|
-
]
|
|
272
|
+
def gen(self, opts: BasePyprojectPackageGenerator.GenOpts = BasePyprojectPackageGenerator.GenOpts()) -> str:
|
|
273
|
+
ret = super().gen(opts)
|
|
172
274
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
275
|
+
if self.build_specs().setuptools.get('cexts'):
|
|
276
|
+
_PyprojectCextPackageGenerator(
|
|
277
|
+
self._dir_name,
|
|
278
|
+
self._pkgs_root,
|
|
279
|
+
pkg_suffix='-cext',
|
|
280
|
+
).gen(opts)
|
|
177
281
|
|
|
178
|
-
|
|
282
|
+
return ret
|
|
179
283
|
|
|
180
|
-
def _run_build(
|
|
181
|
-
self,
|
|
182
|
-
build_output_dir: ta.Optional[str] = None,
|
|
183
|
-
*,
|
|
184
|
-
add_revision: bool = False,
|
|
185
|
-
) -> None:
|
|
186
|
-
subprocess.check_call(
|
|
187
|
-
[
|
|
188
|
-
sys.executable,
|
|
189
|
-
'-m',
|
|
190
|
-
'build',
|
|
191
|
-
],
|
|
192
|
-
cwd=self._build_dir(),
|
|
193
|
-
)
|
|
194
284
|
|
|
195
|
-
|
|
285
|
+
#
|
|
196
286
|
|
|
197
|
-
if add_revision:
|
|
198
|
-
GitRevisionAdder().add_to(dist_dir)
|
|
199
287
|
|
|
200
|
-
|
|
201
|
-
for fn in os.listdir(dist_dir):
|
|
202
|
-
shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(build_output_dir, fn))
|
|
288
|
+
class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
203
289
|
|
|
204
290
|
#
|
|
205
291
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
log.info('Generating pyproject package: %s -> %s', self._dir_name, self._build_root)
|
|
292
|
+
@cached_nullary
|
|
293
|
+
def find_cext_srcs(self) -> ta.Sequence[str]:
|
|
294
|
+
return sorted(find_magic(
|
|
295
|
+
[self._dir_name],
|
|
296
|
+
[CextMagic.MAGIC_COMMENT],
|
|
297
|
+
CextMagic.FILE_EXTENSIONS,
|
|
298
|
+
))
|
|
214
299
|
|
|
215
|
-
|
|
216
|
-
self._write_git_ignore()
|
|
217
|
-
self._symlink_source_dir()
|
|
218
|
-
self._write_file_contents()
|
|
219
|
-
self._symlink_standard_files()
|
|
300
|
+
#
|
|
220
301
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
302
|
+
@dc.dataclass(frozen=True)
|
|
303
|
+
class FileContents:
|
|
304
|
+
pyproject_dct: ta.Mapping[str, ta.Any]
|
|
305
|
+
setup_py: str
|
|
306
|
+
|
|
307
|
+
@cached_nullary
|
|
308
|
+
def file_contents(self) -> FileContents:
|
|
309
|
+
specs = self.build_specs()
|
|
310
|
+
|
|
311
|
+
#
|
|
312
|
+
|
|
313
|
+
pyp_dct = {}
|
|
314
|
+
|
|
315
|
+
pyp_dct['build-system'] = {
|
|
316
|
+
'requires': ['setuptools'],
|
|
317
|
+
'build-backend': 'setuptools.build_meta',
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
prj = specs.pyproject
|
|
321
|
+
prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
|
|
322
|
+
prj['name'] += self._pkg_suffix
|
|
323
|
+
prj.pop('optional_dependencies', None)
|
|
324
|
+
|
|
325
|
+
pyp_dct['project'] = prj
|
|
326
|
+
|
|
327
|
+
#
|
|
328
|
+
|
|
329
|
+
st = specs.setuptools
|
|
330
|
+
pyp_dct['tool.setuptools'] = st
|
|
331
|
+
|
|
332
|
+
st.pop('cexts', None)
|
|
333
|
+
st.pop('find_packages', None)
|
|
334
|
+
st.pop('manifest_in', None)
|
|
335
|
+
|
|
336
|
+
pyp_dct['tool.setuptools.packages.find'] = {
|
|
337
|
+
'include': [],
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
#
|
|
341
|
+
|
|
342
|
+
ext_lines = []
|
|
343
|
+
|
|
344
|
+
for ext_src in self.find_cext_srcs():
|
|
345
|
+
ext_name = ext_src.rpartition('.')[0].replace(os.sep, '.')
|
|
346
|
+
ext_lines.extend([
|
|
347
|
+
'st.Extension(',
|
|
348
|
+
f" name='{ext_name}',",
|
|
349
|
+
f" sources=['{ext_src}'],",
|
|
350
|
+
" extra_compile_args=['-std=c++20'],",
|
|
351
|
+
'),',
|
|
352
|
+
])
|
|
353
|
+
|
|
354
|
+
src = '\n'.join([
|
|
355
|
+
'import setuptools as st',
|
|
356
|
+
'',
|
|
357
|
+
'',
|
|
358
|
+
'st.setup(',
|
|
359
|
+
' ext_modules=[',
|
|
360
|
+
*[' ' + l for l in ext_lines],
|
|
361
|
+
' ]',
|
|
362
|
+
')',
|
|
363
|
+
'',
|
|
364
|
+
])
|
|
365
|
+
|
|
366
|
+
#
|
|
367
|
+
|
|
368
|
+
return self.FileContents(
|
|
369
|
+
pyp_dct,
|
|
370
|
+
src,
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
def _write_file_contents(self) -> None:
|
|
374
|
+
fc = self.file_contents()
|
|
375
|
+
|
|
376
|
+
with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
|
|
377
|
+
TomlWriter(f).write_root(fc.pyproject_dct)
|
|
226
378
|
|
|
227
|
-
|
|
379
|
+
with open(os.path.join(self._pkg_dir(), 'setup.py'), 'w') as f:
|
|
380
|
+
f.write(fc.setup_py)
|
omdev/scripts/pyproject.py
CHANGED
|
@@ -86,6 +86,71 @@ UnparsedVersionVar = ta.TypeVar('UnparsedVersionVar', bound=UnparsedVersion)
|
|
|
86
86
|
CallableVersionOperator = ta.Callable[['Version', str], bool]
|
|
87
87
|
|
|
88
88
|
|
|
89
|
+
########################################
|
|
90
|
+
# ../../cexts/magic.py
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class CextMagic:
|
|
94
|
+
MAGIC = '@omdev-cext'
|
|
95
|
+
MAGIC_COMMENT = f'// {MAGIC}'
|
|
96
|
+
|
|
97
|
+
FILE_EXTENSIONS = ('c', 'cc', 'cpp')
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
########################################
|
|
101
|
+
# ../../findmagic.py
|
|
102
|
+
# @omlish-script
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def compile_magic_pat(m: str) -> re.Pattern:
|
|
106
|
+
return re.compile('^' + re.escape(m) + r'($|(\s.*))')
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def find_magic(
|
|
110
|
+
roots: ta.Sequence[str],
|
|
111
|
+
magics: ta.Sequence[str],
|
|
112
|
+
exts: ta.Sequence[str],
|
|
113
|
+
*,
|
|
114
|
+
py: bool = False,
|
|
115
|
+
) -> ta.Iterator[str]:
|
|
116
|
+
if not magics:
|
|
117
|
+
raise Exception('Must specify magics')
|
|
118
|
+
if not exts:
|
|
119
|
+
raise Exception('Must specify extensions')
|
|
120
|
+
|
|
121
|
+
pats = [compile_magic_pat(m) for m in magics]
|
|
122
|
+
|
|
123
|
+
for root in roots:
|
|
124
|
+
for dp, dns, fns in os.walk(root): # noqa
|
|
125
|
+
for fn in fns:
|
|
126
|
+
if not any(fn.endswith(f'.{x}') for x in exts):
|
|
127
|
+
continue
|
|
128
|
+
|
|
129
|
+
fp = os.path.join(dp, fn)
|
|
130
|
+
try:
|
|
131
|
+
with open(fp) as f:
|
|
132
|
+
src = f.read()
|
|
133
|
+
except UnicodeDecodeError:
|
|
134
|
+
continue
|
|
135
|
+
|
|
136
|
+
if not any(
|
|
137
|
+
any(pat.fullmatch(l) for pat in pats)
|
|
138
|
+
for l in src.splitlines()
|
|
139
|
+
):
|
|
140
|
+
continue
|
|
141
|
+
|
|
142
|
+
if py:
|
|
143
|
+
if fn == '__init__.py':
|
|
144
|
+
out = dp.replace(os.sep, '.')
|
|
145
|
+
elif fn.endswith('.py'):
|
|
146
|
+
out = fp[:-3].replace(os.sep, '.')
|
|
147
|
+
else:
|
|
148
|
+
out = fp
|
|
149
|
+
else:
|
|
150
|
+
out = fp
|
|
151
|
+
yield out
|
|
152
|
+
|
|
153
|
+
|
|
89
154
|
########################################
|
|
90
155
|
# ../../toml/parser.py
|
|
91
156
|
# SPDX-License-Identifier: MIT
|
|
@@ -1003,7 +1068,10 @@ class TomlWriter:
|
|
|
1003
1068
|
elif isinstance(obj, ta.Mapping):
|
|
1004
1069
|
self.write_inline_table(obj)
|
|
1005
1070
|
elif isinstance(obj, ta.Sequence):
|
|
1006
|
-
|
|
1071
|
+
if not obj:
|
|
1072
|
+
self.write_inline_array(obj)
|
|
1073
|
+
else:
|
|
1074
|
+
self.write_array(obj)
|
|
1007
1075
|
else:
|
|
1008
1076
|
raise TypeError(obj)
|
|
1009
1077
|
|
|
@@ -3335,15 +3403,21 @@ vcs+protocol://repo_url/#egg=pkg&subdirectory=pkg_dir
|
|
|
3335
3403
|
# ruff: noqa: UP006 UP007
|
|
3336
3404
|
|
|
3337
3405
|
|
|
3338
|
-
|
|
3406
|
+
#
|
|
3407
|
+
|
|
3408
|
+
|
|
3409
|
+
class BasePyprojectPackageGenerator(abc.ABC):
|
|
3339
3410
|
def __init__(
|
|
3340
3411
|
self,
|
|
3341
3412
|
dir_name: str,
|
|
3342
|
-
|
|
3413
|
+
pkgs_root: str,
|
|
3414
|
+
*,
|
|
3415
|
+
pkg_suffix: str = '',
|
|
3343
3416
|
) -> None:
|
|
3344
3417
|
super().__init__()
|
|
3345
3418
|
self._dir_name = dir_name
|
|
3346
|
-
self.
|
|
3419
|
+
self._pkgs_root = pkgs_root
|
|
3420
|
+
self._pkg_suffix = pkg_suffix
|
|
3347
3421
|
|
|
3348
3422
|
#
|
|
3349
3423
|
|
|
@@ -3351,48 +3425,44 @@ class PyprojectPackageGenerator:
|
|
|
3351
3425
|
def about(self) -> types.ModuleType:
|
|
3352
3426
|
return importlib.import_module(f'{self._dir_name}.__about__')
|
|
3353
3427
|
|
|
3354
|
-
@cached_nullary
|
|
3355
|
-
def project_cls(self) -> type:
|
|
3356
|
-
return self.about().Project
|
|
3357
|
-
|
|
3358
|
-
@cached_nullary
|
|
3359
|
-
def setuptools_cls(self) -> type:
|
|
3360
|
-
return self.about().Setuptools
|
|
3361
|
-
|
|
3362
3428
|
#
|
|
3363
3429
|
|
|
3364
3430
|
@cached_nullary
|
|
3365
|
-
def
|
|
3366
|
-
|
|
3367
|
-
if os.path.isdir(
|
|
3368
|
-
shutil.rmtree(
|
|
3369
|
-
os.makedirs(
|
|
3370
|
-
return
|
|
3431
|
+
def _pkg_dir(self) -> str:
|
|
3432
|
+
pkg_dir: str = os.path.join(self._pkgs_root, self._dir_name + self._pkg_suffix)
|
|
3433
|
+
if os.path.isdir(pkg_dir):
|
|
3434
|
+
shutil.rmtree(pkg_dir)
|
|
3435
|
+
os.makedirs(pkg_dir)
|
|
3436
|
+
return pkg_dir
|
|
3371
3437
|
|
|
3372
3438
|
#
|
|
3373
3439
|
|
|
3440
|
+
_GIT_IGNORE: ta.Sequence[str] = [
|
|
3441
|
+
'/*.egg-info/',
|
|
3442
|
+
'/dist',
|
|
3443
|
+
]
|
|
3444
|
+
|
|
3374
3445
|
def _write_git_ignore(self) -> None:
|
|
3375
|
-
|
|
3376
|
-
'
|
|
3377
|
-
'/dist',
|
|
3378
|
-
]
|
|
3379
|
-
with open(os.path.join(self._build_dir(), '.gitignore'), 'w') as f:
|
|
3380
|
-
f.write('\n'.join(git_ignore))
|
|
3446
|
+
with open(os.path.join(self._pkg_dir(), '.gitignore'), 'w') as f:
|
|
3447
|
+
f.write('\n'.join(self._GIT_IGNORE))
|
|
3381
3448
|
|
|
3382
3449
|
#
|
|
3383
3450
|
|
|
3384
3451
|
def _symlink_source_dir(self) -> None:
|
|
3385
3452
|
os.symlink(
|
|
3386
|
-
os.path.relpath(self._dir_name, self.
|
|
3387
|
-
os.path.join(self.
|
|
3453
|
+
os.path.relpath(self._dir_name, self._pkg_dir()),
|
|
3454
|
+
os.path.join(self._pkg_dir(), self._dir_name),
|
|
3388
3455
|
)
|
|
3389
3456
|
|
|
3390
3457
|
#
|
|
3391
3458
|
|
|
3392
|
-
@
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3459
|
+
@cached_nullary
|
|
3460
|
+
def project_cls(self) -> type:
|
|
3461
|
+
return self.about().Project
|
|
3462
|
+
|
|
3463
|
+
@cached_nullary
|
|
3464
|
+
def setuptools_cls(self) -> type:
|
|
3465
|
+
return self.about().Setuptools
|
|
3396
3466
|
|
|
3397
3467
|
@staticmethod
|
|
3398
3468
|
def _build_cls_dct(cls: type) -> ta.Dict[str, ta.Any]: # noqa
|
|
@@ -3414,18 +3484,115 @@ class PyprojectPackageGenerator:
|
|
|
3414
3484
|
if sk in sd:
|
|
3415
3485
|
dd[dk] = sd.pop(sk)
|
|
3416
3486
|
|
|
3487
|
+
@dc.dataclass(frozen=True)
|
|
3488
|
+
class Specs:
|
|
3489
|
+
pyproject: ta.Dict[str, ta.Any]
|
|
3490
|
+
setuptools: ta.Dict[str, ta.Any]
|
|
3491
|
+
|
|
3492
|
+
def build_specs(self) -> Specs:
|
|
3493
|
+
return self.Specs(
|
|
3494
|
+
self._build_cls_dct(self.project_cls()),
|
|
3495
|
+
self._build_cls_dct(self.setuptools_cls()),
|
|
3496
|
+
)
|
|
3497
|
+
|
|
3498
|
+
#
|
|
3499
|
+
|
|
3500
|
+
@abc.abstractmethod
|
|
3501
|
+
def _write_file_contents(self) -> None:
|
|
3502
|
+
raise NotImplementedError
|
|
3503
|
+
|
|
3504
|
+
#
|
|
3505
|
+
|
|
3506
|
+
_STANDARD_FILES: ta.Sequence[str] = [
|
|
3507
|
+
'LICENSE',
|
|
3508
|
+
'README.rst',
|
|
3509
|
+
]
|
|
3510
|
+
|
|
3511
|
+
def _symlink_standard_files(self) -> None:
|
|
3512
|
+
for fn in self._STANDARD_FILES:
|
|
3513
|
+
if os.path.exists(fn):
|
|
3514
|
+
os.symlink(os.path.relpath(fn, self._pkg_dir()), os.path.join(self._pkg_dir(), fn))
|
|
3515
|
+
|
|
3516
|
+
#
|
|
3517
|
+
|
|
3518
|
+
def _run_build(
|
|
3519
|
+
self,
|
|
3520
|
+
build_output_dir: ta.Optional[str] = None,
|
|
3521
|
+
*,
|
|
3522
|
+
add_revision: bool = False,
|
|
3523
|
+
) -> None:
|
|
3524
|
+
subprocess.check_call(
|
|
3525
|
+
[
|
|
3526
|
+
sys.executable,
|
|
3527
|
+
'-m',
|
|
3528
|
+
'build',
|
|
3529
|
+
],
|
|
3530
|
+
cwd=self._pkg_dir(),
|
|
3531
|
+
)
|
|
3532
|
+
|
|
3533
|
+
dist_dir = os.path.join(self._pkg_dir(), 'dist')
|
|
3534
|
+
|
|
3535
|
+
if add_revision:
|
|
3536
|
+
GitRevisionAdder().add_to(dist_dir)
|
|
3537
|
+
|
|
3538
|
+
if build_output_dir is not None:
|
|
3539
|
+
for fn in os.listdir(dist_dir):
|
|
3540
|
+
shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(build_output_dir, fn))
|
|
3541
|
+
|
|
3542
|
+
#
|
|
3543
|
+
|
|
3544
|
+
@dc.dataclass(frozen=True)
|
|
3545
|
+
class GenOpts:
|
|
3546
|
+
run_build: bool = False
|
|
3547
|
+
build_output_dir: ta.Optional[str] = None
|
|
3548
|
+
add_revision: bool = False
|
|
3549
|
+
|
|
3550
|
+
def gen(self, opts: GenOpts = GenOpts()) -> str:
|
|
3551
|
+
log.info('Generating pyproject package: %s -> %s (%s)', self._dir_name, self._pkgs_root, self._pkg_suffix)
|
|
3552
|
+
|
|
3553
|
+
self._pkg_dir()
|
|
3554
|
+
self._write_git_ignore()
|
|
3555
|
+
self._symlink_source_dir()
|
|
3556
|
+
self._write_file_contents()
|
|
3557
|
+
self._symlink_standard_files()
|
|
3558
|
+
|
|
3559
|
+
if opts.run_build:
|
|
3560
|
+
self._run_build(
|
|
3561
|
+
opts.build_output_dir,
|
|
3562
|
+
add_revision=opts.add_revision,
|
|
3563
|
+
)
|
|
3564
|
+
|
|
3565
|
+
return self._pkg_dir()
|
|
3566
|
+
|
|
3567
|
+
|
|
3568
|
+
#
|
|
3569
|
+
|
|
3570
|
+
|
|
3571
|
+
class PyprojectPackageGenerator(BasePyprojectPackageGenerator):
|
|
3572
|
+
|
|
3573
|
+
#
|
|
3574
|
+
|
|
3575
|
+
@dc.dataclass(frozen=True)
|
|
3576
|
+
class FileContents:
|
|
3577
|
+
pyproject_dct: ta.Mapping[str, ta.Any]
|
|
3578
|
+
manifest_in: ta.Optional[ta.Sequence[str]]
|
|
3579
|
+
|
|
3417
3580
|
@cached_nullary
|
|
3418
3581
|
def file_contents(self) -> FileContents:
|
|
3419
|
-
|
|
3582
|
+
specs = self.build_specs()
|
|
3420
3583
|
|
|
3421
3584
|
#
|
|
3422
3585
|
|
|
3586
|
+
pyp_dct = {}
|
|
3587
|
+
|
|
3423
3588
|
pyp_dct['build-system'] = {
|
|
3424
3589
|
'requires': ['setuptools'],
|
|
3425
3590
|
'build-backend': 'setuptools.build_meta',
|
|
3426
3591
|
}
|
|
3427
3592
|
|
|
3428
|
-
prj =
|
|
3593
|
+
prj = specs.pyproject
|
|
3594
|
+
prj['name'] += self._pkg_suffix
|
|
3595
|
+
|
|
3429
3596
|
pyp_dct['project'] = prj
|
|
3430
3597
|
|
|
3431
3598
|
self._move_dict_key(prj, 'optional_dependencies', pyp_dct, extrask := 'project.optional-dependencies')
|
|
@@ -3441,9 +3608,11 @@ class PyprojectPackageGenerator:
|
|
|
3441
3608
|
|
|
3442
3609
|
#
|
|
3443
3610
|
|
|
3444
|
-
st =
|
|
3611
|
+
st = specs.setuptools
|
|
3445
3612
|
pyp_dct['tool.setuptools'] = st
|
|
3446
3613
|
|
|
3614
|
+
st.pop('cexts', None)
|
|
3615
|
+
|
|
3447
3616
|
self._move_dict_key(st, 'find_packages', pyp_dct, 'tool.setuptools.packages.find')
|
|
3448
3617
|
|
|
3449
3618
|
mani_in = st.pop('manifest_in', None)
|
|
@@ -3458,75 +3627,124 @@ class PyprojectPackageGenerator:
|
|
|
3458
3627
|
def _write_file_contents(self) -> None:
|
|
3459
3628
|
fc = self.file_contents()
|
|
3460
3629
|
|
|
3461
|
-
with open(os.path.join(self.
|
|
3630
|
+
with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
|
|
3462
3631
|
TomlWriter(f).write_root(fc.pyproject_dct)
|
|
3463
3632
|
|
|
3464
3633
|
if fc.manifest_in:
|
|
3465
|
-
with open(os.path.join(self.
|
|
3634
|
+
with open(os.path.join(self._pkg_dir(), 'MANIFEST.in'), 'w') as f:
|
|
3466
3635
|
f.write('\n'.join(fc.manifest_in)) # noqa
|
|
3467
3636
|
|
|
3468
3637
|
#
|
|
3469
3638
|
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
'README.rst',
|
|
3473
|
-
]
|
|
3639
|
+
def gen(self, opts: BasePyprojectPackageGenerator.GenOpts = BasePyprojectPackageGenerator.GenOpts()) -> str:
|
|
3640
|
+
ret = super().gen(opts)
|
|
3474
3641
|
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3642
|
+
if self.build_specs().setuptools.get('cexts'):
|
|
3643
|
+
_PyprojectCextPackageGenerator(
|
|
3644
|
+
self._dir_name,
|
|
3645
|
+
self._pkgs_root,
|
|
3646
|
+
pkg_suffix='-cext',
|
|
3647
|
+
).gen(opts)
|
|
3479
3648
|
|
|
3480
|
-
|
|
3649
|
+
return ret
|
|
3481
3650
|
|
|
3482
|
-
def _run_build(
|
|
3483
|
-
self,
|
|
3484
|
-
build_output_dir: ta.Optional[str] = None,
|
|
3485
|
-
*,
|
|
3486
|
-
add_revision: bool = False,
|
|
3487
|
-
) -> None:
|
|
3488
|
-
subprocess.check_call(
|
|
3489
|
-
[
|
|
3490
|
-
sys.executable,
|
|
3491
|
-
'-m',
|
|
3492
|
-
'build',
|
|
3493
|
-
],
|
|
3494
|
-
cwd=self._build_dir(),
|
|
3495
|
-
)
|
|
3496
3651
|
|
|
3497
|
-
|
|
3652
|
+
#
|
|
3498
3653
|
|
|
3499
|
-
if add_revision:
|
|
3500
|
-
GitRevisionAdder().add_to(dist_dir)
|
|
3501
3654
|
|
|
3502
|
-
|
|
3503
|
-
for fn in os.listdir(dist_dir):
|
|
3504
|
-
shutil.copyfile(os.path.join(dist_dir, fn), os.path.join(build_output_dir, fn))
|
|
3655
|
+
class _PyprojectCextPackageGenerator(BasePyprojectPackageGenerator):
|
|
3505
3656
|
|
|
3506
3657
|
#
|
|
3507
3658
|
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
log.info('Generating pyproject package: %s -> %s', self._dir_name, self._build_root)
|
|
3659
|
+
@cached_nullary
|
|
3660
|
+
def find_cext_srcs(self) -> ta.Sequence[str]:
|
|
3661
|
+
return sorted(find_magic(
|
|
3662
|
+
[self._dir_name],
|
|
3663
|
+
[CextMagic.MAGIC_COMMENT],
|
|
3664
|
+
CextMagic.FILE_EXTENSIONS,
|
|
3665
|
+
))
|
|
3516
3666
|
|
|
3517
|
-
|
|
3518
|
-
self._write_git_ignore()
|
|
3519
|
-
self._symlink_source_dir()
|
|
3520
|
-
self._write_file_contents()
|
|
3521
|
-
self._symlink_standard_files()
|
|
3667
|
+
#
|
|
3522
3668
|
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3669
|
+
@dc.dataclass(frozen=True)
|
|
3670
|
+
class FileContents:
|
|
3671
|
+
pyproject_dct: ta.Mapping[str, ta.Any]
|
|
3672
|
+
setup_py: str
|
|
3673
|
+
|
|
3674
|
+
@cached_nullary
|
|
3675
|
+
def file_contents(self) -> FileContents:
|
|
3676
|
+
specs = self.build_specs()
|
|
3677
|
+
|
|
3678
|
+
#
|
|
3679
|
+
|
|
3680
|
+
pyp_dct = {}
|
|
3681
|
+
|
|
3682
|
+
pyp_dct['build-system'] = {
|
|
3683
|
+
'requires': ['setuptools'],
|
|
3684
|
+
'build-backend': 'setuptools.build_meta',
|
|
3685
|
+
}
|
|
3686
|
+
|
|
3687
|
+
prj = specs.pyproject
|
|
3688
|
+
prj['dependencies'] = [f'{prj["name"]} == {prj["version"]}']
|
|
3689
|
+
prj['name'] += self._pkg_suffix
|
|
3690
|
+
prj.pop('optional_dependencies', None)
|
|
3691
|
+
|
|
3692
|
+
pyp_dct['project'] = prj
|
|
3693
|
+
|
|
3694
|
+
#
|
|
3695
|
+
|
|
3696
|
+
st = specs.setuptools
|
|
3697
|
+
pyp_dct['tool.setuptools'] = st
|
|
3698
|
+
|
|
3699
|
+
st.pop('cexts', None)
|
|
3700
|
+
st.pop('find_packages', None)
|
|
3701
|
+
st.pop('manifest_in', None)
|
|
3702
|
+
|
|
3703
|
+
pyp_dct['tool.setuptools.packages.find'] = {
|
|
3704
|
+
'include': [],
|
|
3705
|
+
}
|
|
3706
|
+
|
|
3707
|
+
#
|
|
3708
|
+
|
|
3709
|
+
ext_lines = []
|
|
3710
|
+
|
|
3711
|
+
for ext_src in self.find_cext_srcs():
|
|
3712
|
+
ext_name = ext_src.rpartition('.')[0].replace(os.sep, '.')
|
|
3713
|
+
ext_lines.extend([
|
|
3714
|
+
'st.Extension(',
|
|
3715
|
+
f" name='{ext_name}',",
|
|
3716
|
+
f" sources=['{ext_src}'],",
|
|
3717
|
+
" extra_compile_args=['-std=c++20'],",
|
|
3718
|
+
'),',
|
|
3719
|
+
])
|
|
3720
|
+
|
|
3721
|
+
src = '\n'.join([
|
|
3722
|
+
'import setuptools as st',
|
|
3723
|
+
'',
|
|
3724
|
+
'',
|
|
3725
|
+
'st.setup(',
|
|
3726
|
+
' ext_modules=[',
|
|
3727
|
+
*[' ' + l for l in ext_lines],
|
|
3728
|
+
' ]',
|
|
3729
|
+
')',
|
|
3730
|
+
'',
|
|
3731
|
+
])
|
|
3732
|
+
|
|
3733
|
+
#
|
|
3734
|
+
|
|
3735
|
+
return self.FileContents(
|
|
3736
|
+
pyp_dct,
|
|
3737
|
+
src,
|
|
3738
|
+
)
|
|
3739
|
+
|
|
3740
|
+
def _write_file_contents(self) -> None:
|
|
3741
|
+
fc = self.file_contents()
|
|
3742
|
+
|
|
3743
|
+
with open(os.path.join(self._pkg_dir(), 'pyproject.toml'), 'w') as f:
|
|
3744
|
+
TomlWriter(f).write_root(fc.pyproject_dct)
|
|
3528
3745
|
|
|
3529
|
-
|
|
3746
|
+
with open(os.path.join(self._pkg_dir(), 'setup.py'), 'w') as f:
|
|
3747
|
+
f.write(fc.setup_py)
|
|
3530
3748
|
|
|
3531
3749
|
|
|
3532
3750
|
########################################
|
|
@@ -4363,10 +4581,10 @@ def _pkg_cmd(args) -> None:
|
|
|
4363
4581
|
raise Exception('must specify command')
|
|
4364
4582
|
|
|
4365
4583
|
elif cmd == 'gen':
|
|
4366
|
-
|
|
4584
|
+
pkgs_root = os.path.join('.pkg')
|
|
4367
4585
|
|
|
4368
|
-
if os.path.exists(
|
|
4369
|
-
shutil.rmtree(
|
|
4586
|
+
if os.path.exists(pkgs_root):
|
|
4587
|
+
shutil.rmtree(pkgs_root)
|
|
4370
4588
|
|
|
4371
4589
|
build_output_dir = 'dist'
|
|
4372
4590
|
run_build = bool(args.build)
|
|
@@ -4381,11 +4599,13 @@ def _pkg_cmd(args) -> None:
|
|
|
4381
4599
|
ex.submit(functools.partial(
|
|
4382
4600
|
PyprojectPackageGenerator(
|
|
4383
4601
|
dir_name,
|
|
4384
|
-
|
|
4602
|
+
pkgs_root,
|
|
4385
4603
|
).gen,
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4604
|
+
PyprojectPackageGenerator.GenOpts(
|
|
4605
|
+
run_build=run_build,
|
|
4606
|
+
build_output_dir=build_output_dir,
|
|
4607
|
+
add_revision=add_revision,
|
|
4608
|
+
),
|
|
4389
4609
|
))
|
|
4390
4610
|
for dir_name in run.cfg().pkgs
|
|
4391
4611
|
]
|
omdev/toml/writer.py
CHANGED
|
@@ -99,6 +99,9 @@ class TomlWriter:
|
|
|
99
99
|
elif isinstance(obj, ta.Mapping):
|
|
100
100
|
self.write_inline_table(obj)
|
|
101
101
|
elif isinstance(obj, ta.Sequence):
|
|
102
|
-
|
|
102
|
+
if not obj:
|
|
103
|
+
self.write_inline_array(obj)
|
|
104
|
+
else:
|
|
105
|
+
self.write_array(obj)
|
|
103
106
|
else:
|
|
104
107
|
raise TypeError(obj)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: omdev
|
|
3
|
-
Version: 0.0.0.
|
|
3
|
+
Version: 0.0.0.dev18
|
|
4
4
|
Summary: omdev
|
|
5
5
|
Author: wrmsr
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -12,7 +12,7 @@ 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.dev18
|
|
16
16
|
Provides-Extra: all
|
|
17
17
|
Requires-Dist: pycparser ~=2.22 ; extra == 'all'
|
|
18
18
|
Requires-Dist: cffi ~=1.17 ; extra == 'all'
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
omdev/__about__.py,sha256=
|
|
1
|
+
omdev/__about__.py,sha256=x1427IilNX73BS7VDiNwnCFDuzGfPVPoRvJze6stnsE,802
|
|
2
2
|
omdev/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
omdev/bracepy.py,sha256=HwBK5XmlOsF_juTel25fRLJK9vHSJCWXuCc-OZlevRQ,2619
|
|
4
4
|
omdev/classdot.py,sha256=urN5Pzd2ooAwnfkH0z-muQxdO90IMo-sX2WB-A37lVU,1533
|
|
@@ -10,26 +10,27 @@ omdev/wheelfile.py,sha256=yfupGcGkbFlmzGzKU64k_vmOKpaKnUlDWxeGn2KdekU,10005
|
|
|
10
10
|
omdev/amalg/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
omdev/amalg/__main__.py,sha256=OE1udULO1g4McUbeg1CoHbSm4hbQ2kcE3ffEGxlnPh4,69
|
|
12
12
|
omdev/amalg/amalg.py,sha256=YEyH097MZop-f1qobZJW__srtyLFS3rI7M2MaRtshKg,13057
|
|
13
|
-
omdev/
|
|
14
|
-
omdev/
|
|
15
|
-
omdev/
|
|
16
|
-
omdev/
|
|
17
|
-
omdev/
|
|
18
|
-
omdev/
|
|
19
|
-
omdev/
|
|
20
|
-
omdev/
|
|
21
|
-
omdev/
|
|
22
|
-
omdev/
|
|
23
|
-
omdev/
|
|
24
|
-
omdev/
|
|
25
|
-
omdev/
|
|
26
|
-
omdev/
|
|
27
|
-
omdev/
|
|
28
|
-
omdev/
|
|
29
|
-
omdev/
|
|
30
|
-
omdev/
|
|
31
|
-
omdev/
|
|
32
|
-
omdev/
|
|
13
|
+
omdev/cexts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
omdev/cexts/build.py,sha256=zViF1wYx6z5ACyifgNjlCAVoPAMCKpTr_VoAvwtmvtY,1013
|
|
15
|
+
omdev/cexts/cmake.py,sha256=WrH5l3WnamyVEcMMjxkX87bNT7O7ZWX-docajc7XwAg,9726
|
|
16
|
+
omdev/cexts/importhook.py,sha256=nljqEuPopuh10DPeSrIYKmkV4z-Wk5Q7WpUid1JEmkg,3530
|
|
17
|
+
omdev/cexts/magic.py,sha256=LhC31I2GiCq3NRU5dpy_9do6IVjhdGu58uPPFffQx5Q,135
|
|
18
|
+
omdev/cexts/scan.py,sha256=_U5DX9ksHP1845PdGxWh4Rf1a6x_sG1MH3uL_hwBnKY,1669
|
|
19
|
+
omdev/cexts/_distutils/__init__.py,sha256=c1zImtnPh3uY8BUTV4RLKtGKqTPx3c_pBbhA6tPtNsE,297
|
|
20
|
+
omdev/cexts/_distutils/build_ext.py,sha256=STHl9Rq2KeWJ3dQ8j8LwIQ-vFc4-3XsYWQ8Qc5_VByU,13833
|
|
21
|
+
omdev/cexts/_distutils/dir_util.py,sha256=xxfAIPHbjlh-aW9OX6UGDrXiXfB5biG4xEC5RA6oszM,2882
|
|
22
|
+
omdev/cexts/_distutils/errors.py,sha256=HWmsruDLOctJwjZ3yjIkef6O-NI2m0A74tLYZKbS-TY,2035
|
|
23
|
+
omdev/cexts/_distutils/extension.py,sha256=CAxie5k3eCD-k-OaBPYYsyOFbgcWgx0oipA2D6_hrIs,5631
|
|
24
|
+
omdev/cexts/_distutils/file_util.py,sha256=glpfHGEDZKMS_VAIgr3YlExtQfNP4agxOrn3WenjE7U,7804
|
|
25
|
+
omdev/cexts/_distutils/modified.py,sha256=OI4guORuIv16fyFTS-B_eaPSELttGPVeZCYgjR357Ec,1723
|
|
26
|
+
omdev/cexts/_distutils/spawn.py,sha256=ROud2VB_tyktPGq6ldsOyFTGIsvSvYAQf_ioWQh0XH0,3435
|
|
27
|
+
omdev/cexts/_distutils/sysconfig.py,sha256=NYfkHHcQRkgVfVhNEexd2DdYhJmZ1BIaT3BhPd7hk0c,12630
|
|
28
|
+
omdev/cexts/_distutils/util.py,sha256=k4t8w-8VWLVzFh5LvfSpygkssSfrU7LaMT6xIMQQkQw,6413
|
|
29
|
+
omdev/cexts/_distutils/version.py,sha256=LEjpZjn2HGFEJElZrklb2NSALhr9wWi1uXfVf_5WLRY,12509
|
|
30
|
+
omdev/cexts/_distutils/compilers/__init__.py,sha256=amL_zrFlba0lHIvpqDne9uhqhLemA7hBZFX-MHL7R3c,68
|
|
31
|
+
omdev/cexts/_distutils/compilers/ccompiler.py,sha256=cTs88qrvj0hBVXHfemSDE_du_nEA4_qo3Qst5TpQkVI,43606
|
|
32
|
+
omdev/cexts/_distutils/compilers/options.py,sha256=H7r5IcLvga5Fs3jjXWIT-6ap3JBduXRKgtpDmSGCZxs,3818
|
|
33
|
+
omdev/cexts/_distutils/compilers/unixccompiler.py,sha256=o1h8QuyupLntv4F21_XjzAZmCiwwxJuTmOirvBSL-Qw,15419
|
|
33
34
|
omdev/interp/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
34
35
|
omdev/interp/__main__.py,sha256=gFhR9DikwDZk0LqgdR3qq_aXQHThUOPllDmHDOfnFAU,67
|
|
35
36
|
omdev/interp/cli.py,sha256=pobok11AGS7UrlCcORyARiS03878rpSVTaFxfv5aaUE,1618
|
|
@@ -47,17 +48,17 @@ omdev/precheck/__main__.py,sha256=wKF_2KP2Yn1hKDEOCGR_fm5zu9UHMWCZtuEmWjpprrU,72
|
|
|
47
48
|
omdev/precheck/precheck.py,sha256=2yTjNGvjPYf3QxUBbCbehBYYuB8gDR_dYSTrlNCs9qU,8322
|
|
48
49
|
omdev/pyproject/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
49
50
|
omdev/pyproject/__main__.py,sha256=gFhR9DikwDZk0LqgdR3qq_aXQHThUOPllDmHDOfnFAU,67
|
|
50
|
-
omdev/pyproject/
|
|
51
|
+
omdev/pyproject/cexts.py,sha256=x13piOOnNrYbA17qZLDVuR0p1sqhgEwpk4FtImX-klM,4281
|
|
52
|
+
omdev/pyproject/cli.py,sha256=RnRj8zfGGUcLJ-oiQS90gR2O0XAH4iwNSX5JIDWzM4U,10004
|
|
51
53
|
omdev/pyproject/configs.py,sha256=MFHnmpMjlwxw74-SyX1Q1qNQ4ptwTXEzDGkeUcGY0mA,2822
|
|
52
|
-
omdev/pyproject/
|
|
53
|
-
omdev/pyproject/pkg.py,sha256=YrnqZK-b2qJh6kSkvYjZ19F39NU0kpbth1FYItpFZ80,5977
|
|
54
|
+
omdev/pyproject/pkg.py,sha256=dJ8KFx7aK9bMxWtSjVoAYqWwNCabz2MmtKFYB7BpFyw,9474
|
|
54
55
|
omdev/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
55
56
|
omdev/scripts/execrss.py,sha256=HzDNmwXOO8fMwIRXw9q8CUnVfLFCQASyU2tfY_y2Vf8,324
|
|
56
57
|
omdev/scripts/interp.py,sha256=Xuj509nGwClnR4MvnB8CJJQ7KhfjdGmzN9ul17-SXjI,63069
|
|
57
|
-
omdev/scripts/pyproject.py,sha256=
|
|
58
|
+
omdev/scripts/pyproject.py,sha256=yHgVqaESt3TdHClqeqOxKXe6jTwe64LGAskSsYSx4Ls,139345
|
|
58
59
|
omdev/toml/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
59
60
|
omdev/toml/parser.py,sha256=84bn09uhYHwQGyfww6Rw6y1RxPAE_HDltODOSakcqDM,29186
|
|
60
|
-
omdev/toml/writer.py,sha256=
|
|
61
|
+
omdev/toml/writer.py,sha256=dwz_Qw8z5Z_nmWpXqch63W6S_j6n256erb7AGFTVzB4,2872
|
|
61
62
|
omdev/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
62
63
|
omdev/tools/dockertools.py,sha256=3844AhUst6kYo2xKNn-2Npi-f6r4rocxEOx0tHjE0dk,2063
|
|
63
64
|
omdev/tools/gittools.py,sha256=zPy2D5WDs-CbwT86_T_hbaq5yCuss5e-ouUccXC6xlg,578
|
|
@@ -67,8 +68,8 @@ omdev/tools/traceimport.py,sha256=oDry9CwIv5h96wSaTVKJ0qQ5vMGxYE5oBtfF-GYNLJs,13
|
|
|
67
68
|
omdev/versioning/__init__.py,sha256=Y3l4WY4JRi2uLG6kgbGp93fuGfkxkKwZDvhsa0Rwgtk,15
|
|
68
69
|
omdev/versioning/specifiers.py,sha256=6Odf9e6farwlPRsD_YqwTfYKG-BXn_dIcKtqfkhfodI,17432
|
|
69
70
|
omdev/versioning/versions.py,sha256=ei2eopEsJq3zSMJmezK1nzZgikgCdxFtnF3f69nCRZQ,12246
|
|
70
|
-
omdev-0.0.0.
|
|
71
|
-
omdev-0.0.0.
|
|
72
|
-
omdev-0.0.0.
|
|
73
|
-
omdev-0.0.0.
|
|
74
|
-
omdev-0.0.0.
|
|
71
|
+
omdev-0.0.0.dev18.dist-info/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
|
72
|
+
omdev-0.0.0.dev18.dist-info/METADATA,sha256=2ww7yF1h3owq29eE0vXnR8thV1ZedVaHJaTv9i3jXNk,1126
|
|
73
|
+
omdev-0.0.0.dev18.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
|
74
|
+
omdev-0.0.0.dev18.dist-info/top_level.txt,sha256=1nr7j30fEWgLYHW3lGR9pkdHkb7knv1U1ES1XRNVQ6k,6
|
|
75
|
+
omdev-0.0.0.dev18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/omdev/{exts → cexts}/build.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|