mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-09-10 12:01:47 +02:00
fix(agents): preserve existing rules during symlink installation
This commit is contained in:
+18
-3
@@ -2,6 +2,7 @@
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -12,10 +13,24 @@ def install_one(target_dir: Path, source_file: Path, target_name: str) -> None:
|
||||
|
||||
target_file = target_dir / target_name
|
||||
|
||||
if target_file.exists() or target_file.is_symlink():
|
||||
target_file.unlink()
|
||||
if target_file.is_file() and not target_file.is_symlink():
|
||||
# Preserve the old inode without reading its contents or replacing an earlier backup.
|
||||
index = 0
|
||||
while True:
|
||||
suffix = ".bak" if index == 0 else f".bak.{index}"
|
||||
backup = target_file.with_name(target_file.name + suffix)
|
||||
try:
|
||||
os.link(target_file, backup)
|
||||
break
|
||||
except FileExistsError:
|
||||
index += 1
|
||||
print(f"backed up {target_file} -> {backup}")
|
||||
|
||||
target_file.symlink_to(source_file)
|
||||
# Create the link on the same filesystem before atomically replacing the destination.
|
||||
with tempfile.TemporaryDirectory(prefix=".install-rules-", dir=target_dir) as staging:
|
||||
link = Path(staging) / target_name
|
||||
link.symlink_to(source_file)
|
||||
link.replace(target_file)
|
||||
print(f"linked {target_file} -> {source_file}")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user