Example #1
0
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)
Example #2
0
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)
Example #3
0
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)