Skip to content

Commit 32158ea

Browse files
[3.13] gh-130025: Correct handling of symlinks during iOS testbed framework installation. (GH-130026) (#130073)
Correct handling of symlinks during iOS testbed framework installation. (cherry picked from commit 625470a) Co-authored-by: Russell Keith-Magee <[email protected]>
1 parent a76aff6 commit 32158ea

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The iOS testbed now correctly handles symlinks used as Python framework
2+
references.

iOS/testbed/__main__.py

+45-9
Original file line numberDiff line numberDiff line change
@@ -230,33 +230,69 @@ def clone_testbed(
230230
shutil.copytree(source, target, symlinks=True)
231231
print(" done")
232232

233+
xc_framework_path = target / "Python.xcframework"
234+
sim_framework_path = xc_framework_path / "ios-arm64_x86_64-simulator"
233235
if framework is not None:
234236
if framework.suffix == ".xcframework":
235237
print(" Installing XCFramework...", end="", flush=True)
236-
xc_framework_path = (target / "Python.xcframework").resolve()
237238
if xc_framework_path.is_dir():
238239
shutil.rmtree(xc_framework_path)
239240
else:
240-
xc_framework_path.unlink()
241+
xc_framework_path.unlink(missing_ok=True)
241242
xc_framework_path.symlink_to(
242243
framework.relative_to(xc_framework_path.parent, walk_up=True)
243244
)
244245
print(" done")
245246
else:
246247
print(" Installing simulator framework...", end="", flush=True)
247-
sim_framework_path = (
248-
target / "Python.xcframework" / "ios-arm64_x86_64-simulator"
249-
).resolve()
250248
if sim_framework_path.is_dir():
251249
shutil.rmtree(sim_framework_path)
252250
else:
253-
sim_framework_path.unlink()
251+
sim_framework_path.unlink(missing_ok=True)
254252
sim_framework_path.symlink_to(
255253
framework.relative_to(sim_framework_path.parent, walk_up=True)
256254
)
257255
print(" done")
258256
else:
259-
print(" Using pre-existing iOS framework.")
257+
if (
258+
xc_framework_path.is_symlink()
259+
and not xc_framework_path.readlink().is_absolute()
260+
):
261+
# XCFramework is a relative symlink. Rewrite the symlink relative
262+
# to the new location.
263+
print(" Rewriting symlink to XCframework...", end="", flush=True)
264+
orig_xc_framework_path = (
265+
source
266+
/ xc_framework_path.readlink()
267+
).resolve()
268+
xc_framework_path.unlink()
269+
xc_framework_path.symlink_to(
270+
orig_xc_framework_path.relative_to(
271+
xc_framework_path.parent, walk_up=True
272+
)
273+
)
274+
print(" done")
275+
elif (
276+
sim_framework_path.is_symlink()
277+
and not sim_framework_path.readlink().is_absolute()
278+
):
279+
print(" Rewriting symlink to simulator framework...", end="", flush=True)
280+
# Simulator framework is a relative symlink. Rewrite the symlink
281+
# relative to the new location.
282+
orig_sim_framework_path = (
283+
source
284+
/ "Python.XCframework"
285+
/ sim_framework_path.readlink()
286+
).resolve()
287+
sim_framework_path.unlink()
288+
sim_framework_path.symlink_to(
289+
orig_sim_framework_path.relative_to(
290+
sim_framework_path.parent, walk_up=True
291+
)
292+
)
293+
print(" done")
294+
else:
295+
print(" Using pre-existing iOS framework.")
260296

261297
for app_src in apps:
262298
print(f" Installing app {app_src.name!r}...", end="", flush=True)
@@ -372,8 +408,8 @@ def main():
372408

373409
if context.subcommand == "clone":
374410
clone_testbed(
375-
source=Path(__file__).parent,
376-
target=Path(context.location),
411+
source=Path(__file__).parent.resolve(),
412+
target=Path(context.location).resolve(),
377413
framework=Path(context.framework).resolve() if context.framework else None,
378414
apps=[Path(app) for app in context.apps],
379415
)

0 commit comments

Comments
 (0)