|
3 | 3 | import os |
4 | 4 | import pathlib |
5 | 5 | import platform |
| 6 | +import shutil |
6 | 7 | import sys |
7 | 8 | import tempfile |
8 | 9 | import typing |
9 | 10 | import zipfile |
10 | 11 | from datetime import datetime |
11 | 12 |
|
12 | 13 | import elfdeps |
| 14 | +import tomlkit |
13 | 15 | from packaging.requirements import Requirement |
14 | 16 | from packaging.utils import parse_wheel_filename |
15 | 17 | from packaging.version import Version |
@@ -129,6 +131,73 @@ def analyze_wheel_elfdeps( |
129 | 131 | return requires, provides |
130 | 132 |
|
131 | 133 |
|
| 134 | +def add_extra_metadata_to_wheels( |
| 135 | + ctx: context.WorkContext, |
| 136 | + req: Requirement, |
| 137 | + version: Version, |
| 138 | + extra_environ: dict[str, str], |
| 139 | + sdist_root_dir: pathlib.Path, |
| 140 | + wheel_file: pathlib.Path, |
| 141 | +) -> None: |
| 142 | + extra_data_plugin = overrides.find_override_method( |
| 143 | + req.name, "add_extra_metadata_to_wheels" |
| 144 | + ) |
| 145 | + data_to_add = {} |
| 146 | + if extra_data_plugin: |
| 147 | + data_to_add = overrides.invoke( |
| 148 | + extra_data_plugin, |
| 149 | + ctx=ctx, |
| 150 | + req=req, |
| 151 | + version=version, |
| 152 | + extra_environ=extra_environ, |
| 153 | + sdist_root_dir=sdist_root_dir, |
| 154 | + ) |
| 155 | + if not isinstance(data_to_add, dict): |
| 156 | + logger.warning( |
| 157 | + f"{req.name}: unexpected return type from plugin add_extra_metadata_to_wheels. Expected dictionary. Will ignore" |
| 158 | + ) |
| 159 | + data_to_add = {} |
| 160 | + |
| 161 | + with tempfile.TemporaryDirectory() as dir_name: |
| 162 | + cmd = ["wheel", "unpack", str(wheel_file), "-d", dir_name] |
| 163 | + external_commands.run( |
| 164 | + cmd, |
| 165 | + cwd=dir_name, |
| 166 | + network_isolation=ctx.network_isolation, |
| 167 | + ) |
| 168 | + |
| 169 | + wheel_file_name_parts = wheel_file.name.split("-") |
| 170 | + distribution_name = f"{wheel_file_name_parts[0]}-{wheel_file_name_parts[1]}" |
| 171 | + dist_info_dir = ( |
| 172 | + pathlib.Path(dir_name) |
| 173 | + / distribution_name |
| 174 | + / f"{distribution_name}.dist-info" |
| 175 | + ) |
| 176 | + if not dist_info_dir.exists(): |
| 177 | + logger.debug( |
| 178 | + f"{req.name}: could not add additional metadata. {dist_info_dir} does not exist" |
| 179 | + ) |
| 180 | + return |
| 181 | + |
| 182 | + build_file = dist_info_dir / "BUILD" |
| 183 | + build_file.write_text( |
| 184 | + tomlkit.dumps(ctx.settings.get_package_settings(req.name)) |
| 185 | + ) |
| 186 | + if data_to_add: |
| 187 | + build_file.write_text(tomlkit.dumps(data_to_add)) |
| 188 | + |
| 189 | + req_files = sdist_root_dir.parent.glob("*-requirements.txt") |
| 190 | + for req_file in req_files: |
| 191 | + shutil.copy(req_file, dist_info_dir) |
| 192 | + |
| 193 | + cmd = ["wheel", "pack", str(dist_info_dir.parent), "-d", str(wheel_file.parent)] |
| 194 | + external_commands.run( |
| 195 | + cmd, |
| 196 | + cwd=dir_name, |
| 197 | + network_isolation=ctx.network_isolation, |
| 198 | + ) |
| 199 | + |
| 200 | + |
132 | 201 | def build_wheel( |
133 | 202 | ctx: context.WorkContext, |
134 | 203 | req: Requirement, |
@@ -172,6 +241,14 @@ def build_wheel( |
172 | 241 | # TODO: raise error? |
173 | 242 | return None |
174 | 243 | wheel = wheels[0] |
| 244 | + add_extra_metadata_to_wheels( |
| 245 | + ctx=ctx, |
| 246 | + req=req, |
| 247 | + version=version, |
| 248 | + extra_environ=extra_environ, |
| 249 | + sdist_root_dir=sdist_root_dir, |
| 250 | + wheel_file=wheel, |
| 251 | + ) |
175 | 252 | logger.info(f"{req.name}: built wheel '{wheel}' in {end - start}") |
176 | 253 | analyze_wheel_elfdeps(ctx, req, wheel) |
177 | 254 | return wheel |
|
0 commit comments