def _background_bootstrap(settings): """ Runs the bootstrap process in a thread since it may need to block to update the package control loader :param settings: A dict of settings """ base_loader_code = """ import sys import os from os.path import dirname # This file adds the package_control subdirectory of Package Control # to first in the sys.path so that all other packages may rely on # PC for utility functions, such as event helpers, adding things to # sys.path, downloading files from the internet, etc if sys.version_info >= (3,): def decode(path): return path def encode(path): return path loader_dir = dirname(__file__) else: def decode(path): if not isinstance(path, unicode): path = path.decode(sys.getfilesystemencoding()) return path def encode(path): if isinstance(path, unicode): path = path.encode(sys.getfilesystemencoding()) return path loader_dir = decode(os.getcwd()) st_dir = dirname(dirname(loader_dir)) found = False if sys.version_info >= (3,): installed_packages_dir = os.path.join(st_dir, u'Installed Packages') pc_package_path = os.path.join(installed_packages_dir, u'Package Control.sublime-package') if os.path.exists(encode(pc_package_path)): found = True if not found: packages_dir = os.path.join(st_dir, u'Packages') pc_package_path = os.path.join(packages_dir, u'Package Control') if os.path.exists(encode(pc_package_path)): found = True if found: if os.name == 'nt': from ctypes import windll, create_unicode_buffer buf = create_unicode_buffer(512) if windll.kernel32.GetShortPathNameW(pc_package_path, buf, len(buf)): pc_package_path = buf.value sys.path.insert(0, encode(pc_package_path)) import package_control # We remove the import path right away so as not to screw up # Sublime Text and its import machinery sys.path.remove(encode(pc_package_path)) else: print(u'Package Control: Error finding main directory from loader') """ base_loader_code = dedent(base_loader_code).lstrip() loader.add_or_update('00', 'package_control', base_loader_code) # SSL support fo Linux if sublime.platform() == 'linux' and int(sublime.version()) < 3109: linux_ssl_url = u'http://packagecontrol.io/ssl/1.0.1/ssl-linux.sublime-package' linux_ssl_hash = u'862d061cbe666777cd1e9cd1cbc7c82f48ad8897dbb68332975f3edf5ce0f38d' linux_ssl_priority = u'01' linux_ssl_version = '1.0.1' def linux_ssl_show_restart(): sublime.message_dialog( text.format(u''' Package Control Package Control just installed or upgraded the missing Python _ssl module for Linux since Sublime Text does not include it. Please restart Sublime Text to make SSL available to all packages. ''')) threading.Thread(target=bootstrap_dependency, args=( settings, linux_ssl_url, linux_ssl_hash, linux_ssl_priority, linux_ssl_version, linux_ssl_show_restart, )).start() # SSL support for SHA-2 certificates with ST2 on Windows elif sublime.platform() == 'windows' and sys.version_info < (3, ): win_ssl_url = u'http://packagecontrol.io/ssl/1.0.0/ssl-windows.sublime-package' win_ssl_hash = u'3c28982eb400039cfffe53d38510556adead39ba7321f2d15a6770d3ebc75030' win_ssl_priority = u'01' win_ssl_version = u'1.0.0' def win_ssl_show_restart(): sublime.message_dialog( text.format(u''' Package Control Package Control just upgraded the Python _ssl module for ST2 on Windows because the bundled one does not include support for modern SSL certificates. Please restart Sublime Text to complete the upgrade. ''')) threading.Thread(target=bootstrap_dependency, args=( settings, win_ssl_url, win_ssl_hash, win_ssl_priority, win_ssl_version, win_ssl_show_restart, )).start() else: sublime.set_timeout(mark_bootstrapped, 10)
def _background_bootstrap(settings): """ Runs the bootstrap process in a thread since it may need to block to update the package control loader :param settings: A dict of settings """ base_loader_code = """ import sys import os from os.path import dirname # This file adds the package_control subdirectory of Package Control # to first in the sys.path so that all other packages may rely on # PC for utility functions, such as event helpers, adding things to # sys.path, downloading files from the internet, etc if sys.version_info >= (3,): def decode(path): return path def encode(path): return path loader_dir = dirname(__file__) else: def decode(path): if not isinstance(path, unicode): path = path.decode(sys.getfilesystemencoding()) return path def encode(path): if isinstance(path, unicode): path = path.encode(sys.getfilesystemencoding()) return path loader_dir = decode(os.getcwd()) st_dir = dirname(dirname(loader_dir)) found = False if sys.version_info >= (3,): installed_packages_dir = os.path.join(st_dir, u'Installed Packages') pc_package_path = os.path.join(installed_packages_dir, u'Package Control.sublime-package') if os.path.exists(encode(pc_package_path)): found = True if not found: packages_dir = os.path.join(st_dir, u'Packages') pc_package_path = os.path.join(packages_dir, u'Package Control') if os.path.exists(encode(pc_package_path)): found = True if found: if os.name == 'nt': from ctypes import windll, create_unicode_buffer buf = create_unicode_buffer(512) if windll.kernel32.GetShortPathNameW(pc_package_path, buf, len(buf)): pc_package_path = buf.value sys.path.insert(0, encode(pc_package_path)) import package_control # We remove the import path right away so as not to screw up # Sublime Text and its import machinery sys.path.remove(encode(pc_package_path)) else: print(u'Package Control: Error finding main directory from loader') """ base_loader_code = dedent(base_loader_code).lstrip() loader.add_or_update('00', 'package_control', base_loader_code) # SSL support fo Linux if sublime.platform() == 'linux' and int(sublime.version()) < 3109: linux_ssl_url = u'http://packagecontrol.io/ssl/1.0.2/ssl-linux.sublime-package' linux_ssl_hash = u'23f35f64458a0a14c99b1bb1bbc3cb04794c7361c4940e0a638d40f038acd377' linux_ssl_priority = u'01' linux_ssl_version = '1.0.2' def linux_ssl_show_restart(): sublime.message_dialog(text.format( u''' Package Control Package Control just installed or upgraded the missing Python _ssl module for Linux since Sublime Text does not include it. Please restart Sublime Text to make SSL available to all packages. ''' )) threading.Thread( target=bootstrap_dependency, args=( settings, linux_ssl_url, linux_ssl_hash, linux_ssl_priority, linux_ssl_version, linux_ssl_show_restart, ) ).start() # SSL support for SHA-2 certificates with ST2 on Windows elif sublime.platform() == 'windows' and sys.version_info < (3,): win_ssl_url = u'http://packagecontrol.io/ssl/1.0.0/ssl-windows.sublime-package' win_ssl_hash = u'3c28982eb400039cfffe53d38510556adead39ba7321f2d15a6770d3ebc75030' win_ssl_priority = u'01' win_ssl_version = u'1.0.0' def win_ssl_show_restart(): sublime.message_dialog(text.format( u''' Package Control Package Control just upgraded the Python _ssl module for ST2 on Windows because the bundled one does not include support for modern SSL certificates. Please restart Sublime Text to complete the upgrade. ''' )) threading.Thread( target=bootstrap_dependency, args=( settings, win_ssl_url, win_ssl_hash, win_ssl_priority, win_ssl_version, win_ssl_show_restart, ) ).start() else: sublime.set_timeout(mark_bootstrapped, 10)
def _background_bootstrap(settings): """ Runs the bootstrap process in a thread since it may need to block to update the PackagesManager loader :param settings: A dict of settings """ reenable_package_code = r""" #!/usr/bin/env python3 # -*- coding: UTF-8 -*- ####################### Licensing ####################################################### # # PackagesManager, Re-enabler Utility # Copyright (C) 2018 Evandro Coan <https://github.com/evandrocoan> # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the # following disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials # provided with the distribution. # # Neither the name Evandro Coan nor the names of any # contributors may be used to endorse or promote products # derived from this software without specific prior written # permission. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation; either version 3 of the License, or ( at # your option ) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # ######################################################################################### # ''' Reenable PackagesManager, if it was disabled during its own update and get lost. This has no effect if the user disabled PackagesManager by himself because this program only takes effect when PackagesManager is disabled and is inserted on the PackagesManager `in_process_packages` setting. And the setting `in_process_packages` is only set by PackagesManager, when its starts updating some package. See the issue: 1. https://github.com/wbond/package_control/issues/1164 Create a dummy package that can re-enable Package Control if ST was restarted during a Package Control update ''' import sublime import os import random import time import stat import shutil import threading SUBLIME_SETTING_NAME = "Preferences" PACKAGESMANAGER_NAME = "{manager}" THIS_SCRIPT_PATH = os.path.realpath( __file__ ) PACKAGE_ROOT_DIRECTORY = os.path.dirname( os.path.realpath( __file__ ) ) PACKAGESMANAGER_ROOT_DIRECTORY = os.path.join( os.path.dirname( os.path.realpath( __file__ ) ), PACKAGESMANAGER_NAME ) def main_directory(): return get_main_directory( PACKAGE_ROOT_DIRECTORY ) def get_main_directory(current_directory): possible_main_directory = os.path.normpath( os.path.dirname( os.path.dirname( current_directory ) ) ) if sublime: sublime_text_packages = os.path.normpath( os.path.dirname( sublime.packages_path() ) ) if possible_main_directory == sublime_text_packages: return possible_main_directory else: return sublime_text_packages return possible_main_directory def sublime_setting_path(): return os.path.join( main_directory(), "Packages", "User", "%s.sublime-settings" % SUBLIME_SETTING_NAME ) def packagesmanager_setting_path(): return os.path.join( main_directory(), "Packages", "User", "%s.sublime-settings" % PACKAGESMANAGER_NAME ) def sublime_setting_file(): return '%s.sublime-settings' % SUBLIME_SETTING_NAME def packagesmanager_setting_file(): return '%s.sublime-settings' % PACKAGESMANAGER_NAME def plugin_loaded(): threading.Thread( target=_delayed_in_progress_removal, args=(PACKAGESMANAGER_NAME,) ).start() def _delayed_in_progress_removal(package_name): sleep_delay = 60 + random.randint( 0, 60 ) # sleep_delay = 6 time.sleep( sleep_delay ) packages_setting = sublime.load_settings( packagesmanager_setting_file() ) in_process_count = packages_setting.get( 'in_process_packages_count', 0 ) in_process_packages = packages_setting.get( 'in_process_packages', [] ) # print("in_process_count:", in_process_count, ", in_process_packages:", in_process_packages) if package_name in in_process_packages: sublime_settings = sublime.load_settings( sublime_setting_file() ) ignored_packages = sublime_settings.get( 'ignored_packages', [] ) if package_name in ignored_packages: print( "{manager}: The package `%s` should not be in your User `ignored_packages` " "package settings, after %d seconds." % ( package_name, sleep_delay ) ) if in_process_count > 3: ignored_packages.remove( package_name ) sublime_settings.set( 'ignored_packages', ignored_packages ) packages_setting.erase( 'in_process_packages_count' ) sublime.save_settings( sublime_setting_file() ) sublime.save_settings( packagesmanager_setting_file() ) else: packages_setting.set( 'in_process_packages_count', in_process_count + 1 ) sublime.save_settings( packagesmanager_setting_file() ) else: print("{manager}: Finishing the package `%s` changes after randomly %s seconds delay." % ( package_name, sleep_delay ) ) in_process_packages.remove( package_name ) packages_setting.erase( 'in_process_packages_count' ) packages_setting.set( 'in_process_packages', in_process_packages ) sublime.save_settings( packagesmanager_setting_file() ) # Remove itself if the Default package is not found if not os.path.exists( PACKAGESMANAGER_ROOT_DIRECTORY ): print("{manager}: Uninstalling %s... Because the %s package was not found installed at %s." % ( THIS_SCRIPT_PATH, PACKAGESMANAGER_NAME, PACKAGESMANAGER_ROOT_DIRECTORY ) ) safe_remove( THIS_SCRIPT_PATH ) def safe_remove(path): try: os.remove( path ) except Exception as error: print( "{manager}: Failed to remove `%s`. Error is: %s" % ( path, error) ) try: delete_read_only_file(path) except Exception as error: print( "{manager}: Failed to remove `%s`. Error is: %s" % ( path, error) ) def delete_read_only_file(path): _delete_read_only_file( None, path, None ) def _delete_read_only_file(action, name, exc): os.chmod( name, stat.S_IWRITE ) os.remove( name ) """.format(manager=PACKAGESMANAGER_NAME) packages_directory = os.path.dirname(PACKAGE_ROOT_DIRECTORY) reenable_package_code = dedent(reenable_package_code).lstrip() reenable_package_file = os.path.join(packages_directory, "zz_packagesmanager_reenabler.py") if not compare_text_with_file(reenable_package_code, reenable_package_file): with open(reenable_package_file, 'w', newline='\n', encoding='utf-8') as output_file: output_file.write(reenable_package_code) base_loader_code = r""" import sys import time import stat import sublime import sublime_plugin import os from os.path import dirname # This file adds the package_control subdirectory of {manager} # to first in the sys.path so that all other packages may rely on # PC for utility functions, such as event helpers, adding things to # sys.path, downloading files from the internet, etc if sys.version_info >= (3,): def decode(path): return path def encode(path): return path loader_dir = dirname(__file__) else: def decode(path): if not isinstance(path, unicode): path = path.decode(sys.getfilesystemencoding()) return path def encode(path): if isinstance(path, unicode): path = path.encode(sys.getfilesystemencoding()) return path loader_dir = decode(os.getcwd()) st_dir = dirname(dirname(loader_dir)) found = False if sys.version_info >= (3,): installed_packages_dir = os.path.join(st_dir, u'Installed Packages') pc_package_path = os.path.join(installed_packages_dir, u'{manager}.sublime-package') if os.path.exists(encode(pc_package_path)): found = True if not found: packages_dir = os.path.join(st_dir, u'Packages') pc_package_path = os.path.join(packages_dir, u'{manager}') if os.path.exists(encode(pc_package_path)): found = True # Handle the development environment if not found and sys.version_info >= (3,): import Default.sort if os.path.basename(Default.sort.__file__) == 'sort.py': packages_dir = dirname(dirname(Default.sort.__file__)) pc_package_path = os.path.join(packages_dir, u'{manager}') if os.path.exists(encode(pc_package_path)): found = True if found: if os.name == 'nt': from ctypes import windll, create_unicode_buffer buf = create_unicode_buffer(512) if windll.kernel32.GetShortPathNameW(pc_package_path, buf, len(buf)): pc_package_path = buf.value sys.path.insert(0, encode(pc_package_path)) import package_control # We remove the import path right away so as not to screw up # Sublime Text and its import machinery sys.path.remove(encode(pc_package_path)) else: print( u'{manager}: Error finding main directory from loader' ) """.format(manager=PACKAGESMANAGER_NAME) base_loader_code = dedent(base_loader_code).lstrip() loader.add_or_update('00', 'package_control', base_loader_code) loader.add_or_update('00', 'package_control', base_loader_code, pythonver='38') # SSL support fo Linux if sublime.platform() == 'linux' and int(sublime.version()) < 3109: linux_ssl_url = u'http://packagecontrol.io/ssl/1.0.2/ssl-linux.sublime-package' linux_ssl_hash = u'23f35f64458a0a14c99b1bb1bbc3cb04794c7361c4940e0a638d40f038acd377' linux_ssl_priority = u'01' linux_ssl_version = '1.0.2' def linux_ssl_show_restart(): sublime.message_dialog( text.format(u''' {PACKAGESMANAGER_NAME} {PACKAGESMANAGER_NAME} just installed or upgraded the missing Python _ssl module for Linux since Sublime Text does not include it. Please restart Sublime Text to make SSL available to all packages. '''.format(PACKAGESMANAGER_NAME=PACKAGESMANAGER_NAME))) threading.Thread(target=bootstrap_dependency, args=( settings, linux_ssl_url, linux_ssl_hash, linux_ssl_priority, linux_ssl_version, linux_ssl_show_restart, )).start() # SSL support for SHA-2 certificates with ST2 on Windows elif sublime.platform() == 'windows' and sys.version_info < (3, ): win_ssl_url = u'http://packagecontrol.io/ssl/1.0.0/ssl-windows.sublime-package' win_ssl_hash = u'3c28982eb400039cfffe53d38510556adead39ba7321f2d15a6770d3ebc75030' win_ssl_priority = u'01' win_ssl_version = u'1.0.0' def win_ssl_show_restart(): sublime.message_dialog( text.format(u''' {PACKAGESMANAGER_NAME} {PACKAGESMANAGER_NAME} just upgraded the Python _ssl module for ST2 on Windows because the bundled one does not include support for modern SSL certificates. Please restart Sublime Text to complete the upgrade. '''.format(PACKAGESMANAGER_NAME=PACKAGESMANAGER_NAME))) threading.Thread(target=bootstrap_dependency, args=( settings, win_ssl_url, win_ssl_hash, win_ssl_priority, win_ssl_version, win_ssl_show_restart, )).start() else: sublime.set_timeout(mark_bootstrapped, 10)