Esempio n. 1
0
    def subprocess_info(self, shell, env, view_settings, window_settings, sublime_settings,
                        executable_temp_files, temp_dirs, executable_name, required_vars, optional_vars,
                        expected_result):

        with GolangConfigMock(shell, env, view_settings, window_settings, sublime_settings) as mock_context:

            mock_context.replace_tempdir_env()
            mock_context.replace_tempdir_view_settings()
            mock_context.replace_tempdir_window_settings()
            mock_context.replace_tempdir_sublime_settings()

            mock_context.make_executable_files(executable_temp_files)
            mock_context.make_dirs(temp_dirs)

            if isinstance(expected_result, tuple):
                tempdir = mock_context.tempdir + os.sep
                executable_path = expected_result[0].replace('{tempdir}', tempdir)
                executable_path = shellenv.path_encode(executable_path)

                env_vars = {}
                for name, value in expected_result[1].items():
                    value = value.replace('{tempdir}', tempdir)
                    name = shellenv.env_encode(name)
                    value = shellenv.env_encode(value)
                    env_vars[name] = value

                expected_result = (executable_path, env_vars)

                self.assertEquals(
                    expected_result,
                    golangconfig.subprocess_info(
                        executable_name,
                        required_vars,
                        optional_vars=optional_vars,
                        view=mock_context.view,
                        window=mock_context.window
                    )
                )
                self.assertEqual('', sys.stdout.getvalue())

            else:
                def do_test():
                    golangconfig.subprocess_info(
                        executable_name,
                        required_vars,
                        optional_vars=optional_vars,
                        view=mock_context.view,
                        window=mock_context.window
                    )
                self.assertRaises(expected_result, do_test)
Esempio n. 2
0
    def subprocess_info(self, shell, env, view_settings, window_settings,
                        sublime_settings, executable_temp_files, temp_dirs,
                        executable_name, required_vars, optional_vars,
                        expected_result):

        with GolangConfigMock(shell, env, view_settings, window_settings,
                              sublime_settings) as mock_context:

            mock_context.replace_tempdir_env()
            mock_context.replace_tempdir_view_settings()
            mock_context.replace_tempdir_window_settings()
            mock_context.replace_tempdir_sublime_settings()

            mock_context.make_executable_files(executable_temp_files)
            mock_context.make_dirs(temp_dirs)

            if isinstance(expected_result, tuple):
                tempdir = mock_context.tempdir + os.sep
                executable_path = expected_result[0].replace(
                    '{tempdir}', tempdir)
                executable_path = shellenv.path_encode(executable_path)

                env_vars = {}
                for name, value in expected_result[1].items():
                    value = value.replace('{tempdir}', tempdir)
                    name = shellenv.env_encode(name)
                    value = shellenv.env_encode(value)
                    env_vars[name] = value

                expected_result = (executable_path, env_vars)

                self.assertEquals(
                    expected_result,
                    golangconfig.subprocess_info(executable_name,
                                                 required_vars,
                                                 optional_vars=optional_vars,
                                                 view=mock_context.view,
                                                 window=mock_context.window))
                self.assertEqual('', sys.stdout.getvalue())

            else:

                def do_test():
                    golangconfig.subprocess_info(executable_name,
                                                 required_vars,
                                                 optional_vars=optional_vars,
                                                 view=mock_context.view,
                                                 window=mock_context.window)

                self.assertRaises(expected_result, do_test)
