diff --git a/package_control/package_cleanup.py b/package_control/package_cleanup.py index 1c24842d..bc3b0a5e 100644 --- a/package_control/package_cleanup.py +++ b/package_control/package_cleanup.py @@ -387,50 +387,20 @@ def install_missing_packages(self, found_packages): return installed_packages = self.manager.installed_packages() - missing_packages = installed_packages - found_packages - if not missing_packages: - return - - # Fetch a list of available (and renamed) packages and abort - # if there are none available for installation. - # An empty list indicates connection or configuration problems. - available_packages = set(self.manager.list_available_packages()) - if not available_packages: - return - # Detect renamed packages and prepare batched install with new names. - # Update `installed_packages` setting to remove old names without loosing something - # in case installation fails. - renamed_packages = self.manager.settings.get('renamed_packages', {}) - renamed_packages = {renamed_packages.get(p, p) for p in missing_packages} - if renamed_packages != missing_packages: - self.manager.update_installed_packages(add=renamed_packages, remove=missing_packages) - - # Make sure not to overwrite existing packages after renaming is applied. - missing_packages = renamed_packages - found_packages - if not missing_packages: - return - - console_write( - 'Installing %s missing package%s...', - (len(missing_packages), 's' if len(missing_packages) != 1 else '') + tasks = self.create_package_tasks( + actions=(self.INSTALL, self.OVERWRITE), + include_packages=installed_packages, + found_packages=found_packages ) - - reenable_packages = self.disable_packages({self.INSTALL: missing_packages}) - time.sleep(0.7) - - try: - for package_name in missing_packages: - result = self.manager.install_package(package_name) - - # re-enable if upgrade is not deferred to next start - if result is None and package_name in reenable_packages: - reenable_packages.remove(package_name) - - finally: - if reenable_packages: - time.sleep(0.7) - self.reenable_packages({self.INSTALL: reenable_packages}) + if tasks: + self.run_install_tasks(tasks, package_kind='missing') + + # Drop remaining missing packages, which seem no longer available upstream, + # to avoid trying again and again each time ST starts. + missing_packages = installed_packages - set(self.manager.list_packages()) + if missing_packages: + self.manager.update_installed_packages(remove=missing_packages) def remove_orphaned_packages(self, found_packages): """ diff --git a/package_control/package_tasks.py b/package_control/package_tasks.py index eeb0cb96..98d97933 100644 --- a/package_control/package_tasks.py +++ b/package_control/package_tasks.py @@ -275,7 +275,7 @@ def remove_packages(self, packages, progress=None, package_kind=''): time.sleep(0.7) self.reenable_packages({self.REMOVE: packages - deffered}) - def run_install_tasks(self, tasks, progress=None): + def run_install_tasks(self, tasks, progress=None, package_kind=''): """ Execute specified package install tasks @@ -284,13 +284,20 @@ def run_install_tasks(self, tasks, progress=None): :param progress: An ``ActivityIndicator`` object to use for status information. + + :param package_kind: + A unicode string with an additional package attribute. + (e.g.: `missing`, ...) """ + if package_kind: + package_kind += ' ' + num_packages = len(tasks) if num_packages == 1: - message = 'Installing package {}'.format(tasks[0].package_name) + message = 'Installing {}package {}'.format(package_kind, tasks[0].package_name) else: - message = 'Installing {} packages...'.format(num_packages) + message = 'Installing {} {}packages...'.format(num_packages, package_kind) console_write(message) if progress: @@ -306,7 +313,7 @@ def run_install_tasks(self, tasks, progress=None): try: for task in tasks: if progress: - progress.set_label('Installing package {}'.format(task.package_name)) + progress.set_label('Installing {}package {}'.format(package_kind, task.package_name)) result = self.manager.install_package(task.package_name) if result is True: num_success += 1 @@ -317,10 +324,11 @@ def run_install_tasks(self, tasks, progress=None): if num_packages == 1: message = 'Package {} successfully installed'.format(tasks[0].package_name) elif num_packages == num_success: - message = 'All packages successfully installed' + message = 'All {}packages successfully installed'.format(package_kind) console_write(message) else: - message = '{} of {} packages successfully installed'.format(num_success, num_packages) + message = '{} of {} {}packages successfully installed'.format( + num_success, num_packages, package_kind) console_write(message) if progress: @@ -417,7 +425,7 @@ def run_upgrade_tasks(self, tasks, progress=None): return update_completed - def create_package_tasks(self, actions, include_packages=None, ignore_packages=None): + def create_package_tasks(self, actions, include_packages=None, ignore_packages=None, found_packages=None): """ Makes tasks. @@ -436,6 +444,11 @@ def create_package_tasks(self, actions, include_packages=None, ignore_packages=N :param ignore_packages: A list/set of package names that should not be returned in the list + :param found_packages: + A list/set of package names found on filesystem to be used for task creation. + It primarily exists to re-use existing data for optimization purposes. + If ``None`` is provided, a list is created internally. + :return: A list of ``PackageInstallTask`` objects on success. ``False``, if no packages are available upstream, most likely a connection error. @@ -447,7 +460,8 @@ def create_package_tasks(self, actions, include_packages=None, ignore_packages=N if not available_packages: return False - found_packages = self.manager.list_packages() + if found_packages is None: + found_packages = self.manager.list_packages() renamed_packages = self.manager.settings.get('renamed_packages', {}) # VCS package updates