|
1 | 1 | import os
|
2 |
| -import sys |
3 |
| -import zipfile |
| 2 | +import shutil |
| 3 | +import subprocess |
4 | 4 | from glob import glob
|
5 | 5 |
|
6 | 6 | if __name__ == "__main__":
|
7 | 7 | # Due to https://github.com/python-poetry/poetry/issues/3509 and Poetry
|
8 |
| - # assuming the tags, we have to change the wheel ourselves after build |
| 8 | + # assuming the tags, we have to change the wheel ourselves after build. In |
| 9 | + # order to keep checksums proper, we use wheel pack/unpack. |
9 | 10 |
|
10 | 11 | # Get the file from the dist dir
|
11 | 12 | dist_files = glob("dist/*.whl")
|
12 |
| - if not dist_files: |
13 |
| - raise RuntimeError("Should have at least one wheel file in dist") |
14 |
| - for existing_wheel_file in dist_files: |
15 |
| - # Rename the wheel file and confirm it is changed. We need to make it |
16 |
| - # py37 minimum interpreter and abi3 compat. |
17 |
| - wheel_file_pieces = existing_wheel_file.split("-") |
18 |
| - if len(wheel_file_pieces) < 4: |
19 |
| - raise RuntimeError("Expecting at least 4 wheel pieces") |
20 |
| - wheel_file_pieces[2] = "cp37" |
21 |
| - wheel_file_pieces[3] = "abi3" |
22 |
| - new_wheel_file = "-".join(wheel_file_pieces) |
23 |
| - if existing_wheel_file == new_wheel_file: |
24 |
| - raise RuntimeError("Wheel file already fixed") |
25 |
| - print( |
26 |
| - f"Converting from {existing_wheel_file} to {new_wheel_file}", |
27 |
| - file=sys.stderr, |
28 |
| - ) |
29 |
| - |
30 |
| - # Walk the Zip writing files except the WHEEL file which we must alter the |
31 |
| - # tag on the WHEEL file |
32 |
| - with zipfile.ZipFile(new_wheel_file, "w") as zipwrite, zipfile.ZipFile( |
33 |
| - existing_wheel_file, "r" |
34 |
| - ) as zipread: |
35 |
| - found_wheel_tag = False |
36 |
| - for item in zipread.infolist(): |
37 |
| - data = zipread.read(item.filename) |
38 |
| - _, _, filename = item.filename.rpartition("/") |
39 |
| - # Change the WHEEL tag |
40 |
| - if filename == "WHEEL": |
41 |
| - lines = data.splitlines() |
42 |
| - for i in range(len(lines)): |
43 |
| - if lines[i].startswith(b"Tag: "): |
44 |
| - pieces = lines[i][len("Tag: ") :].split(b"-") |
45 |
| - if len(pieces) < 3: |
46 |
| - raise RuntimeError( |
47 |
| - "Expecting at least 3 wheel tag pieces" |
48 |
| - ) |
49 |
| - pieces[0] = b"cp37" |
50 |
| - pieces[1] = b"abi3" |
51 |
| - lines[i] = b"Tag: " + b"-".join(pieces) |
52 |
| - found_wheel_tag = True |
53 |
| - data = b"\n".join(lines) |
54 |
| - zipwrite.writestr(item, data) |
55 |
| - if not found_wheel_tag: |
56 |
| - raise RuntimeError("Did not find WHEEL file with tag entry") |
57 |
| - os.remove(existing_wheel_file) |
| 13 | + if len(dist_files) != 1: |
| 14 | + raise RuntimeError(f"Should have only one wheel file, found: {dist_files}") |
| 15 | + |
| 16 | + # Run unpack into temp directory |
| 17 | + if os.path.exists("dist/temp"): |
| 18 | + raise RuntimeError("dist/temp directory already present") |
| 19 | + subprocess.check_call(["wheel", "unpack", "--dest", "dist/temp", dist_files[0]]) |
| 20 | + |
| 21 | + # Read WHEEL contents |
| 22 | + wheel_files = glob("dist/temp/*/*.dist-info/WHEEL") |
| 23 | + if len(wheel_files) != 1: |
| 24 | + raise RuntimeError(f"Should have only one WHEEL file, found: {wheel_files}") |
| 25 | + with open(wheel_files[0]) as f: |
| 26 | + wheel_lines = f.read().splitlines() |
| 27 | + |
| 28 | + # Alter the "Tag" to use 3.7+ Python, ABI3 limited API, or if macOS ARM, |
| 29 | + # manually set as 11_0 w/ 3.8+ |
| 30 | + found_wheel_tag = False |
| 31 | + for i, line in enumerate(wheel_lines): |
| 32 | + if line.startswith("Tag: "): |
| 33 | + pieces = line[len("Tag: ") :].split("-") |
| 34 | + if len(pieces) < 3: |
| 35 | + raise RuntimeError("Expecting at least 3 wheel tag pieces") |
| 36 | + pieces[1] = "abi3" |
| 37 | + if pieces[2].startswith("macosx_") and pieces[2].endswith("_arm64"): |
| 38 | + pieces[0] = "cp38" |
| 39 | + pieces[2] = "macosx_11_0_arm64" |
| 40 | + else: |
| 41 | + pieces[0] = "cp37" |
| 42 | + wheel_lines[i] = "Tag: " + "-".join(pieces) |
| 43 | + found_wheel_tag = True |
| 44 | + break |
| 45 | + if not found_wheel_tag: |
| 46 | + raise RuntimeError("Could not find WHEEL tag") |
| 47 | + |
| 48 | + # Write the WHEEL file |
| 49 | + with open(wheel_files[0], "w") as f: |
| 50 | + f.write("\n".join(wheel_lines)) |
| 51 | + |
| 52 | + # Pack the wheel |
| 53 | + unpacked_dirs = glob("dist/temp/*") |
| 54 | + subprocess.check_call(["wheel", "pack", "--dest", "dist", unpacked_dirs[0]]) |
| 55 | + |
| 56 | + # Remove temp dir |
| 57 | + shutil.rmtree("dist/temp") |
| 58 | + |
| 59 | + # If there are multiple wheels now, remove the old one |
| 60 | + new_dist_files = glob("dist/*.whl") |
| 61 | + new_dist_files.remove(dist_files[0]) |
| 62 | + if new_dist_files: |
| 63 | + os.remove(dist_files[0]) |
| 64 | + print(f"Created wheel {new_dist_files[0]} from {dist_files[0]}") |
| 65 | + else: |
| 66 | + print(f"Overwrote wheel {dist_files[0]}") |
0 commit comments