mirror of
https://github.com/cft0808/edict.git
synced 2026-09-03 07:17:16 +08:00
fix: prevent self-referential symlinks in sync_scripts_to_workspaces
When install.sh link_resources() creates workspace-*/scripts as a
directory-level symlink pointing to the project scripts/ dir, iterating
over it in sync_scripts_to_workspaces() produces dst_file paths that
resolve to the same real file as src_file.
The old idempotency check only skipped when dst_file itself was already a
symlink:
if dst_file.is_symlink() and dst_file.resolve() == src_resolved:
return False
For a workspace whose scripts/ directory is a symlink-to-directory,
dst_file appears as a regular file (is_symlink() == False), so the check
passes, the real source file is unlinked, and os.symlink() re-creates it
as a self-referential link (foo.py -> foo.py). Running run_loop.sh every
15 s makes the whole scripts/ directory unusable within one cycle.
Fix: resolve dst_file before any other check and bail out early when
dst_resolved == src_resolved, regardless of whether dst_file itself is
stored as a symlink entry.
This commit is contained in:
@@ -222,8 +222,19 @@ def _sync_script_symlink(src_file: pathlib.Path, dst_file: pathlib.Path) -> bool
|
||||
Returns True if the link was (re-)created, False if already up-to-date.
|
||||
"""
|
||||
src_resolved = src_file.resolve()
|
||||
# Guard: skip if dst resolves to the same real path as src.
|
||||
# This happens when ws_scripts is itself a directory-level symlink pointing
|
||||
# to the project scripts/ dir (created by install.sh link_resources).
|
||||
# Without this check the function would unlink the real source file and
|
||||
# then create a self-referential symlink (foo.py -> foo.py).
|
||||
try:
|
||||
dst_resolved = dst_file.resolve()
|
||||
except OSError:
|
||||
dst_resolved = None
|
||||
if dst_resolved == src_resolved:
|
||||
return False
|
||||
# Already a correct symlink?
|
||||
if dst_file.is_symlink() and dst_file.resolve() == src_resolved:
|
||||
if dst_file.is_symlink() and dst_resolved == src_resolved:
|
||||
return False
|
||||
# Remove stale file / old physical copy / broken symlink
|
||||
if dst_file.exists() or dst_file.is_symlink():
|
||||
|
||||
Reference in New Issue
Block a user