def UpdateCliTrees(cli=None, commands=None, directory=None,
                   verbose=False, warn_on_exceptions=False):
  """(re)generates the CLI trees in directory if non-existent or out ot date.

  This function uses the progress tracker because some of the updates can
  take ~minutes.

  Args:
    cli: The default CLI. If not None then the default CLI is also updated.
    commands: Update only the commands in this list.
    directory: The directory containing the CLI tree JSON files. If None
      then the default installation directories are used.
    verbose: Display a status line for up to date CLI trees if True.
    warn_on_exceptions: Emits warning messages in lieu of exceptions. Used
      during installation.

  Raises:
    NoCliTreeGeneratorForCommand: A command in commands is not supported
      (doesn't have a generator).
  """
  # Initialize the list of directories to search for CLI tree files. The default
  # CLI tree is only searched for and generated in directories[0]. Other
  # existing trees are updated in the directory in which they were found. New
  # trees are generated in directories[-1].
  directories = []
  if directory:
    directories.append(directory)
  else:
    try:
      directories.append(cli_tree.CliTreeDir())
    except cli_tree.SdkRootNotFoundError as e:
      if not warn_on_exceptions:
        raise
      log.warn(str(e))
    directories.append(cli_tree.CliTreeConfigDir())

  if not commands:
    commands = set([cli_tree.DEFAULT_CLI_NAME] + GENERATORS.keys())

  failed = []
  for command in sorted(commands):
    if command != cli_tree.DEFAULT_CLI_NAME:
      generator = GetCliTreeGenerator(command)
      try:
        generator.LoadOrGenerate(directories=directories, verbose=verbose,
                                 warn_on_exceptions=warn_on_exceptions)
      except subprocess.CalledProcessError:
        failed.append(command)
    elif cli:
      cli_tree.Load(cli=cli,
                    path=cli_tree.CliTreePath(directory=directories[0]),
                    verbose=verbose)
  if failed:
    message = 'No CLI tree {} for [{}].'.format(
        text_utils.Pluralize(len(failed), 'generator'),
        ', '.join(sorted(failed)))
    if not warn_on_exceptions:
      raise NoCliTreeGeneratorForCommand(message)
    log.warn(message)
Exemple #2
0
 def FindTreeFile(self, directories):
     """Returns (path,f) open for read for the first CLI tree in directories."""
     for directory in directories or [cli_tree.CliTreeConfigDir()]:
         path = os.path.join(directory or '.', self.command) + '.json'
         try:
             return path, io.open(path, 'rt')
         except IOError:
             pass
     return path, None  # pytype: disable=name-error
Exemple #3
0
def _GetDirectories(directory=None, warn_on_exceptions=False):
  """Returns the list of directories to search for CLI trees.

  Args:
    directory: The directory containing the CLI tree JSON files. If None
      then the default installation and config directories are used.
    warn_on_exceptions: Emits warning messages in lieu of exceptions.
  """
  # Initialize the list of directories to search for CLI tree files. The default
  # CLI tree is only searched for and generated in directories[0]. Other
  # existing trees are updated in the directory in which they were found. New
  # trees are generated in directories[-1].
  directories = []
  if directory:
    directories.append(directory)
  else:
    try:
      directories.append(cli_tree.CliTreeDir())
    except cli_tree.SdkRootNotFoundError as e:
      if not warn_on_exceptions:
        raise
      log.warning(six.text_type(e))
    directories.append(cli_tree.CliTreeConfigDir())
  return directories
def ListAll(directory=None):
    """Returns the CliTreeInfo list of all available CLI trees.

  Args:
    directory: The config directory containing the CLI tree modules.

  Raises:
    CliTreeVersionError: loaded tree version mismatch
    ImportModuleError: import errors

  Returns:
    The CLI tree.
  """
    # List all CLIs by searching directories in order. .py, .pyc, and .json
    # files are treated as CLI modules/data, where the file base name is the name
    # of the CLI root command.
    directories = [
        directory,  # Explicit caller override dir
        cli_tree.CliTreeConfigDir(),  # Config dir shared across installations
        cli_tree.CliTreeDir(),  # Installation dir controlled by the updater
    ]

    trees = []
    for directory in directories:
        if not directory or not os.path.exists(directory):
            continue
        for (dirpath, _, filenames) in os.walk(directory):
            for filename in sorted(filenames):  # For stability across runs.
                base, extension = os.path.splitext(filename)
                if base == '__init__' or '.' in base:
                    # Ignore Python droppings and names containing more than one dot.
                    continue
                path = os.path.join(dirpath, filename)
                error = ''
                tree = None
                if extension in ('.py', '.pyc'):
                    try:
                        module = module_util.ImportPath(path)
                    except module_util.ImportModuleError as e:
                        error = six.text_type(e)
                    try:
                        tree = module.TREE
                    except AttributeError:
                        tree = None
                elif extension == '.json':
                    try:
                        tree = json.loads(files.ReadFileContents(path))
                    except Exception as e:  # pylint: disable=broad-except, record all errors
                        error = six.text_type(e)
                if tree:
                    version = tree.get(cli_tree.LOOKUP_VERSION, 'UNKNOWN')
                    cli_version = tree.get(cli_tree.LOOKUP_CLI_VERSION,
                                           'UNKNOWN')
                    del tree
                else:
                    version = 'UNKNOWN'
                    cli_version = 'UNKNOWN'
                trees.append(
                    CliTreeInfo(command=base,
                                path=_ParameterizePath(path),
                                version=version,
                                cli_version=cli_version,
                                command_installed=bool(
                                    files.FindExecutableOnPath(base)),
                                error=error))
            # Don't search subdirectories.
            break
    return trees