Skip to content

Commit f1ba182

Browse files
marvin1099Marvin1099
authored andcommitted
change create_symlink with type hints and error handling
Refactor create_symlink function to add type hints and enhance error handling for existing symlinks and files.
1 parent 65f0d31 commit f1ba182

1 file changed

Lines changed: 27 additions & 14 deletions

File tree

src/mainutils.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import sys
66
import pwd
77
import shutil
8+
import pathlib
89

910
from typing import (
1011
Callable,
@@ -321,8 +322,6 @@ def dereference_links() -> None:
321322
update_progress(int((i + 1) / total_links * 100))
322323

323324
def find_symlinks(path: str) -> List[List[str]]:
324-
import pathlib
325-
326325
links = []
327326
directory = pathlib.Path(path)
328327
for item in directory.rglob("*"):
@@ -408,8 +407,6 @@ def copy_folder_with_progress(
408407
log(f"ignoring: {ignore}\nincluding anyway: {include_override}")
409408

410409
def traverse_folders(path: str) -> List[str]:
411-
import pathlib
412-
413410
allf = []
414411
directory = pathlib.Path(path)
415412
for item in directory.rglob("*"):
@@ -685,13 +682,29 @@ def flatpakrunner():
685682
if os.path.isfile(flatpakrunfile):
686683
os.remove(flatpakrunfile)
687684

688-
# Safe symlink creation function
689-
# Yeeted from: https://zetcode.com/python/os-symlink/
690-
def create_symlink(src, dst):
691-
try:
692-
os.symlink(src, dst)
693-
except FileExistsError:
694-
if os.path.islink(dst):
695-
# Optionally update existing symlink
696-
os.remove(dst)
697-
os.symlink(src, dst)
685+
def create_symlink(src: Union[str, pathlib.Path], dst: Union[str, pathlib.Path], replace: Union[bool, None] = True) -> None:
686+
# Needs src, dest; replace can be True (replace all), None (replace only files and symlinks) or False (don't replace anything)
687+
src_path = pathlib.Path(src).resolve()
688+
dst_path = pathlib.Path(dst)
689+
690+
if not src_path.exists():
691+
raise FileNotFoundError(f"Source does not exist: {src_path}")
692+
693+
if dst_path.lexists(): # Handle existing destination, still true on broken symlinks
694+
if dst_path.is_symlink():
695+
if dst_path.resolve() == src_path: # Correct symlink – nothing to do
696+
return
697+
if replace is False: # Wrong target
698+
raise OSError(f"Symlink {dst_path} points to {dst_path.resolve()}, expected {src_path}")
699+
dst_path.unlink() # remove incorrect link
700+
else:
701+
if replace is False:
702+
raise OSError(f"{dst_path} exists and is not a symlink")
703+
elif dst_path.is_dir() and replace is None:
704+
raise OSError(f"{dst_path} exists and is not a file or symlink")
705+
if dst_path.is_dir():
706+
shutil.rmtree(dst_path) # delete whole directory tree
707+
else:
708+
dst_path.unlink() # delete regular file
709+
710+
os.symlink(src_path, dst_path) # Create link

0 commit comments

Comments
 (0)