Esempio n. 3
0
def subprocess_info(executable_name,
                    required_vars,
                    optional_vars=None,
                    view=None,
                    window=None):
    """
    Gathers and formats information necessary to use subprocess.Popen() to
    run one of the go executables, with details pulled from setting_value() and
    executable_path().

    Ensures that the executable path and env dictionary are properly encoded for
    Sublime Text 2, where byte strings are necessary.

    :param executable_name:
        A unicode string of the executable to locate, e.g. "go" or "gofmt"

    :param required_vars:
        A list of unicode strings of the environment variables that are
        required, e.g. "GOPATH". Obtains values from setting_value().

    :param optional_vars:
        A list of unicode strings of the environment variables that are
        optional, but should be pulled from setting_value() if available - e.g.
        "GOOS", "GOARCH". Obtains values from setting_value().

    :param view:
        A sublime.View object to use in finding project-specific settings. This
        should be passed whenever available.

    :param window:
        A sublime.Window object to use in finding project-specific settings.
        This should be passed whenever available.

    :raises:
        RuntimeError
            When the function is called from any thread but the UI thread
        TypeError
            When any of the parameters are of the wrong type
        golangconfig.ExecutableError
            When the executable requested could not be located. The .name
            attribute contains the name of the executable that could not be
            located. The .dirs attribute contains a list of unicode strings
            of the directories searched.
        golangconfig.EnvVarError
            When one or more required_vars are not available. The .missing
            attribute will be a list of the names of missing environment
            variables.

    :return:
        A two-element tuple.

         - [0] A unicode string (byte string for ST2) of the path to the executable
         - [1] A dict to pass to the env parameter of subprocess.Popen()
    """

    path, _ = executable_path(executable_name, view=view, window=window)
    if path is None:
        name = executable_name
        if sys.platform == 'win32':
            name += '.exe'
        dirs = []
        settings_path, _ = _get_most_specific_setting('PATH',
                                                      view=view,
                                                      window=window)
        if settings_path and settings_path != _NO_VALUE:
            dirs.extend(settings_path.split(os.pathsep))
        _, shell_dirs = shellenv.get_path()
        for shell_dir in shell_dirs:
            if shell_dir not in dirs:
                dirs.append(shell_dir)
        exception = ExecutableError(
            'The executable "%s" could not be located in any of the following locations: "%s"'
            % (name, '", "'.join(dirs)))
        exception.name = name
        exception.dirs = dirs
        raise exception

    path = shellenv.path_encode(path)

    _, env = shellenv.get_env(for_subprocess=True)

    var_groups = [required_vars]
    if optional_vars:
        var_groups.append(optional_vars)

    missing_vars = []

    for var_names in var_groups:
        for var_name in var_names:
            value, _ = setting_value(var_name, view=view, window=window)
            var_key = var_name

            if value is not None:
                value = str_cls(value)
                value = shellenv.env_encode(value)
            var_key = shellenv.env_encode(var_key)

            if value is None:
                if var_key in env:
                    del env[var_key]
                continue

            env[var_key] = value

    for required_var in required_vars:
        var_key = shellenv.env_encode(required_var)
        if var_key not in env:
            missing_vars.append(required_var)

    if missing_vars:
        missing_vars = sorted(missing_vars, key=lambda s: s.lower())
        exception = EnvVarError(
            'The following environment variable%s currently unset: %s' %
            ('s are' if len(missing_vars) > 1 else ' is',
             ', '.join(missing_vars)))
        exception.missing = missing_vars
        raise exception

    encoded_goroot = shellenv.env_encode('GOROOT')
    if encoded_goroot in env:
        unicode_sep = shellenv.path_decode(os.sep)
        name = executable_name
        if sys.platform == 'win32':
            name += '.exe'
        relative_executable_path = shellenv.path_encode('bin%s%s' %
                                                        (unicode_sep, name))
        goroot_executable_path = os.path.join(env[encoded_goroot],
                                              relative_executable_path)
        if goroot_executable_path != path:
            print(
                'golangconfig: warning - binary %s was found at "%s", which is not inside of the GOROOT "%s"'
                % (executable_name, path,
                   shellenv.path_decode(env[encoded_goroot])))

    return (path, env)
