14
14
15
15
import glob
16
16
import os
17
+ import platform
17
18
import shutil
18
19
import subprocess
19
20
import sys
20
21
import zipfile
21
22
from pathlib import Path
23
+ from typing import Dict, List
22
24
23
25
from setuptools import find_packages, setup
24
26
@@ -40,6 +42,23 @@ def extractall(zip: zipfile.ZipFile, path: str) -> None:
40
42
os.chmod(extracted_path, attr)
41
43
42
44
45
+ def download_driver(zip_name: str) -> None:
46
+ zip_file = f"playwright-{driver_version}-{zip_name}.zip"
47
+ if os.path.exists("driver/" + zip_file):
48
+ return
49
+ url = "https://playwright.azureedge.net/builds/driver/"
50
+ if (
51
+ "-alpha" in driver_version
52
+ or "-beta" in driver_version
53
+ or "-next" in driver_version
54
+ ):
55
+ url = url + "next/"
56
+ url = url + zip_file
57
+ print(f"Fetching {url}")
58
+ # Don't replace this with urllib - Python won't have certificates to do SSL on all platforms.
59
+ subprocess.check_call(["curl", url, "-o", "driver/" + zip_file])
60
+
61
+
43
62
class PlaywrightBDistWheelCommand(BDistWheelCommand):
44
63
user_options = BDistWheelCommand.user_options + [
45
64
("all", "a", "create wheels for all platforms")
@@ -57,90 +76,90 @@ def run(self) -> None:
57
76
super().run()
58
77
os.makedirs("driver", exist_ok=True)
59
78
os.makedirs("playwright/driver", exist_ok=True)
60
- if self.all:
61
- # If building for all platforms
62
- platform_map = {
63
- "darwin": [
64
- {
65
- "zip_name": "mac",
66
- "wheels": [
67
- "macosx_10_13_x86_64.whl",
68
- "macosx_11_0_universal2.whl",
69
- ],
70
- },
71
- {
72
- "zip_name": "mac-arm64",
73
- "wheels": [
74
- "macosx_11_0_arm64.whl",
75
- ],
76
- },
77
- ],
78
- "linux": [
79
- {"zip_name": "linux", "wheels": ["manylinux1_x86_64.whl"]},
80
- {
81
- "zip_name": "linux-arm64",
82
- "wheels": ["manylinux_2_17_aarch64.manylinux2014_aarch64.whl"],
83
- },
84
- ],
85
- "win32": [
86
- {
87
- "zip_name": "win32_x64",
88
- "wheels": ["win32.whl", "win_amd64.whl"],
89
- }
90
- ],
91
- }
92
- platforms = [*platform_map.values()]
93
- else:
94
- # If building for only current platform
95
- platform_map = {
96
- "darwin": [
97
- {
98
- "zip_name": "mac",
99
- "wheels": ["macosx_10_13_x86_64.whl"],
100
- },
101
- ],
102
- "linux": [{"zip_name": "linux", "wheels": ["manylinux1_x86_64.whl"]}],
103
- "win32": [
104
- {
105
- "zip_name": "win32_x64",
106
- "wheels": ["win_amd64.whl"],
107
- }
108
- ],
109
- }
110
- platforms = [platform_map[sys.platform]]
111
- for platform in platforms:
112
- for arch in platform:
113
- zip_file = f"playwright-{driver_version}-{arch['zip_name']}.zip"
114
- if not os.path.exists("driver/" + zip_file):
115
- url = f"https://playwright.azureedge.net/builds/driver/{zip_file}"
116
- print(f"Fetching {url}")
117
- # Don't replace this with urllib - Python won't have certificates to do SSL on all platforms.
118
- subprocess.check_call(["curl", url, "-o", "driver/" + zip_file])
119
- base_wheel_location = glob.glob(os.path.join(self.dist_dir, "*.whl"))[0]
120
- without_platform = base_wheel_location[:-7]
79
+ base_wheel_bundles: List[Dict[str, str]] = [
80
+ {
81
+ "wheel": "macosx_10_13_x86_64.whl",
82
+ "machine": "x86_64",
83
+ "platform": "darwin",
84
+ "zip_name": "mac",
85
+ },
86
+ {
87
+ "wheel": "macosx_11_0_universal2.whl",
88
+ "machine": "x86_64",
89
+ "platform": "darwin",
90
+ "zip_name": "mac",
91
+ },
92
+ {
93
+ "wheel": "macosx_11_0_arm64.whl",
94
+ "machine": "arm64",
95
+ "platform": "darwin",
96
+ "zip_name": "mac-arm64",
97
+ },
98
+ {
99
+ "wheel": "manylinux1_x86_64.whl",
100
+ "machine": "x86_64",
101
+ "platform": "linux",
102
+ "zip_name": "linux",
103
+ },
104
+ {
105
+ "wheel": "manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
106
+ "machine": "aarch64",
107
+ "platform": "linux",
108
+ "zip_name": "linux-arm64",
109
+ },
110
+ {
111
+ "wheel": "win32.whl",
112
+ "machine": "i386",
113
+ "platform": "win32",
114
+ "zip_name": "win32_x64",
115
+ },
116
+ {
117
+ "wheel": "win_amd64.whl",
118
+ "machine": "amd64",
119
+ "platform": "win32",
120
+ "zip_name": "win32_x64",
121
+ },
122
+ ]
123
+ self._download_and_extract_local_driver(base_wheel_bundles)
121
124
122
- for platform in platforms:
123
- for arch in platform:
124
- zip_file = f"driver/playwright-{driver_version}-{arch['zip_name']}.zip"
125
- with zipfile.ZipFile(zip_file, "r") as zip:
126
- extractall(zip, f"driver/{arch['zip_name']}")
127
- if platform_map[sys.platform][0] in platform:
128
- with zipfile.ZipFile(zip_file, "r") as zip:
129
- extractall(zip, "playwright/driver")
130
- for wheel in arch["wheels"]:
131
- wheel_location = without_platform + wheel
132
- shutil.copy(base_wheel_location, wheel_location)
133
- with zipfile.ZipFile(wheel_location, "a") as zip:
134
- driver_root = os.path.abspath(f"driver/{arch['zip_name']}")
135
- for dir_path, _, files in os.walk(driver_root):
136
- for file in files:
137
- from_path = os.path.join(dir_path, file)
138
- to_path = os.path.relpath(from_path, driver_root)
139
- zip.write(from_path, f"playwright/driver/{to_path}")
140
- zip.writestr(
141
- "playwright/driver/README.md", f"{wheel} driver package"
142
- )
125
+ wheels = base_wheel_bundles
126
+ if not self.all:
127
+ # Limit to 1, since for MacOS e.g. we have multiple wheels for the same platform and architecture and Conda expects 1.
128
+ wheels = list(
129
+ filter(
130
+ lambda wheel: wheel["platform"] == sys.platform
131
+ and wheel["machine"] == platform.machine().lower(),
132
+ base_wheel_bundles,
133
+ )
134
+ )[:1]
135
+ self._build_wheels(wheels)
143
136
137
+ def _build_wheels(
138
+ self,
139
+ wheels: List[Dict[str, str]],
140
+ ) -> None:
141
+ base_wheel_location: str = glob.glob(os.path.join(self.dist_dir, "*.whl"))[0]
142
+ without_platform = base_wheel_location[:-7]
143
+ for wheel_bundle in wheels:
144
+ download_driver(wheel_bundle["zip_name"])
145
+ zip_file = (
146
+ f"driver/playwright-{driver_version}-{wheel_bundle['zip_name']}.zip"
147
+ )
148
+ with zipfile.ZipFile(zip_file, "r") as zip:
149
+ extractall(zip, f"driver/{wheel_bundle['zip_name']}")
150
+ wheel_location = without_platform + wheel_bundle["wheel"]
151
+ shutil.copy(base_wheel_location, wheel_location)
152
+ with zipfile.ZipFile(wheel_location, "a") as zip:
153
+ driver_root = os.path.abspath(f"driver/{wheel_bundle['zip_name']}")
154
+ for dir_path, _, files in os.walk(driver_root):
155
+ for file in files:
156
+ from_path = os.path.join(dir_path, file)
157
+ to_path = os.path.relpath(from_path, driver_root)
158
+ zip.write(from_path, f"playwright/driver/{to_path}")
159
+ zip.writestr(
160
+ "playwright/driver/README.md",
161
+ f"{wheel_bundle['wheel']} driver package",
162
+ )
144
163
os.remove(base_wheel_location)
145
164
if InWheel:
146
165
for whlfile in glob.glob(os.path.join(self.dist_dir, "*.whl")):
@@ -156,6 +175,27 @@ def run(self) -> None:
156
175
else:
157
176
print("auditwheel not installed, not updating RECORD file")
158
177
178
+ def _download_and_extract_local_driver(
179
+ self,
180
+ wheels: List[Dict[str, str]],
181
+ ) -> None:
182
+ zip_names_for_current_system = set(
183
+ map(
184
+ lambda wheel: wheel["zip_name"],
185
+ filter(
186
+ lambda wheel: wheel["machine"] == platform.machine().lower()
187
+ and wheel["platform"] == sys.platform,
188
+ wheels,
189
+ ),
190
+ )
191
+ )
192
+ assert len(zip_names_for_current_system) == 1
193
+ zip_name = zip_names_for_current_system.pop()
194
+ download_driver(zip_name)
195
+ zip_file = f"driver/playwright-{driver_version}-{zip_name}.zip"
196
+ with zipfile.ZipFile(zip_file, "r") as zip:
197
+ extractall(zip, "playwright/driver")
198
+
159
199
160
200
setup(
161
201
name="playwright",
0 commit comments