text: # Copyright 2013 Google Inc. All Rights Reserved.
  
  """Common bootstrapping functionality used by the wrapper scripts."""
  
  # Disables import order warning and unused import.  Setup changes the python
  # path so cloud sdk imports will actually work, so it must come first.
  # pylint: disable=C6203
  # pylint: disable=W0611
  from __future__ import absolute_import
  from __future__ import unicode_literals
  
  # Python 3 is strict about imports and we use this file in different ways, which
  # makes sub-imports difficult. In general, when a script is executed, that
  # directory is put on the PYTHONPATH. The issue is that some of the wrapper
  # scripts are executed from within the bootstrapping/ directory and some are
  # executed from within the bin/ directory.
  # pylint: disable=g-statement-before-imports
  if '.' in __name__:
    # Here, __name__ will be bootstrapping.bootstrapping. This indicates that this
    # file was loaded as a member of package bootstrapping. This in turn indicates
    # that the main file that was executed was not in the bootstrapping directory,
    # so bin/ is on the path and bootstrapping is considered a python package.
    # Do an import of setup from this current package.
    from . import setup  # pylint:disable=g-import-not-at-top
  else:
    # In this case, __name__ is bootstrapping, which indicates that the main
    # script was executed from within this directory meaning that Python doesn't
    # consider this a package but rather the root of the PYTHONPATH. We can't do
    # the above import because since we are not in a package, the '.' doesn't
    # refer to anything. Just do a direct import which will find setup on the
    # PYTHONPATH (which is just this directory).
    import setup  # pylint:disable=g-import-not-at-top
  
  import json
  import os
  import sys
  import platform
  
  from googlecloudsdk.core import config
  from googlecloudsdk.core import execution_utils
  from googlecloudsdk.core import metrics
  from googlecloudsdk.core import properties
  from googlecloudsdk.core.console import console_attr
  from googlecloudsdk.core.credentials import store as c_store
  from googlecloudsdk.core.updater import local_state
  from googlecloudsdk.core.updater import update_manager
  from googlecloudsdk.core.util import encoding
  from googlecloudsdk.core.util import files
  from googlecloudsdk.core.util import platforms
  from six.moves import input
  
  
  BOOTSTRAPPING_DIR = os.path.dirname(os.path.realpath(__file__))
  BIN_DIR = os.path.dirname(BOOTSTRAPPING_DIR)
  SDK_ROOT = os.path.dirname(BIN_DIR)
  
  
  def DisallowPython3():
    if not platforms.PythonVersion().IsCompatible():
      sys.exit(1)
  
  
  def GetDecodedArgv():
    return [console_attr.Decode(arg) for arg in sys.argv]
  
  
  def _FullPath(tool_dir, exec_name):
    return os.path.join(SDK_ROOT, tool_dir, exec_name)
  
  
  def ExecutePythonTool(tool_dir, exec_name, *args):
    """Execute the given python script with the given args and command line.
  
    Args:
      tool_dir: the directory the tool is located in
      exec_name: additional path to the executable under the tool_dir
      *args: args for the command
    """
    py_path = None  # Let execution_utils resolve the path.
    # Gsutil allows users to set the desired Python interpreter using a separate
    # environment variable, so as to allow users to run gsutil using Python 3
    # without forcing the rest of the Cloud SDK to use Python 3 (as it would
    # likely break at the time this comment was written).
    if exec_name == 'gsutil':
      gsutil_py = encoding.GetEncodedValue(os.environ, 'CLOUDSDK_GSUTIL_PYTHON')
      if gsutil_py:
        py_path = gsutil_py
  
    _ExecuteTool(
        execution_utils.ArgsForPythonTool(
            _FullPath(tool_dir, exec_name), *args, python=py_path))
  
  
  def ExecuteJarTool(java_bin, jar_dir, jar_name, classname, flags=None, *args):
    """Execute a given jar with the given args and command line.
  
    Args:
      java_bin: str, path to the system Java binary
      jar_dir: str, the directory the jar is located in
      jar_name: str, file name of the jar under tool_dir
      classname: str, name of the main class in the jar
      flags: [str], flags for the java binary
      *args: args for the command
    """
    flags = flags or []
    jar_path = _FullPath(jar_dir, jar_name)
    classname_arg = [classname] if classname else []
    java_args = ['-cp', jar_path] + flags + classname_arg + list(args)
    _ExecuteTool(
        execution_utils.ArgsForExecutableTool(java_bin, *java_args))
  
  
  def ExecuteJavaClass(java_bin,
                       jar_dir,
                       main_jar,
                       main_class,
                       java_flags=None,
                       main_args=None):
    """Execute a given java class within a directory of jars.
  
    Args:
      java_bin: str, path to the system Java binary
      jar_dir: str, directory of jars to put on class path
      main_jar: str, main jar (placed first on class path)
      main_class: str, name of the main class in the jar
      java_flags: [str], flags for the java binary
      main_args: args for the command
    """
    java_flags = java_flags or []
    main_args = main_args or []
    jar_dir_path = os.path.join(SDK_ROOT, jar_dir, '*')
    main_jar_path = os.path.join(SDK_ROOT, jar_dir, main_jar)
    classpath = main_jar_path + os.pathsep + jar_dir_path
    java_args = (['-cp', classpath]
                 + list(java_flags)
                 + [main_class]
                 + list(main_args))
    _ExecuteTool(execution_utils.ArgsForExecutableTool(java_bin, *java_args))
  
  
  def ExecuteShellTool(tool_dir, exec_name, *args):
    """Execute the given bash script with the given args.
  
    Args:
      tool_dir: the directory the tool is located in
      exec_name: additional path to the executable under the tool_dir
      *args: args for the command
    """
    _ExecuteTool(
        execution_utils.ArgsForExecutableTool(_FullPath(tool_dir, exec_name),
                                              *args))
  
  
  def ExecuteCMDTool(tool_dir, exec_name, *args):
    """Execute the given batch file with the given args.
  
    Args:
      tool_dir: the directory the tool is located in
      exec_name: additional path to the executable under the tool_dir
      *args: args for the command
    """
    _ExecuteTool(
        execution_utils.ArgsForCMDTool(_FullPath(tool_dir, exec_name), *args))
  
  
  def _GetToolEnv():
    env = dict(os.environ)
    encoding.SetEncodedValue(env, 'CLOUDSDK_WRAPPER', '1')
    encoding.SetEncodedValue(env, 'CLOUDSDK_VERSION', config.CLOUD_SDK_VERSION)
    encoding.SetEncodedValue(env, 'CLOUDSDK_PYTHON',
                             execution_utils.GetPythonExecutable())
    return env
  
  
  def _ExecuteTool(args):
    """Executes a new tool with the given args, plus the args from the cmdline.
  
    Args:
      args: [str], The args of the command to execute.
    """
    execution_utils.Exec(args + sys.argv[1:], env=_GetToolEnv())
  
  
  def GetDefaultInstalledComponents():
    """Gets the list of components to install by default.
  
    Returns:
      list(str), The component ids that should be installed.  It will return []
      if there are no default components, or if there is any error in reading
      the file with the defaults.
    """
    default_components_file = os.path.join(BOOTSTRAPPING_DIR,
                                           '.default_components')
    try:
      with open(default_components_file) as f:
        return json.load(f)
    # pylint:disable=bare-except, If the file does not exist or is malformed,
    # we don't want to expose this as an error.  Setup will just continue
    # without installing any components by default and will tell the user how
    # to install the components they want manually.
    except:
      pass
    return []
  
  
  def CheckForBlacklistedCommand(args, blacklist, warn=True, die=False):
    """Blacklist certain subcommands, and warn the user.
  
    Args:
      args: the command line arguments, including the 0th argument which is
        the program name.
      blacklist: a map of blacklisted commands to the messages that should be
        printed when they're run.
      warn: if true, print a warning message.
      die: if true, exit.
  
    Returns:
      True if a command in the blacklist is being indicated by args.
  
    """
    bad_arg = None
    for arg in args[1:]:
      # Flags are skipped and --flag=value are skipped. It is possible for
      # '--flag value' to result in a false positive if value happens to be in
      # the blacklist.
      if arg and arg[0] == '-':
        continue
      if arg in blacklist:
        bad_arg = arg
        break
  
    blacklisted = bad_arg is not None
  
    if blacklisted:
      if warn:
        sys.stderr.write('It looks like you are trying to run "%s %s".\n'
                         % (args[0], bad_arg))
        sys.stderr.write('The "%s" command is no longer needed with the '
                         'Cloud SDK.\n' % bad_arg)
        sys.stderr.write(blacklist[bad_arg] + '\n')
        answer = input('Really run this command? (y/N) ')
        if answer in ['y', 'Y']:
          return False
  
      if die:
        sys.exit(1)
  
    return blacklisted
  
  
  def CheckUpdates(command_path):
    """Check for updates and inform the user.
  
    Args:
      command_path: str, The '.' separated path of the command that is currently
        being run (i.e. gcloud.foo.bar).
    """
    try:
      update_manager.UpdateManager.PerformUpdateCheck(command_path=command_path)
    # pylint:disable=broad-except, We never want this to escape, ever. Only
    # messages printed should reach the user.
    except Exception:
      pass
  
  
  def CommandStart(command_name, component_id=None, version=None):
    """Logs that the given command is being executed.
  
    Args:
      command_name: str, The name of the command being executed.
      component_id: str, The component id that this command belongs to.  Used for
        version information if version was not specified.
      version: str, Directly use this version instead of deriving it from
        component.
    """
    if version is None and component_id:
      version = local_state.InstallationState.VersionForInstalledComponent(
          component_id)
    metrics.Executions(command_name, version)
  
  
  def GetActiveProjectAndAccount():
    """Get the active project name and account for the active credentials.
  
    For use with wrapping legacy tools that take projects and credentials on
    the command line.
  
    Returns:
      (str, str), A tuple whose first element is the project, and whose second
      element is the account.
    """
    project_name = properties.VALUES.core.project.Get(validate=False)
    account = properties.VALUES.core.account.Get(validate=False)
    return (project_name, account)
  
  
  def ReadFileContents(*path_parts):
    """Returns file content at specified relative path wrt SDK root path."""
    return files.ReadFileContents(os.path.join(SDK_ROOT, *path_parts)).strip()
  
  
  # Register some other sources for credentials and project.
  c_store.DevShellCredentialProvider().Register()
  c_store.GceCredentialProvider().Register()
  