def subprocess_info(executable_name, required_vars, optional_vars=None, view=None, window=None):
    """
    Gathers and formats information necessary to use subprocess.Popen() to
    run one of the go executables, with details pulled from setting_value() and
    executable_path().

    Ensures that the executable path and env dictionary are properly encoded for
    Sublime Text 2, where byte strings are necessary.

    :param executable_name:
        A unicode string of the executable to locate, e.g. "go" or "gofmt"

    :param required_vars:
        A list of unicode strings of the environment variables that are
        required, e.g. "GOPATH". Obtains values from setting_value().

    :param optional_vars:
        A list of unicode strings of the environment variables that are
        optional, but should be pulled from setting_value() if available - e.g.
        "GOOS", "GOARCH". Obtains values from setting_value().

    :param view:
        A sublime.View object to use in finding project-specific settings. This
        should be passed whenever available.

    :param window:
        A sublime.Window object to use in finding project-specific settings.
        This should be passed whenever available.

    :raises:
        RuntimeError
            When the function is called from any thread but the UI thread
        TypeError
            When any of the parameters are of the wrong type
        golangconfig.ExecutableError
            When the executable requested could not be located. The .name
            attribute contains the name of the executable that could not be
            located. The .dirs attribute contains a list of unicode strings
            of the directories searched.
        golangconfig.EnvVarError
            When one or more required_vars are not available. The .missing
            attribute will be a list of the names of missing environment
            variables.
        golangconfig.GoPathNotFoundError
            When one or more directories specified by the GOPATH environment
            variable could not be found on disk. The .directories attribute will
            be a list of the directories that could not be found.
        golangconfig.GoRootNotFoundError
            When the directory specified by GOROOT environment variable could
            not be found on disk. The .directory attribute will be the path to
            the directory that could not be found.

        golangconfig.EnvVarError
            When one or more required_vars are not available. The .missing
            attribute will be a list of the names of missing environment
            variables.

    :return:
        A two-element tuple.

         - [0] A unicode string (byte string for ST2) of the path to the executable
         - [1] A dict to pass to the env parameter of subprocess.Popen()
    """

    path, _ = executable_path(executable_name, view=view, window=window)
    if path is None:
        name = executable_name
        if sys.platform == 'win32':
            name += '.exe'
        dirs = []
        settings_path, _ = _get_most_specific_setting('PATH', view=view, window=window)
        if settings_path and settings_path != _NO_VALUE:
            dirs.extend(settings_path.split(os.pathsep))
        _, shell_dirs = shellenv.get_path()
        for shell_dir in shell_dirs:
            if shell_dir not in dirs:
                dirs.append(shell_dir)
        exception = ExecutableError(
            'The executable "%s" could not be located in any of the following locations: "%s"' %
            (
                name,
                '", "'.join(dirs)
            )
        )
        exception.name = name
        exception.dirs = dirs
        raise exception

    path = shellenv.path_encode(path)

    _, env = shellenv.get_env(for_subprocess=True)

    var_groups = [required_vars]
    if optional_vars:
        var_groups.append(optional_vars)

    missing_vars = []

    for var_names in var_groups:
        for var_name in var_names:
            value, _ = setting_value(var_name, view=view, window=window)
            var_key = var_name

            if value is not None:
                value = str_cls(value)
                value = shellenv.env_encode(value)
            var_key = shellenv.env_encode(var_key)

            if value is None:
                if var_key in env:
                    del env[var_key]
                continue

            env[var_key] = value

    for required_var in required_vars:
        var_key = shellenv.env_encode(required_var)
        if var_key not in env:
            missing_vars.append(required_var)

    if missing_vars:
        missing_vars = sorted(missing_vars, key=lambda s: s.lower())
        exception = EnvVarError(
            'The following environment variable%s currently unset: %s' %
            (
                's are' if len(missing_vars) > 1 else ' is',
                ', '.join(missing_vars)
            )
        )
        exception.missing = missing_vars
        raise exception

    encoded_goroot = shellenv.env_encode('GOROOT')
    if encoded_goroot in env:
        unicode_sep = shellenv.path_decode(os.sep)
        name = executable_name
        if sys.platform == 'win32':
            name += '.exe'
        relative_executable_path = shellenv.path_encode('bin%s%s' % (unicode_sep, name))
        goroot_executable_path = os.path.join(env[encoded_goroot], relative_executable_path)
        if goroot_executable_path != path:
            print(
                'golangconfig: warning - binary %s was found at "%s", which is not inside of the GOROOT "%s"' %
                (
                    executable_name,
                    path,
                    shellenv.path_decode(env[encoded_goroot])
                )
            )

    return (path, env)
Esempio n. 5
0
 def test_path_encode(self):
     value = shellenv.path_encode(os.path.expanduser('~'))
     if sys.version_info < (3,):
         self.assertEqual(os.path.expanduser(b'~'), value)
     else:
         self.assertEqual(os.path.expanduser('~'), value)
 def test_path_encode(self):
     value = shellenv.path_encode(os.path.expanduser('~'))
     if sys.version_info < (3, ):
         self.assertEqual(os.path.expanduser(b'~'), value)
     else:
         self.assertEqual(os.path.expanduser('~'), value)