fix to updating deleting plugins and replacing all files
This commit is contained in:
1 parent
8270d7b7a8
commit
9ecafe09ac
2 files changed
+90
-2
No files matched your search
@@ -311,7 +311,6 @@ script_dir = os.path.dirname(os.path.abspath(__file__))
|
|||||||
os.chdir(script_dir)
|
os.chdir(script_dir)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Configure logging with rotation to prevent indefinite growth
|
# Configure logging with rotation to prevent indefinite growth
|
||||||
if PLATFORM_NAME == 'darwin':
|
if PLATFORM_NAME == 'darwin':
|
||||||
log_path = os.path.abspath(os.path.join(os.path.dirname(sys.executable), "../../../fnirs_analysis.log"))
|
log_path = os.path.abspath(os.path.join(os.path.dirname(sys.executable), "../../../fnirs_analysis.log"))
|
||||||
|
|||||||
+90
-1
@@ -462,6 +462,88 @@ def _remove_readonly(func: Callable[[str], Any], path: str, exc: Any) -> None:
|
|||||||
func(path)
|
func(path)
|
||||||
|
|
||||||
|
|
||||||
|
def files_are_identical(src_path: str, dst_path: str) -> bool:
|
||||||
|
"""
|
||||||
|
Check if two files are identical by comparing size and modification time.
|
||||||
|
|
||||||
|
This is much faster than hashing and catches all real changes for update purposes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
src_path (str): Path to source file.
|
||||||
|
dst_path (str): Path to destination file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if files are identical, False otherwise.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if not os.path.exists(src_path) or not os.path.exists(dst_path):
|
||||||
|
return False
|
||||||
|
|
||||||
|
src_stat = os.stat(src_path)
|
||||||
|
dst_stat = os.stat(dst_path)
|
||||||
|
|
||||||
|
# Compare size first
|
||||||
|
if src_stat.st_size != dst_stat.st_size:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Compare modification time (rounded to 1 second to handle cross-platform differences)
|
||||||
|
src_mtime = int(src_stat.st_mtime)
|
||||||
|
dst_mtime = int(dst_stat.st_mtime)
|
||||||
|
|
||||||
|
return src_mtime == dst_mtime
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def smart_replace_folder(source_dir: str, dest_dir: str) -> Tuple[int, int]:
|
||||||
|
"""
|
||||||
|
Replace files in dest_dir with files from source_dir, but only if they differ.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
source_dir (str): Source directory containing new files.
|
||||||
|
dest_dir (str): Destination directory to update.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[int, int]: (files_updated, files_skipped) counts.
|
||||||
|
"""
|
||||||
|
files_updated = 0
|
||||||
|
files_skipped = 0
|
||||||
|
|
||||||
|
for root, dirs, files in os.walk(source_dir):
|
||||||
|
relative_path = os.path.relpath(root, source_dir)
|
||||||
|
dest_root = os.path.join(dest_dir, relative_path)
|
||||||
|
|
||||||
|
# Create directory if it doesn't exist
|
||||||
|
if not os.path.exists(dest_root):
|
||||||
|
os.makedirs(dest_root)
|
||||||
|
|
||||||
|
for filename in files:
|
||||||
|
src_file = os.path.join(root, filename)
|
||||||
|
dst_file = os.path.join(dest_root, filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Skip if file is identical
|
||||||
|
if files_are_identical(src_file, dst_file):
|
||||||
|
files_skipped += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Remove destination if it exists (handles locked files on some systems)
|
||||||
|
if os.path.exists(dst_file):
|
||||||
|
if os.path.isdir(dst_file):
|
||||||
|
shutil.rmtree(dst_file, onexc=_remove_readonly)
|
||||||
|
else:
|
||||||
|
os.remove(dst_file)
|
||||||
|
|
||||||
|
# Copy the file
|
||||||
|
shutil.copy2(src_file, dst_file)
|
||||||
|
files_updated += 1
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f" Warning: Failed to update {filename}: {e}")
|
||||||
|
|
||||||
|
return files_updated, files_skipped
|
||||||
|
|
||||||
|
|
||||||
def finish_update_if_needed(platform_name: str, app_name: str, cfg_path: str, finish_update: bool) -> None:
|
def finish_update_if_needed(platform_name: str, app_name: str, cfg_path: str, finish_update: bool) -> None:
|
||||||
"""
|
"""
|
||||||
Completes a pending application update if '--finish-update' is present in the command-line arguments.
|
Completes a pending application update if '--finish-update' is present in the command-line arguments.
|
||||||
@@ -565,7 +647,14 @@ def finish_update_if_needed(platform_name: str, app_name: str, cfg_path: str, fi
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to replace {app_name}_updater: {e}")
|
print(f"Failed to replace {app_name}_updater: {e}")
|
||||||
|
|
||||||
# 5. Clean up all temporary update folders (with retries for Windows file locks)
|
# 5. Use smart replacement - only update files that have changed
|
||||||
|
print("Using smart update: only replacing files that have changed...")
|
||||||
|
files_updated, files_skipped = smart_replace_folder(target_updater_folder, target_base)
|
||||||
|
print(f"\nUpdate summary:")
|
||||||
|
print(f" Files updated: {files_updated}")
|
||||||
|
print(f" Files skipped (unchanged): {files_skipped}")
|
||||||
|
|
||||||
|
# 6. Clean up all temporary update folders (with retries for Windows file locks)
|
||||||
for folder in update_folders:
|
for folder in update_folders:
|
||||||
for attempt in range(3):
|
for attempt in range(3):
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in new issue
Block a user