Files
link-fixer/swap_link.py

47 lines
1.5 KiB
Python

# swap_link.py
# Replace a link file with another one pointing to a new target
#
from pathlib import Path
from os.path import relpath # won't be necessary with Python 3.12 thanks to walk_up arg in relative_to()
def swap_link(lnk, tgt):
#lnk: symbolic link to swap, str
#tgt: target for new link, str
lnpath = Path(lnk)
if not lnpath.is_symlink():
raise Exception("First argument is not a symbolic link")
elif lnpath.exists():
raise Exception("Link is not broken")
tpath = Path(tgt)
if tpath.is_symlink():
if not tpath.exists():
raise Exception("Target is also a broken link!")
elif tpath.readlink().resolve() == lnpath.resolve() :
raise Exception("Target is a link to link to be fixed...")
tmp_suffix = 0
tmp_prefix = 'temp'
tmp_name = tmp_prefix + str(tmp_suffix)
tmp_path = Path(lnpath.parent / tmp_name)
while tmp_path.exists() or tmp_path.is_symlink():
tmp_suffix += 1
tmp_name = tmp_prefix + str(tmp_suffix)
tmp_path = Path(lnk.parent / tmp_name)
sym_path = relpath(tgt, lnk)[3:]
try:
tmp_path.symlink_to(sym_path)
except Exception:
print(f"Attempted to create tmp link: {tmp_name}")
raise Exception("Failed to create new symlink. Check permissions!")
try:
lnpath.unlink()
except Exception:
tmp_path.unlink()
raise Exception("Failed to remove broken link. Check permissions!")
tmp_path.rename(lnk)