From 1986f2953a0e1dda8abb42b9d8847308546f4ea6 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Tue, 25 Jul 2023 13:04:42 +0200 Subject: [PATCH] feat(core): resolve symlinks on file write Instead of using the passed filename as the rename target, use Path.resolve for resolving any symlinks. This allows to use symlinks for the nvchecker database files that point somewhere else. Before this commit nvchecker simply replaced the symlink with an actual file, now we resolve the targets first and only replace the actual file that is pointed to. Co-authored-by: Andreas 'Segaja' Schleifer Signed-off-by: Levente Polyak --- nvchecker/core.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/nvchecker/core.py b/nvchecker/core.py index 7875298..3c22f8b 100644 --- a/nvchecker/core.py +++ b/nvchecker/core.py @@ -110,11 +110,11 @@ def process_common_arguments(args: argparse.Namespace) -> bool: return True return False -def safe_overwrite(fname: str, data: Union[bytes, str], *, +def safe_overwrite(file: Path, data: Union[bytes, str], *, method: str = 'write', mode: str = 'w', encoding: Optional[str] = None) -> None: # FIXME: directory has no read perm - # FIXME: symlinks and hard links - tmpname = fname + '.tmp' + # FIXME: hard links + tmpname = str(file) + '.tmp' # if not using "with", write can fail without exception with open(tmpname, mode, encoding=encoding) as f: getattr(f, method)(data) @@ -122,7 +122,7 @@ def safe_overwrite(fname: str, data: Union[bytes, str], *, f.flush() os.fsync(f.fileno()) # if the above write failed (because disk is full etc), the old data should be kept - os.rename(tmpname, fname) + os.rename(tmpname, file.resolve()) def read_verfile(file: Path) -> VersData: try: @@ -149,7 +149,7 @@ def write_verfile(file: Path, versions: VersData) -> None: indent=2, ensure_ascii=False, ) + '\n' - safe_overwrite(str(file), data) + safe_overwrite(file, data) class Options(NamedTuple): ver_files: Optional[Tuple[Path, Path]]