Skip to content

Commit

Permalink
Move package to Trash if removal is rejected by OS
Browse files Browse the repository at this point in the history
Fixes #1418

This commit sends removed packages to "Trash", if their file is still locked
by Windows OS. That's most likely caused by external processes interacting with
that file, which may be anti-virus programs or Sublime Merge holding a lock due
to using the package. Renaming triggers unloading and thus frees the lock.
Trash is cleared at next ST startup.

That's basically the same strategy used to remove libraries.
  • Loading branch information
deathaxe committed Nov 26, 2023
1 parent d9a04f6 commit 70ba78f
Showing 1 changed file with 25 additions and 10 deletions.
35 changes: 25 additions & 10 deletions package_control/package_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def __init__(self):

self._available_packages = None
self._available_libraries = None
self.session_time = datetime.datetime.now()

self.settings = {}
settings = sublime.load_settings(pc_settings_filename())
Expand Down Expand Up @@ -1987,16 +1988,30 @@ def delete_package(self, package_name):
if can_delete_file:
try:
os.remove(package_file)
except (OSError, IOError) as e:
if self.settings.get('debug'):
console_write(
'''
Unable to remove package "%s" -
deferring until next start: %s
''',
(package_name, e)
except OSError:
try:
trash_path = sys_path.trash_path()
os.makedirs(trash_path, exist_ok=True)
# Try to move file to "Trash" directory.
# Required for e.g. Sublime Merge to unload the package and unlock the file.
# Note: Locked files on Windows OS can still be renamed.
trash_path = os.path.join(
trash_path,
hashlib.sha1(
(str(self.session_time) + package_file).encode('utf-8')
).hexdigest().lower()
)
result = None
os.rename(package_file, trash_path)
except OSError as e:
if self.settings.get('debug'):
console_write(
'''
Unable to remove package "%s" -
deferring until next start: %s
''',
(package_name, e)
)
result = None

if can_delete_dir:
if not self.backup_package_dir(package_name):
Expand Down Expand Up @@ -2041,7 +2056,7 @@ def backup_package_dir(self, package_name):
return True

backup_dir = os.path.join(
sys_path.data_path(), 'Backup', datetime.datetime.now().strftime('%Y%m%d%H%M%S')
sys_path.data_path(), 'Backup', self.session_time.strftime('%Y%m%d%H%M%S')
)
package_backup_dir = os.path.join(backup_dir, package_name)

Expand Down

0 comments on commit 70ba78f

Please sign in to comment.