Skip to content

Commit 8e5bc44

Browse files
authored
Preserve '/Scripts' when upgrading an install. (#171)
Fixes #170
1 parent 4e89c24 commit 8e5bc44

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

src/manage/install_command.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,14 @@ def _download_one(cmd, source, install, download_dir, *, must_copy=False):
458458
return package
459459

460460

461+
def _should_preserve_on_upgrade(cmd, root, path):
462+
if path.match("site-packages"):
463+
return True
464+
if path.parent == root and path.match("Scripts"):
465+
return True
466+
return False
467+
468+
461469
def _preserve_site(cmd, root):
462470
if not root.is_dir():
463471
return None
@@ -473,12 +481,12 @@ def _preserve_site(cmd, root):
473481
state = []
474482
i = 0
475483
dirs = [root]
476-
root = root.with_name(f"_{root.name}")
477-
root.mkdir(parents=True, exist_ok=True)
484+
target_root = root.with_name(f"_{root.name}")
485+
target_root.mkdir(parents=True, exist_ok=True)
478486
while dirs:
479-
if dirs[0].match("site-packages"):
487+
if _should_preserve_on_upgrade(cmd, root, dirs[0]):
480488
while True:
481-
target = root / str(i)
489+
target = target_root / str(i)
482490
i += 1
483491
try:
484492
unlink(target)
@@ -487,7 +495,12 @@ def _preserve_site(cmd, root):
487495
break
488496
except OSError:
489497
LOGGER.verbose("Failed to remove %s.", target)
490-
LOGGER.info("Preserving %s during update as %s.", dirs[0], target)
498+
try:
499+
LOGGER.info("Preserving %s during update.", dirs[0].relative_to(root))
500+
except ValueError:
501+
# Just in case a directory goes weird, so we don't break
502+
LOGGER.verbose(exc_info=True)
503+
LOGGER.verbose("Moving %s to %s", dirs[0], target)
491504
try:
492505
dirs[0].rename(target)
493506
except OSError:
@@ -498,8 +511,8 @@ def _preserve_site(cmd, root):
498511
else:
499512
dirs.extend(d for d in dirs[0].iterdir() if d.is_dir())
500513
dirs.pop(0)
501-
# Append None, root last so that root gets cleaned up after restore is done
502-
state.append((None, root))
514+
# Append None, target_root last to clean up after restore is done
515+
state.append((None, target_root))
503516
return state
504517

505518

@@ -520,7 +533,7 @@ def _restore_site(cmd, state):
520533
except KeyboardInterrupt:
521534
break
522535
continue
523-
LOGGER.info("Restoring %s from %s after update.", dest, src)
536+
LOGGER.verbose("Restoring %s from %s after update.", dest, src)
524537
try:
525538
for i in src.iterdir():
526539
if not i.is_dir() and not i.is_file():
@@ -534,6 +547,7 @@ def _restore_site(cmd, state):
534547
LOGGER.verbose("Restoring %s to %s", i, d)
535548
d.parent.mkdir(parents=True, exist_ok=True)
536549
i.rename(d)
550+
LOGGER.info("Restored %s", dest.name)
537551
except OSError:
538552
LOGGER.warn("Failed to restore %s during update.", dest)
539553
LOGGER.verbose("TRACEBACK", exc_info=True)

0 commit comments

Comments
 (0)