cmeel 0.45.0__py3-none-any.whl → 0.47.1__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.
Potentially problematic release.
This version of cmeel might be problematic. Click here for more details.
- cmeel/__init__.py +1 -4
- cmeel/__main__.py +11 -1
- cmeel/backports.py +1 -1
- cmeel/build.py +16 -342
- cmeel/consts.py +1 -1
- cmeel/impl.py +200 -0
- cmeel/metadata.py +19 -9
- cmeel/release.py +50 -0
- cmeel/sdist.py +36 -0
- cmeel/utils.py +193 -0
- {cmeel-0.45.0.dist-info → cmeel-0.47.1.dist-info}/METADATA +15 -8
- cmeel-0.47.1.dist-info/RECORD +21 -0
- cmeel-0.45.0.dist-info/RECORD +0 -17
- {cmeel-0.45.0.dist-info → cmeel-0.47.1.dist-info}/LICENSE +0 -0
- {cmeel-0.45.0.dist-info → cmeel-0.47.1.dist-info}/WHEEL +0 -0
- {cmeel-0.45.0.dist-info → cmeel-0.47.1.dist-info}/entry_points.txt +0 -0
cmeel/__init__.py
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
"""Cmeel module."""
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
from importlib.metadata import metadata
|
|
5
|
-
except ImportError: # Python < 3.8
|
|
6
|
-
from importlib_metadata import metadata # type: ignore
|
|
3
|
+
from importlib.metadata import metadata
|
|
7
4
|
|
|
8
5
|
__metadata__ = metadata("cmeel")
|
|
9
6
|
__project_name__ = __metadata__["name"]
|
cmeel/__main__.py
CHANGED
|
@@ -6,8 +6,10 @@ import os
|
|
|
6
6
|
import pathlib
|
|
7
7
|
import sys
|
|
8
8
|
|
|
9
|
+
from . import __version__
|
|
9
10
|
from .docker import add_docker_arguments, docker_build
|
|
10
11
|
from .env import add_paths_arguments, get_paths
|
|
12
|
+
from .release import add_release_arguments, release
|
|
11
13
|
|
|
12
14
|
LOG = logging.getLogger("cmeel")
|
|
13
15
|
|
|
@@ -39,6 +41,10 @@ def parse_args() -> argparse.Namespace:
|
|
|
39
41
|
|
|
40
42
|
add_paths_arguments(subparsers)
|
|
41
43
|
add_docker_arguments(subparsers)
|
|
44
|
+
add_release_arguments(subparsers)
|
|
45
|
+
|
|
46
|
+
ver = subparsers.add_parser("version", help="print current cmeel version.")
|
|
47
|
+
ver.set_defaults(cmd="version")
|
|
42
48
|
|
|
43
49
|
args = parser.parse_args()
|
|
44
50
|
|
|
@@ -48,7 +54,7 @@ def parse_args() -> argparse.Namespace:
|
|
|
48
54
|
level = 30 - 10 * args.verbose
|
|
49
55
|
logging.basicConfig(level=level)
|
|
50
56
|
|
|
51
|
-
LOG.debug("parsed arguments
|
|
57
|
+
LOG.debug("parsed arguments: %s", args)
|
|
52
58
|
|
|
53
59
|
if "cmd" in args:
|
|
54
60
|
LOG.debug("running subcommand %s", args.cmd)
|
|
@@ -63,6 +69,10 @@ def main():
|
|
|
63
69
|
args = parse_args()
|
|
64
70
|
if args.cmd == "docker":
|
|
65
71
|
docker_build(**vars(args))
|
|
72
|
+
elif args.cmd == "release":
|
|
73
|
+
release(**vars(args))
|
|
74
|
+
elif args.cmd == "version":
|
|
75
|
+
print(f"This is cmeel version {__version__}")
|
|
66
76
|
else:
|
|
67
77
|
print(get_paths(**vars(args)))
|
|
68
78
|
|
cmeel/backports.py
CHANGED
cmeel/build.py
CHANGED
|
@@ -1,357 +1,31 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""PEP 517 & 660 entry points."""
|
|
2
2
|
|
|
3
|
-
Functions to generate package archives.
|
|
4
|
-
"""
|
|
5
3
|
import logging
|
|
6
4
|
import os
|
|
7
|
-
import re
|
|
8
|
-
import sys
|
|
9
|
-
import warnings
|
|
10
|
-
from importlib.util import find_spec
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
from subprocess import CalledProcessError, check_call, check_output, run
|
|
13
5
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
except ImportError as e:
|
|
17
|
-
err = "You need the 'build' extra option to use this build module.\n"
|
|
18
|
-
err += "For this you can install the 'cmeel[build]' package."
|
|
19
|
-
raise ImportError(err) from e
|
|
20
|
-
try:
|
|
21
|
-
import tomllib # type: ignore
|
|
22
|
-
except ModuleNotFoundError:
|
|
23
|
-
import tomli as tomllib # type: ignore
|
|
24
|
-
|
|
25
|
-
from . import __version__
|
|
26
|
-
from .config import cmeel_config
|
|
27
|
-
from .consts import CMEEL_PREFIX, SITELIB
|
|
28
|
-
from .metadata import (
|
|
29
|
-
get_deps,
|
|
30
|
-
get_keywords,
|
|
31
|
-
get_license,
|
|
32
|
-
get_people,
|
|
33
|
-
get_readme,
|
|
34
|
-
get_urls,
|
|
35
|
-
normalize,
|
|
36
|
-
)
|
|
6
|
+
from .impl import build_impl
|
|
7
|
+
from .sdist import sdist_impl
|
|
37
8
|
|
|
38
9
|
LOG = logging.getLogger("cmeel")
|
|
39
|
-
EXECUTABLE = """#!python
|
|
40
|
-
from cmeel.run import cmeel_run
|
|
41
|
-
cmeel_run()
|
|
42
|
-
"""
|
|
43
|
-
PATCH_IGNORE = [
|
|
44
|
-
"hunk ignored",
|
|
45
|
-
"hunks ignored",
|
|
46
|
-
"Skipping patch.",
|
|
47
|
-
"The next patch would delete",
|
|
48
|
-
]
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class NonRelocatableError(Exception):
|
|
52
|
-
"""Exception raised when absolute paths are in the final package."""
|
|
53
|
-
|
|
54
|
-
pass
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class PatchError(CalledProcessError):
|
|
58
|
-
"""Exception raised when patch operation failed."""
|
|
59
|
-
|
|
60
|
-
def __str__(self):
|
|
61
|
-
"""Render this error as a string."""
|
|
62
|
-
if self.returncode and self.returncode < 0:
|
|
63
|
-
return super().__str__()
|
|
64
|
-
return (
|
|
65
|
-
f"Command '{self.cmd}' exit status {self.returncode}\n"
|
|
66
|
-
f"with output:\n{self.output}\n"
|
|
67
|
-
f"and stderr:\n{self.stderr}\n"
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def deprecate_build_system(pyproject, key, default):
|
|
72
|
-
"""Cmeel up to v0.22 was using the "build-system" section of pyproject.toml.
|
|
73
10
|
|
|
74
|
-
This function helps to deprecate that and move to "tool.cmeel".
|
|
75
|
-
"""
|
|
76
|
-
if key in pyproject["build-system"]:
|
|
77
|
-
default = pyproject["build-system"][key]
|
|
78
|
-
warnings.warn(
|
|
79
|
-
'Using the "build-system" section of pyproject.toml for cmeel '
|
|
80
|
-
"configuration is deprecated since cmeel v0.23 and will be removed in v1.\n"
|
|
81
|
-
f'Please move your "{key} = {default}" to the "tool.cmeel" section.',
|
|
82
|
-
DeprecationWarning,
|
|
83
|
-
stacklevel=2,
|
|
84
|
-
)
|
|
85
|
-
if "tool" in pyproject and "cmeel" in pyproject["tool"]:
|
|
86
|
-
return pyproject["tool"]["cmeel"].get(key, default)
|
|
87
|
-
return default
|
|
88
11
|
|
|
89
|
-
|
|
90
|
-
|
|
12
|
+
def build_editable(
|
|
13
|
+
wheel_directory,
|
|
14
|
+
config_settings=None,
|
|
15
|
+
metadata_directory=None,
|
|
16
|
+
) -> str:
|
|
91
17
|
"""Build an editable wheel: main entry point for PEP 660."""
|
|
18
|
+
LOG.info("cmeel build editable")
|
|
92
19
|
os.environ["CMAKE_INSTALL_MODE"] = "ABS_SYMLINK"
|
|
93
|
-
return
|
|
20
|
+
return build_impl(wheel_directory, editable=True)
|
|
94
21
|
|
|
95
22
|
|
|
96
|
-
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
|
|
23
|
+
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None) -> str:
|
|
97
24
|
"""Build a binary wheel: main entry point for PEP 517."""
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
def build(wheel_directory, editable=False): # noqa: C901 TODO
|
|
102
|
-
"""Run CMake configure / build / test / install steps, and pack the wheel."""
|
|
103
|
-
logging.basicConfig(level=cmeel_config.log_level.upper())
|
|
104
|
-
LOG.info("CMake Wheel in editable mode" if editable else "CMake Wheel")
|
|
105
|
-
LOG.info("cmeel version %s" % __version__)
|
|
106
|
-
if LOG.getEffectiveLevel() <= logging.DEBUG:
|
|
107
|
-
if find_spec("pip") is not None:
|
|
108
|
-
LOG.debug("pip freeze:")
|
|
109
|
-
deps = check_output([sys.executable, "-m", "pip", "freeze"], text=True)
|
|
110
|
-
for dep in deps.strip().split("\n"):
|
|
111
|
-
LOG.debug(" %s", dep)
|
|
112
|
-
|
|
113
|
-
prefix = Path(".") / "build-editable" if editable else cmeel_config.temp_dir
|
|
114
|
-
build = prefix / "bld"
|
|
115
|
-
wheel_dir = prefix / "whl"
|
|
116
|
-
install = (prefix if editable else wheel_dir) / CMEEL_PREFIX
|
|
117
|
-
tag = str(next(sys_tags()))
|
|
118
|
-
# handle cross compilation on macOS with cibuildwheel
|
|
119
|
-
# ref. https://github.com/pypa/cibuildwheel/blob/6549a9/cibuildwheel/macos.py#L221
|
|
120
|
-
if "_PYTHON_HOST_PLATFORM" in os.environ:
|
|
121
|
-
plat = os.environ["_PYTHON_HOST_PLATFORM"].replace("-", "_").replace(".", "_")
|
|
122
|
-
tag = "-".join(tag.split("-")[:-1] + [plat])
|
|
123
|
-
|
|
124
|
-
LOG.info("load conf from pyproject.toml")
|
|
125
|
-
with Path("pyproject.toml").open("rb") as f:
|
|
126
|
-
pyproject = tomllib.load(f)
|
|
127
|
-
conf = pyproject["project"]
|
|
128
|
-
conf["name"] = normalize(conf["name"])
|
|
129
|
-
source = deprecate_build_system(pyproject, "source", ".")
|
|
130
|
-
run_tests = (
|
|
131
|
-
os.environ.get("CMEEL_RUN_TESTS", "ON").upper()
|
|
132
|
-
not in ("0", "NO", "OFF", "FALSE")
|
|
133
|
-
if "CMEEL_RUN_TESTS" in os.environ
|
|
134
|
-
else deprecate_build_system(pyproject, "run-tests", True)
|
|
135
|
-
)
|
|
136
|
-
run_tests_after_install = deprecate_build_system(
|
|
137
|
-
pyproject,
|
|
138
|
-
"run-tests-after-install",
|
|
139
|
-
False,
|
|
140
|
-
)
|
|
141
|
-
build_number = deprecate_build_system(pyproject, "build-number", 0)
|
|
142
|
-
configure_args = deprecate_build_system(pyproject, "configure-args", [])
|
|
143
|
-
test_cmd = deprecate_build_system(
|
|
144
|
-
pyproject,
|
|
145
|
-
"test-cmd",
|
|
146
|
-
["cmake", "--build", "BUILD_DIR", "-t", "test"],
|
|
147
|
-
)
|
|
148
|
-
check_relocatable = deprecate_build_system(pyproject, "check-relocatable", True)
|
|
149
|
-
fix_pkg_config = deprecate_build_system(pyproject, "fix-pkg-config", True)
|
|
150
|
-
if deprecate_build_system(pyproject, "py3-none", False):
|
|
151
|
-
tag = "-".join(["py3", "none", tag.split("-")[-1]])
|
|
152
|
-
elif deprecate_build_system(pyproject, "any", False):
|
|
153
|
-
tag = "py3-none-any"
|
|
154
|
-
elif deprecate_build_system(pyproject, "pyver-any", False):
|
|
155
|
-
tag = f"py3{sys.version_info.minor}-none-any"
|
|
156
|
-
distribution = f"{conf['name'].replace('-', '_')}-{conf['version']}"
|
|
157
|
-
|
|
158
|
-
LOG.info("build wheel")
|
|
159
|
-
|
|
160
|
-
# Patch
|
|
161
|
-
|
|
162
|
-
if Path("cmeel.patch").exists():
|
|
163
|
-
LOG.info("patching")
|
|
164
|
-
cmd = ["patch", "-p0", "-s", "-N", "-i", "cmeel.patch"]
|
|
165
|
-
ret = run(cmd, capture_output=True, text=True)
|
|
166
|
-
if ret.returncode != 0:
|
|
167
|
-
# If this patch was already applied, it's okay.
|
|
168
|
-
for line in ret.stdout.split("\n"):
|
|
169
|
-
if not line or any(val in line for val in PATCH_IGNORE):
|
|
170
|
-
continue
|
|
171
|
-
raise PatchError(
|
|
172
|
-
returncode=ret.returncode,
|
|
173
|
-
cmd=cmd,
|
|
174
|
-
output=ret.stdout,
|
|
175
|
-
stderr=ret.stderr + f"\nwrong line: {line}\n",
|
|
176
|
-
)
|
|
177
|
-
LOG.info("this patch was already applied")
|
|
178
|
-
|
|
179
|
-
# Set env
|
|
180
|
-
|
|
181
|
-
if run_tests_after_install:
|
|
182
|
-
path = f"{install / SITELIB}"
|
|
183
|
-
old = os.environ.get("PYTHONPATH", "")
|
|
184
|
-
if old:
|
|
185
|
-
path += f"{os.pathsep}{old}"
|
|
186
|
-
os.environ.update(PYTHONPATH=path)
|
|
187
|
-
|
|
188
|
-
# Configure
|
|
189
|
-
|
|
190
|
-
LOG.info("configure")
|
|
191
|
-
configure_env = cmeel_config.get_configure_env()
|
|
192
|
-
configure_args = cmeel_config.get_configure_args(
|
|
193
|
-
conf,
|
|
194
|
-
install,
|
|
195
|
-
configure_args,
|
|
196
|
-
configure_env,
|
|
197
|
-
run_tests,
|
|
198
|
-
)
|
|
199
|
-
configure_cmd = ["cmake", "-S", source, "-B", str(build), *configure_args]
|
|
200
|
-
LOG.debug("configure environment: %s", configure_env)
|
|
201
|
-
LOG.debug("configure command: %s", configure_cmd)
|
|
202
|
-
check_call(configure_cmd, env=configure_env)
|
|
203
|
-
|
|
204
|
-
LOG.info("build")
|
|
205
|
-
build_cmd = ["cmake", "--build", str(build), f"-j{cmeel_config.jobs}"]
|
|
206
|
-
LOG.debug("build command: %s", build_cmd)
|
|
207
|
-
check_call(build_cmd)
|
|
208
|
-
|
|
209
|
-
def launch_tests():
|
|
210
|
-
LOG.info("test")
|
|
211
|
-
test_env = cmeel_config.get_test_env()
|
|
212
|
-
cmd = [i.replace("BUILD_DIR", str(build)) for i in test_cmd]
|
|
213
|
-
LOG.debug("test environment: %s", test_env)
|
|
214
|
-
LOG.debug("test command: %s", cmd)
|
|
215
|
-
check_call(cmd, env=test_env)
|
|
216
|
-
|
|
217
|
-
if run_tests and not run_tests_after_install:
|
|
218
|
-
launch_tests()
|
|
219
|
-
|
|
220
|
-
LOG.info("install")
|
|
221
|
-
install_cmd = ["cmake", "--build", str(build), "-t", "install"]
|
|
222
|
-
LOG.debug("install command: %s", install_cmd)
|
|
223
|
-
check_call(install_cmd)
|
|
224
|
-
|
|
225
|
-
if run_tests and run_tests_after_install:
|
|
226
|
-
launch_tests()
|
|
227
|
-
|
|
228
|
-
LOG.info("fix relocatablization")
|
|
229
|
-
# Replace absolute install path in generated .cmake files, if any.
|
|
230
|
-
for f in install.rglob("*.cmake"):
|
|
231
|
-
ff = install / f"{f.stem}.fix"
|
|
232
|
-
with f.open("r") as fr, ff.open("w") as fw:
|
|
233
|
-
fw.write(fr.read().replace(str(install), "${PACKAGE_PREFIX_DIR}"))
|
|
234
|
-
f.unlink()
|
|
235
|
-
ff.rename(f)
|
|
236
|
-
|
|
237
|
-
LOG.info("create dist-info")
|
|
238
|
-
|
|
239
|
-
dist_info = wheel_dir / f"{distribution}.dist-info"
|
|
240
|
-
dist_info.mkdir(parents=True)
|
|
241
|
-
|
|
242
|
-
LOG.info("create dist-info / METADATA")
|
|
243
|
-
|
|
244
|
-
metadata = [
|
|
245
|
-
"Metadata-Version: 2.1",
|
|
246
|
-
f"Name: {conf['name']}",
|
|
247
|
-
f"Version: {conf['version']}",
|
|
248
|
-
f"Summary: {conf['description']}",
|
|
249
|
-
f"Requires-Python: {conf.get('requires-python', '>=3.7')}",
|
|
250
|
-
*get_license(conf, dist_info),
|
|
251
|
-
*get_people(conf, "author"),
|
|
252
|
-
*get_people(conf, "maintainer"),
|
|
253
|
-
*get_keywords(conf),
|
|
254
|
-
*get_urls(conf),
|
|
255
|
-
*get_deps(conf, pyproject["build-system"]["requires"]),
|
|
256
|
-
*[f"Classifier: {classifier}" for classifier in conf.get("classifiers", [])],
|
|
257
|
-
*get_readme(conf),
|
|
258
|
-
]
|
|
259
|
-
|
|
260
|
-
with (dist_info / "METADATA").open("w") as f:
|
|
261
|
-
f.write("\n".join(metadata))
|
|
262
|
-
|
|
263
|
-
LOG.info("create dist-info / top level")
|
|
264
|
-
with (dist_info / "top_level.txt").open("w") as f:
|
|
265
|
-
f.write("")
|
|
266
|
-
|
|
267
|
-
LOG.info("create dist-info / WHEEL")
|
|
268
|
-
with (dist_info / "WHEEL").open("w") as f:
|
|
269
|
-
f.write(
|
|
270
|
-
"\n".join(
|
|
271
|
-
[
|
|
272
|
-
"Wheel-Version: 1.0",
|
|
273
|
-
f"Generator: cmeel {__version__}",
|
|
274
|
-
"Root-Is-Purelib: false",
|
|
275
|
-
f"Tag: {tag}",
|
|
276
|
-
"",
|
|
277
|
-
],
|
|
278
|
-
),
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
bin_dir = install / "bin"
|
|
282
|
-
if bin_dir.is_dir():
|
|
283
|
-
LOG.info("adding executables")
|
|
284
|
-
scripts = wheel_dir / f"{distribution}.data" / "scripts"
|
|
285
|
-
scripts.mkdir(parents=True)
|
|
286
|
-
for fn in bin_dir.glob("*"):
|
|
287
|
-
executable = scripts / fn.name
|
|
288
|
-
with executable.open("w") as fe:
|
|
289
|
-
fe.write(EXECUTABLE)
|
|
290
|
-
executable.chmod(0o755)
|
|
291
|
-
|
|
292
|
-
if check_relocatable:
|
|
293
|
-
LOG.info("check generated cmake files")
|
|
294
|
-
wrong_dirs = [
|
|
295
|
-
"/tmp/pip-build-env",
|
|
296
|
-
"/tmp/pip-req-build",
|
|
297
|
-
"/opt/_internal",
|
|
298
|
-
str(prefix),
|
|
299
|
-
]
|
|
300
|
-
for fc in install.glob("**/*.cmake"):
|
|
301
|
-
with fc.open() as f:
|
|
302
|
-
cmake_file = f.read()
|
|
303
|
-
if any(wrong_dir in cmake_file for wrong_dir in wrong_dirs):
|
|
304
|
-
lines = cmake_file.split("\n")
|
|
305
|
-
# Get indexes of of problematic lines
|
|
306
|
-
indexes = [
|
|
307
|
-
idx
|
|
308
|
-
for idx, line in enumerate(lines)
|
|
309
|
-
if any(wrong_dir in line for wrong_dir in wrong_dirs)
|
|
310
|
-
]
|
|
311
|
-
# Get lines at those indexes and around them to display
|
|
312
|
-
display = [
|
|
313
|
-
f"{i}: {line}"
|
|
314
|
-
for i, line in enumerate(lines)
|
|
315
|
-
if any(
|
|
316
|
-
idx in indexes for idx in (i - 2, i - 1, i, i + 1, i + 2)
|
|
317
|
-
)
|
|
318
|
-
]
|
|
319
|
-
raise NonRelocatableError(
|
|
320
|
-
f"{fc} references temporary paths:\n" + "\n".join(display),
|
|
321
|
-
)
|
|
322
|
-
if fix_pkg_config and not editable:
|
|
323
|
-
LOG.info("fix pkg-config files")
|
|
324
|
-
for fc in install.glob("**/*.pc"):
|
|
325
|
-
with fc.open() as f:
|
|
326
|
-
pc_file = f.read()
|
|
327
|
-
if str(install) in pc_file:
|
|
328
|
-
rel = str(fc.parent.relative_to(install))
|
|
329
|
-
fix = "/".join(["${pcfiledir}"] + [".." for _ in rel.split("/")])
|
|
330
|
-
LOG.warning("fix pkg-config %s: replace %s by %s", fc, install, fix)
|
|
331
|
-
with fc.open("w") as f:
|
|
332
|
-
f.write(pc_file.replace(str(install), fix))
|
|
333
|
-
if editable:
|
|
334
|
-
LOG.info("Add .pth in wheel")
|
|
335
|
-
with (wheel_dir / f"{distribution}.pth").open("w") as f:
|
|
336
|
-
f.write(str((install / SITELIB).absolute()))
|
|
25
|
+
LOG.info("cmeel build wheel")
|
|
26
|
+
return build_impl(wheel_directory, editable=False)
|
|
337
27
|
|
|
338
|
-
LOG.info("wheel pack")
|
|
339
|
-
pack = check_output(
|
|
340
|
-
[
|
|
341
|
-
sys.executable,
|
|
342
|
-
"-m",
|
|
343
|
-
"wheel",
|
|
344
|
-
"pack",
|
|
345
|
-
"--build-number",
|
|
346
|
-
str(build_number),
|
|
347
|
-
"-d",
|
|
348
|
-
wheel_directory,
|
|
349
|
-
str(wheel_dir),
|
|
350
|
-
],
|
|
351
|
-
).decode()
|
|
352
|
-
LOG.debug("wheel pack output: %s", pack)
|
|
353
|
-
name = Path(re.search("Repacking wheel as (.*\\.whl)\\.\\.\\.", pack).group(1)).name
|
|
354
|
-
LOG.debug("returning '%s'", name)
|
|
355
28
|
|
|
356
|
-
|
|
357
|
-
|
|
29
|
+
def build_sdist(sdist_directory, config_settings=None) -> str:
|
|
30
|
+
"""Generate a gzipped distribution tarball."""
|
|
31
|
+
return sdist_impl(sdist_directory)
|
cmeel/consts.py
CHANGED
cmeel/impl.py
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""Implementation of the main build function."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from subprocess import check_call, check_output
|
|
9
|
+
|
|
10
|
+
try:
|
|
11
|
+
import tomllib # type: ignore
|
|
12
|
+
except ModuleNotFoundError:
|
|
13
|
+
import tomli as tomllib # type: ignore
|
|
14
|
+
|
|
15
|
+
from . import __version__
|
|
16
|
+
from .config import cmeel_config
|
|
17
|
+
from .consts import CMEEL_PREFIX, SITELIB
|
|
18
|
+
from .metadata import metadata
|
|
19
|
+
from .utils import (
|
|
20
|
+
deprecate_build_system,
|
|
21
|
+
ensure_relocatable,
|
|
22
|
+
expose_bin,
|
|
23
|
+
get_tag,
|
|
24
|
+
launch_tests,
|
|
25
|
+
log_pip,
|
|
26
|
+
normalize,
|
|
27
|
+
patch,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
LOG = logging.getLogger("cmeel.impl")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def build_impl(wheel_directory, editable=False) -> str:
|
|
34
|
+
"""Run CMake configure / build / test / install steps, and pack the wheel."""
|
|
35
|
+
logging.basicConfig(level=cmeel_config.log_level.upper())
|
|
36
|
+
LOG.info("CMake Wheel in editable mode" if editable else "CMake Wheel")
|
|
37
|
+
LOG.info("cmeel version %s" % __version__)
|
|
38
|
+
log_pip()
|
|
39
|
+
|
|
40
|
+
prefix = Path() / "build-editable" if editable else cmeel_config.temp_dir
|
|
41
|
+
build = prefix / "bld"
|
|
42
|
+
wheel_dir = prefix / "whl"
|
|
43
|
+
install = (prefix if editable else wheel_dir) / CMEEL_PREFIX
|
|
44
|
+
|
|
45
|
+
LOG.info("load conf from pyproject.toml")
|
|
46
|
+
with Path("pyproject.toml").open("rb") as f:
|
|
47
|
+
pyproject = tomllib.load(f)
|
|
48
|
+
|
|
49
|
+
conf = pyproject["project"]
|
|
50
|
+
conf["name"] = normalize(conf["name"])
|
|
51
|
+
distribution = f"{conf['name'].replace('-', '_')}-{conf['version']}"
|
|
52
|
+
|
|
53
|
+
source = deprecate_build_system(pyproject, "source", ".")
|
|
54
|
+
run_tests = (
|
|
55
|
+
os.environ.get("CMEEL_RUN_TESTS", "ON").upper()
|
|
56
|
+
not in ("0", "NO", "OFF", "FALSE")
|
|
57
|
+
if "CMEEL_RUN_TESTS" in os.environ
|
|
58
|
+
else deprecate_build_system(pyproject, "run-tests", True)
|
|
59
|
+
)
|
|
60
|
+
run_tests_after_install = deprecate_build_system(
|
|
61
|
+
pyproject,
|
|
62
|
+
"run-tests-after-install",
|
|
63
|
+
False,
|
|
64
|
+
)
|
|
65
|
+
build_number = deprecate_build_system(pyproject, "build-number", 0)
|
|
66
|
+
configure_args = deprecate_build_system(pyproject, "configure-args", [])
|
|
67
|
+
|
|
68
|
+
check_relocatable = deprecate_build_system(pyproject, "check-relocatable", True)
|
|
69
|
+
fix_pkg_config = deprecate_build_system(pyproject, "fix-pkg-config", True)
|
|
70
|
+
|
|
71
|
+
LOG.info("build wheel")
|
|
72
|
+
|
|
73
|
+
# Patch
|
|
74
|
+
|
|
75
|
+
patch()
|
|
76
|
+
|
|
77
|
+
# Set env
|
|
78
|
+
|
|
79
|
+
if run_tests_after_install:
|
|
80
|
+
path = f"{install / SITELIB}"
|
|
81
|
+
old = os.environ.get("PYTHONPATH", "")
|
|
82
|
+
if old:
|
|
83
|
+
path += f"{os.pathsep}{old}"
|
|
84
|
+
os.environ.update(PYTHONPATH=path)
|
|
85
|
+
|
|
86
|
+
# Configure
|
|
87
|
+
|
|
88
|
+
LOG.info("configure")
|
|
89
|
+
configure_env = cmeel_config.get_configure_env()
|
|
90
|
+
configure_args = cmeel_config.get_configure_args(
|
|
91
|
+
conf,
|
|
92
|
+
install,
|
|
93
|
+
configure_args,
|
|
94
|
+
configure_env,
|
|
95
|
+
run_tests,
|
|
96
|
+
)
|
|
97
|
+
configure_cmd = ["cmake", "-S", source, "-B", str(build), *configure_args]
|
|
98
|
+
LOG.debug("configure environment: %s", configure_env)
|
|
99
|
+
LOG.debug("configure command: %s", configure_cmd)
|
|
100
|
+
check_call(configure_cmd, env=configure_env)
|
|
101
|
+
|
|
102
|
+
LOG.info("build")
|
|
103
|
+
build_cmd = ["cmake", "--build", str(build), f"-j{cmeel_config.jobs}"]
|
|
104
|
+
LOG.debug("build command: %s", build_cmd)
|
|
105
|
+
check_call(build_cmd)
|
|
106
|
+
|
|
107
|
+
launch_tests(True, run_tests and not run_tests_after_install, pyproject, build)
|
|
108
|
+
|
|
109
|
+
LOG.info("install")
|
|
110
|
+
install_cmd = ["cmake", "--build", str(build), "-t", "install"]
|
|
111
|
+
LOG.debug("install command: %s", install_cmd)
|
|
112
|
+
check_call(install_cmd)
|
|
113
|
+
|
|
114
|
+
launch_tests(False, run_tests and run_tests_after_install, pyproject, build)
|
|
115
|
+
|
|
116
|
+
LOG.info("fix relocatablization")
|
|
117
|
+
# Replace absolute install path in generated .cmake files, if any.
|
|
118
|
+
for cmake_file in install.rglob("*.cmake"):
|
|
119
|
+
ff = install / f"{cmake_file.stem}.fix"
|
|
120
|
+
with cmake_file.open("r") as fr, ff.open("w") as fw:
|
|
121
|
+
fw.write(fr.read().replace(str(install), "${PACKAGE_PREFIX_DIR}"))
|
|
122
|
+
cmake_file.unlink()
|
|
123
|
+
ff.rename(cmake_file)
|
|
124
|
+
|
|
125
|
+
LOG.info("create dist-info")
|
|
126
|
+
|
|
127
|
+
dist_info = wheel_dir / f"{distribution}.dist-info"
|
|
128
|
+
dist_info.mkdir(parents=True)
|
|
129
|
+
|
|
130
|
+
LOG.info("create dist-info / METADATA")
|
|
131
|
+
|
|
132
|
+
with (dist_info / "METADATA").open("w") as f:
|
|
133
|
+
requires = pyproject["build-system"]["requires"]
|
|
134
|
+
f.write("\n".join(metadata(conf, dist_info, requires)))
|
|
135
|
+
|
|
136
|
+
LOG.info("create dist-info / top level")
|
|
137
|
+
with (dist_info / "top_level.txt").open("w") as f:
|
|
138
|
+
f.write("")
|
|
139
|
+
|
|
140
|
+
LOG.info("create dist-info / WHEEL")
|
|
141
|
+
with (dist_info / "WHEEL").open("w") as f:
|
|
142
|
+
f.write(
|
|
143
|
+
"\n".join(
|
|
144
|
+
[
|
|
145
|
+
"Wheel-Version: 1.0",
|
|
146
|
+
f"Generator: cmeel {__version__}",
|
|
147
|
+
"Root-Is-Purelib: false",
|
|
148
|
+
f"Tag: {get_tag(pyproject)}",
|
|
149
|
+
"",
|
|
150
|
+
],
|
|
151
|
+
),
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
expose_bin(install, wheel_dir, distribution)
|
|
155
|
+
|
|
156
|
+
ensure_relocatable(check_relocatable, install, prefix)
|
|
157
|
+
|
|
158
|
+
if editable:
|
|
159
|
+
LOG.info("Add .pth in wheel")
|
|
160
|
+
with (wheel_dir / f"{distribution}.pth").open("w") as f:
|
|
161
|
+
f.write(str((install / SITELIB).absolute()))
|
|
162
|
+
elif fix_pkg_config:
|
|
163
|
+
LOG.info("fix pkg-config files")
|
|
164
|
+
for fc in install.glob("**/*.pc"):
|
|
165
|
+
with fc.open() as f:
|
|
166
|
+
pc_file = f.read()
|
|
167
|
+
if str(install) in pc_file:
|
|
168
|
+
rel = str(fc.parent.relative_to(install))
|
|
169
|
+
fix = "/".join(["${pcfiledir}"] + [".." for _ in rel.split("/")])
|
|
170
|
+
LOG.warning("fix pkg-config %s: replace %s by %s", fc, install, fix)
|
|
171
|
+
with fc.open("w") as f:
|
|
172
|
+
f.write(pc_file.replace(str(install), fix))
|
|
173
|
+
|
|
174
|
+
LOG.info("wheel pack")
|
|
175
|
+
pack = check_output(
|
|
176
|
+
[
|
|
177
|
+
sys.executable,
|
|
178
|
+
"-m",
|
|
179
|
+
"wheel",
|
|
180
|
+
"pack",
|
|
181
|
+
"--build-number",
|
|
182
|
+
str(build_number),
|
|
183
|
+
"-d",
|
|
184
|
+
wheel_directory,
|
|
185
|
+
str(wheel_dir),
|
|
186
|
+
],
|
|
187
|
+
).decode()
|
|
188
|
+
LOG.debug("wheel pack output: %s", pack)
|
|
189
|
+
parse_pack = re.search("Repacking wheel as (.*\\.whl)\\.\\.\\.", pack)
|
|
190
|
+
if parse_pack is None:
|
|
191
|
+
err = (
|
|
192
|
+
"'wheel pack' command did not provide the .whl name, "
|
|
193
|
+
"or the parser must be updated. Please report the following output: \n"
|
|
194
|
+
)
|
|
195
|
+
raise FileNotFoundError(err + pack)
|
|
196
|
+
name = Path(parse_pack.group(1)).name
|
|
197
|
+
LOG.debug("returning '%s'", name)
|
|
198
|
+
|
|
199
|
+
LOG.info("done")
|
|
200
|
+
return name
|
cmeel/metadata.py
CHANGED
|
@@ -5,7 +5,6 @@ https://packaging.python.org/en/latest/specifications/declaring-project-metadata
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import glob
|
|
8
|
-
import re
|
|
9
8
|
import warnings
|
|
10
9
|
from pathlib import Path
|
|
11
10
|
from typing import Any, Dict, List, Tuple, Union
|
|
@@ -13,14 +12,6 @@ from typing import Any, Dict, List, Tuple, Union
|
|
|
13
12
|
LICENSE_GLOBS = ["LICEN[CS]E*", "COPYING*", "NOTICE*", "AUTHORS*"]
|
|
14
13
|
|
|
15
14
|
|
|
16
|
-
def normalize(name: str) -> str:
|
|
17
|
-
"""Normalize name.
|
|
18
|
-
|
|
19
|
-
ref. https://packaging.python.org/en/latest/specifications/name-normalization
|
|
20
|
-
"""
|
|
21
|
-
return re.sub(r"[-_.]+", "-", name).lower()
|
|
22
|
-
|
|
23
|
-
|
|
24
15
|
def get_license(conf: Dict[str, Any], dist_info: Path) -> List[str]:
|
|
25
16
|
"""Parse 'license' and 'license-files' keys."""
|
|
26
17
|
metadata = []
|
|
@@ -237,3 +228,22 @@ def get_keywords(conf: Dict[str, Any]) -> List[str]:
|
|
|
237
228
|
keywords = ",".join(conf["keywords"])
|
|
238
229
|
metadata.append(f"Keywords: {keywords}")
|
|
239
230
|
return metadata
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def metadata(conf, dist_info, requires) -> List[str]:
|
|
234
|
+
"""Return the lines which should go in the METADATA / PKG-INFO file."""
|
|
235
|
+
return [
|
|
236
|
+
"Metadata-Version: 2.1",
|
|
237
|
+
f"Name: {conf['name']}",
|
|
238
|
+
f"Version: {conf['version']}",
|
|
239
|
+
f"Summary: {conf['description']}",
|
|
240
|
+
f"Requires-Python: {conf.get('requires-python', '>=3.8')}",
|
|
241
|
+
*get_license(conf, dist_info),
|
|
242
|
+
*get_people(conf, "author"),
|
|
243
|
+
*get_people(conf, "maintainer"),
|
|
244
|
+
*get_keywords(conf),
|
|
245
|
+
*get_urls(conf),
|
|
246
|
+
*get_deps(conf, requires),
|
|
247
|
+
*[f"Classifier: {classifier}" for classifier in conf.get("classifiers", [])],
|
|
248
|
+
*get_readme(conf),
|
|
249
|
+
]
|
cmeel/release.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Helper to release a cmeel project."""
|
|
3
|
+
from logging import getLogger
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from subprocess import check_call
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
import tomllib # type: ignore
|
|
9
|
+
except ModuleNotFoundError:
|
|
10
|
+
import tomli as tomllib # type: ignore
|
|
11
|
+
|
|
12
|
+
LOG = getLogger("cmeel.release")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def add_release_arguments(subparsers):
|
|
16
|
+
"""Append release command for argparse."""
|
|
17
|
+
sub = subparsers.add_parser("release", help="release a cmeel project.")
|
|
18
|
+
sub.set_defaults(cmd="release")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def release(**kwargs):
|
|
22
|
+
"""Release a cmeel project."""
|
|
23
|
+
with Path("pyproject.toml").open("rb") as f:
|
|
24
|
+
pyproject = tomllib.load(f)
|
|
25
|
+
|
|
26
|
+
version = pyproject["project"]["version"]
|
|
27
|
+
build = pyproject.get("tool", {}).get("cmeel", {}).get("build-number", 0)
|
|
28
|
+
tag = f"v{version}.c{build}"
|
|
29
|
+
release = f"Cmeel Release {tag}"
|
|
30
|
+
|
|
31
|
+
LOG.info("Releasing vesion '%s'", tag)
|
|
32
|
+
|
|
33
|
+
commit_cmd = ["git", "commit", "-am", release]
|
|
34
|
+
LOG.debug("commit command: %s", commit_cmd)
|
|
35
|
+
check_call(commit_cmd)
|
|
36
|
+
|
|
37
|
+
tag_cmd = ["git", "tag", "-s", tag, "-m", release]
|
|
38
|
+
LOG.debug("tag command: %s", tag_cmd)
|
|
39
|
+
check_call(tag_cmd)
|
|
40
|
+
|
|
41
|
+
push_cmd = ["git", "push", "origin", tag]
|
|
42
|
+
LOG.debug("push command: %s", push_cmd)
|
|
43
|
+
check_call(push_cmd)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
if __name__ == "__main__":
|
|
47
|
+
import logging
|
|
48
|
+
|
|
49
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
50
|
+
release()
|
cmeel/sdist.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Generate .tar.gz source distribution."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
import tomllib # type: ignore
|
|
8
|
+
except ModuleNotFoundError:
|
|
9
|
+
import tomli as tomllib # type: ignore
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
import git_archive_all
|
|
13
|
+
except ImportError as e:
|
|
14
|
+
err = "You need the 'build' extra option to use this build module.\n"
|
|
15
|
+
err += "For this you can install the 'cmeel[build]' package."
|
|
16
|
+
raise ImportError(err) from e
|
|
17
|
+
|
|
18
|
+
from .utils import normalize
|
|
19
|
+
|
|
20
|
+
LOG = logging.getLogger("cmeel.sdist")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def sdist_impl(sdist_directory) -> str:
|
|
24
|
+
"""Implement the build_sdist entry point."""
|
|
25
|
+
LOG.info("load conf from pyproject.toml")
|
|
26
|
+
with Path("pyproject.toml").open("rb") as f:
|
|
27
|
+
pyproject = tomllib.load(f)
|
|
28
|
+
|
|
29
|
+
conf = pyproject["project"]
|
|
30
|
+
conf["name"] = normalize(conf["name"])
|
|
31
|
+
distribution = f"{conf['name'].replace('-', '_')}-{conf['version']}"
|
|
32
|
+
|
|
33
|
+
git_archive_all.main(
|
|
34
|
+
["git_archive_all.py", str(Path(sdist_directory) / f"{distribution}.tar.gz")],
|
|
35
|
+
)
|
|
36
|
+
return distribution
|
cmeel/utils.py
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"""Utilities."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import sys
|
|
7
|
+
import warnings
|
|
8
|
+
from importlib.util import find_spec
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from subprocess import CalledProcessError, check_call, check_output, run
|
|
11
|
+
|
|
12
|
+
from .config import cmeel_config
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
from packaging.tags import sys_tags
|
|
16
|
+
except ImportError as e:
|
|
17
|
+
err = "You need the 'build' extra option to use this build module.\n"
|
|
18
|
+
err += "For this you can install the 'cmeel[build]' package."
|
|
19
|
+
raise ImportError(err) from e
|
|
20
|
+
|
|
21
|
+
LOG = logging.getLogger("cmeel.utils")
|
|
22
|
+
|
|
23
|
+
PATCH_IGNORE = [
|
|
24
|
+
"hunk ignored",
|
|
25
|
+
"hunks ignored",
|
|
26
|
+
"Skipping patch.",
|
|
27
|
+
"The next patch would delete",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
EXECUTABLE = """#!python
|
|
31
|
+
from cmeel.run import cmeel_run
|
|
32
|
+
cmeel_run()
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class PatchError(CalledProcessError):
|
|
37
|
+
"""Exception raised when patch operation failed."""
|
|
38
|
+
|
|
39
|
+
def __str__(self):
|
|
40
|
+
"""Render this error as a string."""
|
|
41
|
+
if self.returncode and self.returncode < 0:
|
|
42
|
+
return super().__str__()
|
|
43
|
+
return (
|
|
44
|
+
f"Command '{self.cmd}' exit status {self.returncode}\n"
|
|
45
|
+
f"with output:\n{self.output}\n"
|
|
46
|
+
f"and stderr:\n{self.stderr}\n"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class NonRelocatableError(Exception):
|
|
51
|
+
"""Exception raised when absolute paths are in the final package."""
|
|
52
|
+
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def deprecate_build_system(pyproject, key, default):
|
|
57
|
+
"""Cmeel up to v0.22 was using the "build-system" section of pyproject.toml.
|
|
58
|
+
|
|
59
|
+
This function helps to deprecate that and move to "tool.cmeel".
|
|
60
|
+
"""
|
|
61
|
+
if key in pyproject["build-system"]:
|
|
62
|
+
default = pyproject["build-system"][key]
|
|
63
|
+
warnings.warn(
|
|
64
|
+
'Using the "build-system" section of pyproject.toml for cmeel '
|
|
65
|
+
"configuration is deprecated since cmeel v0.23 and will be removed in v1.\n"
|
|
66
|
+
f'Please move your "{key} = {default}" to the "tool.cmeel" section.',
|
|
67
|
+
DeprecationWarning,
|
|
68
|
+
stacklevel=2,
|
|
69
|
+
)
|
|
70
|
+
if "tool" in pyproject and "cmeel" in pyproject["tool"]:
|
|
71
|
+
return pyproject["tool"]["cmeel"].get(key, default)
|
|
72
|
+
return default
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def normalize(name: str) -> str:
|
|
76
|
+
"""Normalize name.
|
|
77
|
+
|
|
78
|
+
ref. https://packaging.python.org/en/latest/specifications/name-normalization
|
|
79
|
+
"""
|
|
80
|
+
return re.sub(r"[-_.]+", "-", name).lower()
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def log_pip():
|
|
84
|
+
"""Log output of pip freeze."""
|
|
85
|
+
if LOG.getEffectiveLevel() <= logging.DEBUG:
|
|
86
|
+
if find_spec("pip") is not None:
|
|
87
|
+
LOG.debug("pip freeze:")
|
|
88
|
+
deps = check_output([sys.executable, "-m", "pip", "freeze"], text=True)
|
|
89
|
+
for dep in deps.strip().split("\n"):
|
|
90
|
+
LOG.debug(" %s", dep)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def get_tag(pyproject) -> str:
|
|
94
|
+
"""Find the correct tag for the wheel."""
|
|
95
|
+
tag = str(next(sys_tags()))
|
|
96
|
+
# handle cross compilation on macOS with cibuildwheel
|
|
97
|
+
# ref. https://github.com/pypa/cibuildwheel/blob/6549a9/cibuildwheel/macos.py#L221
|
|
98
|
+
if "_PYTHON_HOST_PLATFORM" in os.environ:
|
|
99
|
+
plat = os.environ["_PYTHON_HOST_PLATFORM"].replace("-", "_").replace(".", "_")
|
|
100
|
+
tag = "-".join(tag.split("-")[:-1] + [plat])
|
|
101
|
+
|
|
102
|
+
if deprecate_build_system(pyproject, "py3-none", False):
|
|
103
|
+
tag = "-".join(["py3", "none", tag.split("-")[-1]])
|
|
104
|
+
elif deprecate_build_system(pyproject, "any", False):
|
|
105
|
+
tag = "py3-none-any"
|
|
106
|
+
elif deprecate_build_system(pyproject, "pyver-any", False):
|
|
107
|
+
tag = f"py3{sys.version_info.minor}-none-any"
|
|
108
|
+
return tag
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def patch():
|
|
112
|
+
"""Apply cmeel.patch if it exists and was not already applied."""
|
|
113
|
+
if Path("cmeel.patch").exists():
|
|
114
|
+
LOG.info("patching")
|
|
115
|
+
cmd = ["patch", "-p0", "-s", "-N", "-i", "cmeel.patch"]
|
|
116
|
+
ret = run(cmd, capture_output=True, text=True)
|
|
117
|
+
if ret.returncode != 0:
|
|
118
|
+
# If this patch was already applied, it's okay.
|
|
119
|
+
for line in ret.stdout.split("\n"):
|
|
120
|
+
if not line or any(val in line for val in PATCH_IGNORE):
|
|
121
|
+
continue
|
|
122
|
+
raise PatchError(
|
|
123
|
+
returncode=ret.returncode,
|
|
124
|
+
cmd=cmd,
|
|
125
|
+
output=ret.stdout,
|
|
126
|
+
stderr=ret.stderr + f"\nwrong line: {line}\n",
|
|
127
|
+
)
|
|
128
|
+
LOG.info("this patch was already applied")
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def expose_bin(install: Path, wheel_dir: Path, distribution: str):
|
|
132
|
+
"""Add scripts wrapping calls to CMEEL_PREFIX/bin/ executables."""
|
|
133
|
+
bin_dir = install / "bin"
|
|
134
|
+
if bin_dir.is_dir():
|
|
135
|
+
LOG.info("adding executables")
|
|
136
|
+
scripts = wheel_dir / f"{distribution}.data" / "scripts"
|
|
137
|
+
scripts.mkdir(parents=True)
|
|
138
|
+
for fn in bin_dir.glob("*"):
|
|
139
|
+
executable = scripts / fn.name
|
|
140
|
+
with executable.open("w") as fe:
|
|
141
|
+
fe.write(EXECUTABLE)
|
|
142
|
+
executable.chmod(0o755)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def ensure_relocatable(check_relocatable: bool, install: Path, prefix: Path):
|
|
146
|
+
"""Ensure no cmake file contains wrong absolute paths."""
|
|
147
|
+
if not check_relocatable:
|
|
148
|
+
return
|
|
149
|
+
LOG.info("check generated cmake files")
|
|
150
|
+
wrong_dirs = [
|
|
151
|
+
"/tmp/pip-build-env",
|
|
152
|
+
"/tmp/pip-req-build",
|
|
153
|
+
"/opt/_internal",
|
|
154
|
+
str(prefix),
|
|
155
|
+
]
|
|
156
|
+
for fc in install.glob("**/*.cmake"):
|
|
157
|
+
with fc.open() as f:
|
|
158
|
+
cmake_file = f.read()
|
|
159
|
+
if any(wrong_dir in cmake_file for wrong_dir in wrong_dirs):
|
|
160
|
+
lines = cmake_file.split("\n")
|
|
161
|
+
# Get indexes of of problematic lines
|
|
162
|
+
indexes = [
|
|
163
|
+
idx
|
|
164
|
+
for idx, line in enumerate(lines)
|
|
165
|
+
if any(wrong_dir in line for wrong_dir in wrong_dirs)
|
|
166
|
+
]
|
|
167
|
+
# Get lines at those indexes and around them to display
|
|
168
|
+
display = [
|
|
169
|
+
f"{i}: {line}"
|
|
170
|
+
for i, line in enumerate(lines)
|
|
171
|
+
if any(idx in indexes for idx in (i - 2, i - 1, i, i + 1, i + 2))
|
|
172
|
+
]
|
|
173
|
+
raise NonRelocatableError(
|
|
174
|
+
f"{fc} references temporary paths:\n" + "\n".join(display),
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def launch_tests(before: bool, now: bool, pyproject, build: Path):
|
|
179
|
+
"""Launch tests, before or after the install."""
|
|
180
|
+
if not now:
|
|
181
|
+
return
|
|
182
|
+
|
|
183
|
+
test_cmd = deprecate_build_system(
|
|
184
|
+
pyproject,
|
|
185
|
+
"test-cmd",
|
|
186
|
+
["cmake", "--build", "BUILD_DIR", "-t", "test"],
|
|
187
|
+
)
|
|
188
|
+
LOG.info("test {} install".format("before") if before else "after")
|
|
189
|
+
test_env = cmeel_config.get_test_env()
|
|
190
|
+
cmd = [i.replace("BUILD_DIR", str(build)) for i in test_cmd]
|
|
191
|
+
LOG.debug("test environment: %s", test_env)
|
|
192
|
+
LOG.debug("test command: %s", cmd)
|
|
193
|
+
check_call(cmd, env=test_env)
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cmeel
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.47.1
|
|
4
4
|
Summary: Create Wheel from CMake projects
|
|
5
5
|
Home-page: https://github.com/cmake-wheel/cmeel
|
|
6
6
|
License: BSD-2-Clause
|
|
7
7
|
Author: Guilhem Saurel
|
|
8
8
|
Author-email: guilhem.saurel@laas.fr
|
|
9
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.8,<4.0
|
|
10
10
|
Classifier: License :: OSI Approved :: BSD License
|
|
11
11
|
Classifier: Operating System :: MacOS
|
|
12
12
|
Classifier: Operating System :: POSIX :: Linux
|
|
13
13
|
Classifier: Programming Language :: C++
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.8
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -21,11 +20,11 @@ Classifier: Topic :: Software Development :: Build Tools
|
|
|
21
20
|
Classifier: Topic :: System :: Archiving :: Packaging
|
|
22
21
|
Classifier: Topic :: System :: Software Distribution
|
|
23
22
|
Provides-Extra: build
|
|
24
|
-
Requires-Dist: cmake (>=3.
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist: packaging (>=23.
|
|
23
|
+
Requires-Dist: cmake (>=3.27.0,<4.0.0) ; extra == "build"
|
|
24
|
+
Requires-Dist: git-archive-all (>=1.23.1,<2.0.0) ; extra == "build"
|
|
25
|
+
Requires-Dist: packaging (>=23.1,<24.0) ; extra == "build"
|
|
27
26
|
Requires-Dist: tomli (>=2.0.1,<3.0.0) ; python_version < "3.11"
|
|
28
|
-
Requires-Dist: wheel (>=0.
|
|
27
|
+
Requires-Dist: wheel (>=0.41.0,<0.42.0) ; extra == "build"
|
|
29
28
|
Project-URL: Documentation, https://cmeel.readthedocs.io/
|
|
30
29
|
Project-URL: changelog, https://github.com/cmake-wheel/cmeel/blob/main/CHANGELOG.md
|
|
31
30
|
Description-Content-Type: text/markdown
|
|
@@ -55,7 +54,7 @@ https://matrix.to/#/#cmake-wheel:matrix.org
|
|
|
55
54
|
|
|
56
55
|
## Basic idea
|
|
57
56
|
|
|
58
|
-
Glue between PEP 517
|
|
57
|
+
Glue between PEP 517 & 660 entry points and modern CMake standard project configuration / build / test / install
|
|
59
58
|
|
|
60
59
|
This Install in `${PYTHON_SITELIB}/cmeel.prefix/`:
|
|
61
60
|
- As there is a dot, it is not a valid python module name, so no risk of importing anything there by mistake
|
|
@@ -92,3 +91,11 @@ build-backend = "cmeel.build"
|
|
|
92
91
|
Complete specification is available at:
|
|
93
92
|
https://packaging.python.org/en/latest/specifications/declaring-project-metadata
|
|
94
93
|
|
|
94
|
+
## Install
|
|
95
|
+
|
|
96
|
+
If you want to use the helpers provided by cmeel, to *eg*. test building a project in a manylinux container with
|
|
97
|
+
`cmeel docker`, the best way to install cmeel is to use pipx: `pipx install cmeel`
|
|
98
|
+
|
|
99
|
+
Otherwise, if you just want to use the build backend, there is no need to install anything: your frontent (*eg.* `pip`)
|
|
100
|
+
should do this for you
|
|
101
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
cmeel/__init__.py,sha256=eEZ_-QB8hrFy71rXK-I3CfkC-LbTqMaM-5EzynRzwHU,247
|
|
2
|
+
cmeel/__main__.py,sha256=gLQ5_di07raiL6u75jpE36QydXlsbBzSdff9mVKtbg4,2042
|
|
3
|
+
cmeel/backports.py,sha256=ZJ34NDWgrlrSkq8AGrKof9SQexQH8sver2HmJIur80c,1473
|
|
4
|
+
cmeel/build.py,sha256=iYcKI1CCiRry2ESee1gUrL71N8-6rC_yie97hCfKgz0,867
|
|
5
|
+
cmeel/config.py,sha256=VrxuFCaoQ7c9cVeGNNMFR7Hl6Vv_G44x8perI-XhrjA,3634
|
|
6
|
+
cmeel/consts.py,sha256=m0wZ8IbghuFII9hVnLzWBK9GLQn0ibrHIQkPB5YF0Yk,195
|
|
7
|
+
cmeel/docker.py,sha256=wT-VZuGKj1wcdldwgsYcWmJK_rjo2Eh1USEDMOmlsBU,2775
|
|
8
|
+
cmeel/env.py,sha256=OOA64v6KysZTvFup5rZuBFYVSDvPoW_6PqUcuf4m0Os,1235
|
|
9
|
+
cmeel/impl.py,sha256=B7BbnV5hahytfkinwdtP_hfV1PwbOhQGMci92qUNhV8,6372
|
|
10
|
+
cmeel/metadata.py,sha256=MVR2noMFVzJAKAdpSfi3nbLxf60btK_yHmsT9lETMaw,8496
|
|
11
|
+
cmeel/pth.py,sha256=N0G1d8BHRcuzNEfQaK9WMW0h6s-Sjigc7JUAPPoeu4Q,403
|
|
12
|
+
cmeel/release.py,sha256=j8vxeAevtUFfwlV4gXGJ6tWqR-CNHn_d69FRhgeWkjY,1356
|
|
13
|
+
cmeel/run.py,sha256=sD2Is7MEb5yIUu6dMjzyOJgb-ErJh-EBII9WzL13zco,743
|
|
14
|
+
cmeel/sdist.py,sha256=RRN-FksbDSnCsSpIkfpd0AWKIkbcqUUpAKml_8l3R1k,1015
|
|
15
|
+
cmeel/utils.py,sha256=VGzjn5Z4Xjw--8sdL1ldaWXhC5oQEPG2Nl4v1JbUH2c,6604
|
|
16
|
+
cmeel.pth,sha256=CD-QdG4ceUgq5wIEJZpipOSZQF8apq7i9u9RhsBWbc8,17
|
|
17
|
+
cmeel-0.47.1.dist-info/LICENSE,sha256=4QHEuqIDbscybBc21CcazwRjix-rV-AH2QAZ4IqxlzQ,1324
|
|
18
|
+
cmeel-0.47.1.dist-info/METADATA,sha256=rukCJUfjjF0vTv8jHCLeoji-62_AoylQV06Q1c7dnNk,4906
|
|
19
|
+
cmeel-0.47.1.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
|
20
|
+
cmeel-0.47.1.dist-info/entry_points.txt,sha256=AiK0nCTi1LpRXxyiSCcbPsLYIpSvYW8GF7jcllMIl1U,45
|
|
21
|
+
cmeel-0.47.1.dist-info/RECORD,,
|
cmeel-0.45.0.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
cmeel/__init__.py,sha256=qXgvoZwlDxRzuWhU5M88WFU42uSbOQS9TY4CfmKJTKY,352
|
|
2
|
-
cmeel/__main__.py,sha256=oUdz8nBX0mtsDHoMh-_leiTY7grjFwrEzV-wkupKfYk,1661
|
|
3
|
-
cmeel/backports.py,sha256=ahVkwvNplt4xqY8RAb7lzzDks9tzrgB5QEAGVzkeBqg,1457
|
|
4
|
-
cmeel/build.py,sha256=dvUj6ofbpQLau3VvlvagqP0X6ap0cjB1r0jPecfvphI,12583
|
|
5
|
-
cmeel/config.py,sha256=VrxuFCaoQ7c9cVeGNNMFR7Hl6Vv_G44x8perI-XhrjA,3634
|
|
6
|
-
cmeel/consts.py,sha256=HRFNs1Zusp1aw7TfzseUcE6Llz4zbCGhxw0O1Wc5c5E,179
|
|
7
|
-
cmeel/docker.py,sha256=wT-VZuGKj1wcdldwgsYcWmJK_rjo2Eh1USEDMOmlsBU,2775
|
|
8
|
-
cmeel/env.py,sha256=OOA64v6KysZTvFup5rZuBFYVSDvPoW_6PqUcuf4m0Os,1235
|
|
9
|
-
cmeel/metadata.py,sha256=sjcuglpUdalkTIB6REaH7eoD-6f04jzYIO9rftTaZOQ,8017
|
|
10
|
-
cmeel/pth.py,sha256=N0G1d8BHRcuzNEfQaK9WMW0h6s-Sjigc7JUAPPoeu4Q,403
|
|
11
|
-
cmeel/run.py,sha256=sD2Is7MEb5yIUu6dMjzyOJgb-ErJh-EBII9WzL13zco,743
|
|
12
|
-
cmeel.pth,sha256=CD-QdG4ceUgq5wIEJZpipOSZQF8apq7i9u9RhsBWbc8,17
|
|
13
|
-
cmeel-0.45.0.dist-info/LICENSE,sha256=4QHEuqIDbscybBc21CcazwRjix-rV-AH2QAZ4IqxlzQ,1324
|
|
14
|
-
cmeel-0.45.0.dist-info/METADATA,sha256=Uf18Ajzg2ePo2nQZ48aRMvDb2tIlSnmCNPnTgz3CxRw,4615
|
|
15
|
-
cmeel-0.45.0.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
|
16
|
-
cmeel-0.45.0.dist-info/entry_points.txt,sha256=AiK0nCTi1LpRXxyiSCcbPsLYIpSvYW8GF7jcllMIl1U,45
|
|
17
|
-
cmeel-0.45.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|