#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Meta checkout dependency manager for Git."""
# Files
#   .gclient      : Current client configuration, written by 'config' command.
#                   Format is a Python script defining 'solutions', a list whose
#                   entries each are maps binding the strings "name" and "url"
#                   to strings specifying the name and location of the client
#                   module, as well as "custom_deps" to a map similar to the
#                   deps section of the DEPS file below, as well as
#                   "custom_hooks" to a list similar to the hooks sections of
#                   the DEPS file below.
#   .gclient_entries : A cache constructed by 'update' command.  Format is a
#                   Python script defining 'entries', a list of the names
#                   of all modules in the client
#   <module>/DEPS : Python script defining var 'deps' as a map from each
#                   requisite submodule name to a URL where it can be found (via
#                   one SCM)
#
# Hooks
#   .gclient and DEPS files may optionally contain a list named "hooks" to
#   allow custom actions to be performed based on files that have changed in the
#   working copy as a result of a "sync"/"update" or "revert" operation.  This
#   can be prevented by using --nohooks (hooks run by default). Hooks can also
#   be forced to run with the "runhooks" operation.  If "sync" is run with
#   --force, all known but not suppressed hooks will run regardless of the state
#   of the working copy.
#
#   Each item in a "hooks" list is a dict, containing these two keys:
#     "pattern"  The associated value is a string containing a regular
#                expression.  When a file whose pathname matches the expression
#                is checked out, updated, or reverted, the hook's "action" will
#                run.
#     "action"   A list describing a command to run along with its arguments, if
#                any.  An action command will run at most one time per gclient
#                invocation, regardless of how many files matched the pattern.
#                The action is executed in the same directory as the .gclient
#                file.  If the first item in the list is the string "python",
#                the current Python interpreter (sys.executable) will be used
#                to run the command. If the list contains string
#                "$matching_files" it will be removed from the list and the list
#                will be extended by the list of matching files.
#     "name"     An optional string specifying the group to which a hook belongs
#                for overriding and organizing.
#
#   Example:
#     hooks = [
#       { "pattern": "\\.(gif|jpe?g|pr0n|png)$",
#         "action":  ["python", "image_indexer.py", "--all"]},
#       { "pattern": ".",
#         "name": "gyp",
#         "action":  ["python", "src/build/gyp_chromium"]},
#     ]
#
# Pre-DEPS Hooks
#   DEPS files may optionally contain a list named "pre_deps_hooks".  These are
#   the same as normal hooks, except that they run before the DEPS are
#   processed. Pre-DEPS run with "sync" and "revert" unless the --noprehooks
#   flag is used.
#
# Specifying a target OS
#   An optional key named "target_os" may be added to a gclient file to specify
#   one or more additional operating systems that should be considered when
#   processing the deps_os/hooks_os dict of a DEPS file.
#
#   Example:
#     target_os = [ "android" ]
#
#   If the "target_os_only" key is also present and true, then *only* the
#   operating systems listed in "target_os" will be used.
#
#   Example:
#     target_os = [ "ios" ]
#     target_os_only = True
#
# Specifying a target CPU
#   To specify a target CPU, the variables target_cpu and target_cpu_only
#   are available and are analagous to target_os and target_os_only.

from __future__ import print_function

__version__ = '0.7'

import collections
import copy
import json
import logging
import optparse
import os
import platform
import posixpath
import pprint
import re
import sys
import time

try:
  import urlparse
except ImportError:  # For Py3 compatibility
  import urllib.parse as urlparse

import detect_host_arch
import fix_encoding
import gclient_eval
import gclient_scm
import gclient_paths
import gclient_utils
import git_cache
import metrics
import metrics_utils
from third_party.repo.progress import Progress
import subcommand
import subprocess2
import setup_color

from third_party import six


# TODO(crbug.com/953884): Remove this when python3 migration is done.
if six.PY3:
  # pylint: disable=redefined-builtin
  basestring = str


DEPOT_TOOLS_DIR = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))

# Singleton object to represent an unset cache_dir (as opposed to a disabled
# one, e.g. if a spec explicitly says `cache_dir = None`.)
UNSET_CACHE_DIR = object()


class GNException(Exception):
  pass


def ToGNString(value, allow_dicts = True):
  """Returns a stringified GN equivalent of the Python value.

  allow_dicts indicates if this function will allow converting dictionaries
  to GN scopes. This is only possible at the top level, you can't nest a
  GN scope in a list, so this should be set to False for recursive calls."""
  if isinstance(value, basestring):
    if value.find('\n') >= 0:
      raise GNException("Trying to print a string with a newline in it.")
    return '"' + \
        value.replace('\\', '\\\\').replace('"', '\\"').replace('$', '\\$') + \
        '"'

  if sys.version_info.major == 2 and isinstance(value, unicode):
    return ToGNString(value.encode('utf-8'))

  if isinstance(value, bool):
    if value:
      return "true"
    return "false"

  # NOTE: some type handling removed compared to chromium/src copy.

  raise GNException("Unsupported type when printing to GN.")


class Hook(object):
  """Descriptor of command ran before/after sync or on demand."""

  def __init__(self, action, pattern=None, name=None, cwd=None, condition=None,
               variables=None, verbose=False, cwd_base=None):
    """Constructor.

    Arguments:
      action (list of basestring): argv of the command to run
      pattern (basestring regex): noop with git; deprecated
      name (basestring): optional name; no effect on operation
      cwd (basestring): working directory to use
      condition (basestring): condition when to run the hook
      variables (dict): variables for evaluating the condition
    """
    self._action = gclient_utils.freeze(action)
    self._pattern = pattern
    self._name = name
    self._cwd = cwd
    self._condition = condition
    self._variables = variables
    self._verbose = verbose
    self._cwd_base = cwd_base

  @staticmethod
  def from_dict(d, variables=None, verbose=False, conditions=None,
                cwd_base=None):
    """Creates a Hook instance from a dict like in the DEPS file."""
    # Merge any local and inherited conditions.
    gclient_eval.UpdateCondition(d, 'and', conditions)
    return Hook(
        d['action'],
        d.get('pattern'),
        d.get('name'),
        d.get('cwd'),
        d.get('condition'),
        variables=variables,
        # Always print the header if not printing to a TTY.
        verbose=verbose or not setup_color.IS_TTY,
        cwd_base=cwd_base)

  @property
  def action(self):
    return self._action

  @property
  def pattern(self):
    return self._pattern

  @property
  def name(self):
    return self._name

  @property
  def condition(self):
    return self._condition

  @property
  def effective_cwd(self):
    cwd = self._cwd_base
    if self._cwd:
      cwd = os.path.join(cwd, self._cwd)
    return cwd

  def matches(self, file_list):
    """Returns true if the pattern matches any of files in the list."""
    if not self._pattern:
      return True
    pattern = re.compile(self._pattern)
    return bool([f for f in file_list if pattern.search(f)])

  def run(self):
    """Executes the hook's command (provided the condition is met)."""
    if (self._condition and
        not gclient_eval.EvaluateCondition(self._condition, self._variables)):
      return

    cmd = [arg for arg in self._action]

    if cmd[0] == 'python' and six.PY2:
      # If the hook specified "python" as the first item, the action is a
      # Python script. Run it by starting a new copy of the same interpreter if
      # we're running on Python 2.
      # On Python 3 we simply execute 'python'.
      cmd[0] = sys.executable
    elif cmd[0] == 'vpython' and _detect_host_os() == 'win':
      cmd[0] += '.bat'

    try:
      start_time = time.time()
      gclient_utils.CheckCallAndFilter(
          cmd, cwd=self.effective_cwd, print_stdout=True, show_header=True,
          always_show_header=self._verbose)
    except (gclient_utils.Error, subprocess2.CalledProcessError) as e:
      # Use a discrete exit status code of 2 to indicate that a hook action
      # failed.  Users of this script may wish to treat hook action failures
      # differently from VC failures.
      print('Error: %s' % str(e), file=sys.stderr)
      sys.exit(2)
    finally:
      elapsed_time = time.time() - start_time
      if elapsed_time > 10:
        print("Hook '%s' took %.2f secs" % (
            gclient_utils.CommandToStr(cmd), elapsed_time))


class DependencySettings(object):
  """Immutable configuration settings."""
  def __init__(
      self, parent, url, managed, custom_deps, custom_vars,
      custom_hooks, deps_file, should_process, relative, condition):
    # These are not mutable:
    self._parent = parent
    self._deps_file = deps_file
    self._url = url
    # The condition as string (or None). Useful to keep e.g. for flatten.
    self._condition = condition
    # 'managed' determines whether or not this dependency is synced/updated by
    # gclient after gclient checks it out initially.  The difference between
    # 'managed' and 'should_process' is that the user specifies 'managed' via
    # the --unmanaged command-line flag or a .gclient config, where
    # 'should_process' is dynamically set by gclient if it goes over its
    # recursion limit and controls gclient's behavior so it does not misbehave.
    self._managed = managed
    self._should_process = should_process
    # If this is a recursed-upon sub-dependency, and the parent has
    # use_relative_paths set, then this dependency should check out its own
    # dependencies relative to that parent's path for this, rather than
    # relative to the .gclient file.
    self._relative = relative
    # This is a mutable value which has the list of 'target_os' OSes listed in
    # the current deps file.
    self.local_target_os = None

    # These are only set in .gclient and not in DEPS files.
    self._custom_vars = custom_vars or {}
    self._custom_deps = custom_deps or {}
    self._custom_hooks = custom_hooks or []

    # Post process the url to remove trailing slashes.
    if isinstance(self.url, basestring):
      # urls are sometime incorrectly written as proto://host/path/@rev. Replace
      # it to proto://host/path@rev.
      self.set_url(self.url.replace('/@', '@'))
    elif not isinstance(self.url, (None.__class__)):
      raise gclient_utils.Error(
          ('dependency url must be either string or None, '
           'instead of %s') % self.url.__class__.__name__)

    # Make any deps_file path platform-appropriate.
    if self._deps_file:
      for sep in ['/', '\\']:
        self._deps_file = self._deps_file.replace(sep, os.sep)

  @property
  def deps_file(self):
    return self._deps_file

  @property
  def managed(self):
    return self._managed

  @property
  def parent(self):
    return self._parent

  @property
  def root(self):
    """Returns the root node, a GClient object."""
    if not self.parent:
      # This line is to signal pylint that it could be a GClient instance.
      return self or GClient(None, None)
    return self.parent.root

  @property
  def should_process(self):
    """True if this dependency should be processed, i.e. checked out."""
    return self._should_process

  @property
  def custom_vars(self):
    return self._custom_vars.copy()

  @property
  def custom_deps(self):
    return self._custom_deps.copy()

  @property
  def custom_hooks(self):
    return self._custom_hooks[:]

  @property
  def url(self):
    """URL after variable expansion."""
    return self._url

  @property
  def condition(self):
    return self._condition

  @property
  def target_os(self):
    if self.local_target_os is not None:
      return tuple(set(self.local_target_os).union(self.parent.target_os))
    else:
      return self.parent.target_os

  @property
  def target_cpu(self):
    return self.parent.target_cpu

  def set_url(self, url):
    self._url = url

  def get_custom_deps(self, name, url):
    """Returns a custom deps if applicable."""
    if self.parent:
      url = self.parent.get_custom_deps(name, url)
    # None is a valid return value to disable a dependency.
    return self.custom_deps.get(name, url)


class Dependency(gclient_utils.WorkItem, DependencySettings):
  """Object that represents a dependency checkout."""

  def __init__(self, parent, name, url, managed, custom_deps,
               custom_vars, custom_hooks, deps_file, should_process,
               should_recurse, relative, condition, print_outbuf=False):
    gclient_utils.WorkItem.__init__(self, name)
    DependencySettings.__init__(
        self, parent, url, managed, custom_deps, custom_vars,
        custom_hooks, deps_file, should_process, relative, condition)

    # This is in both .gclient and DEPS files:
    self._deps_hooks = []

    self._pre_deps_hooks = []

    # Calculates properties:
    self._dependencies = []
    self._vars = {}

    # A cache of the files affected by the current operation, necessary for
    # hooks.
    self._file_list = []
    # List of host names from which dependencies are allowed.
    # Default is an empty set, meaning unspecified in DEPS file, and hence all
    # hosts will be allowed. Non-empty set means whitelist of hosts.
    # allowed_hosts var is scoped to its DEPS file, and so it isn't recursive.
    self._allowed_hosts = frozenset()
    self._gn_args_from = None
    # Spec for .gni output to write (if any).
    self._gn_args_file = None
    self._gn_args = []
    # If it is not set to True, the dependency wasn't processed for its child
    # dependency, i.e. its DEPS wasn't read.
    self._deps_parsed = False
    # This dependency has been processed, i.e. checked out
    self._processed = False
    # This dependency had its pre-DEPS hooks run
    self._pre_deps_hooks_ran = False
    # This dependency had its hook run
    self._hooks_ran = False
    # This is the scm used to checkout self.url. It may be used by dependencies
    # to get the datetime of the revision we checked out.
    self._used_scm = None
    self._used_revision = None
    # The actual revision we ended up getting, or None if that information is
    # unavailable
    self._got_revision = None

    # recursedeps is a mutable value that selectively overrides the default
    # 'no recursion' setting on a dep-by-dep basis.
    #
    # It will be a dictionary of {deps_name: depfile_namee}
    self.recursedeps = {}

    # Whether we should process this dependency's DEPS file.
    self._should_recurse = should_recurse

    self._OverrideUrl()
    # This is inherited from WorkItem.  We want the URL to be a resource.
    if self.url and isinstance(self.url, basestring):
      # The url is usually given to gclient either as https://blah@123
      # or just https://blah.  The @123 portion is irrelevant.
      self.resources.append(self.url.split('@')[0])

    # Controls whether we want to print git's output when we first clone the
    # dependency
    self.print_outbuf = print_outbuf

    if not self.name and self.parent:
      raise gclient_utils.Error('Dependency without name')

  def _OverrideUrl(self):
    """Resolves the parsed url from the parent hierarchy."""
    parsed_url = self.get_custom_deps(self._name, self.url)
    if parsed_url != self.url:
      logging.info('Dependency(%s)._OverrideUrl(%s) -> %s', self._name,
                   self.url, parsed_url)
      self.set_url(parsed_url)

    elif isinstance(self.url, basestring):
      parsed_url = urlparse.urlparse(self.url)
      if (not parsed_url[0] and
          not re.match(r'^\w+\@[\w\.-]+\:[\w\/]+', parsed_url[2])):
        path = parsed_url[2]
        if not path.startswith('/'):
          raise gclient_utils.Error(
              'relative DEPS entry \'%s\' must begin with a slash' % self.url)
        # A relative url. Get the parent url, strip from the last '/'
        # (equivalent to unix basename), and append the relative url.
        parent_url = self.parent.url
        parsed_url = parent_url[:parent_url.rfind('/')] + self.url
        logging.info('Dependency(%s)._OverrideUrl(%s) -> %s', self.name,
                     self.url, parsed_url)
        self.set_url(parsed_url)

    elif self.url is None:
      logging.info('Dependency(%s)._OverrideUrl(None) -> None', self._name)

    else:
      raise gclient_utils.Error('Unknown url type')

  def PinToActualRevision(self):
    """Updates self.url to the revision checked out on disk."""
    if self.url is None:
      return
    url = None
    scm = self.CreateSCM()
    if os.path.isdir(scm.checkout_path):
      revision = scm.revinfo(None, None, None)
      url = '%s@%s' % (gclient_utils.SplitUrlRevision(self.url)[0], revision)
    self.set_url(url)

  def ToLines(self):
    s = []
    condition_part = (['    "condition": %r,' % self.condition]
                      if self.condition else [])
    s.extend([
        '  # %s' % self.hierarchy(include_url=False),
        '  "%s": {' % (self.name,),
        '    "url": "%s",' % (self.url,),
    ] + condition_part + [
        '  },',
        '',
    ])
    return s

  @property
  def requirements(self):
    """Calculate the list of requirements."""
    requirements = set()
    # self.parent is implicitly a requirement. This will be recursive by
    # definition.
    if self.parent and self.parent.name:
      requirements.add(self.parent.name)

    # For a tree with at least 2 levels*, the leaf node needs to depend
    # on the level higher up in an orderly way.
    # This becomes messy for >2 depth as the DEPS file format is a dictionary,
    # thus unsorted, while the .gclient format is a list thus sorted.
    #
    # Interestingly enough, the following condition only works in the case we
    # want: self is a 2nd level node. 3nd level node wouldn't need this since
    # they already have their parent as a requirement.
    if self.parent and self.parent.parent and not self.parent.parent.parent:
      requirements |= set(i.name for i in self.root.dependencies if i.name)

    if self.name:
      requirements |= set(
          obj.name for obj in self.root.subtree(False)
          if (obj is not self
              and obj.name and
              self.name.startswith(posixpath.join(obj.name, ''))))
    requirements = tuple(sorted(requirements))
    logging.info('Dependency(%s).requirements = %s' % (self.name, requirements))
    return requirements

  @property
  def should_recurse(self):
    return self._should_recurse

  def verify_validity(self):
    """Verifies that this Dependency is fine to add as a child of another one.

    Returns True if this entry should be added, False if it is a duplicate of
    another entry.
    """
    logging.info('Dependency(%s).verify_validity()' % self.name)
    if self.name in [s.name for s in self.parent.dependencies]:
      raise gclient_utils.Error(
          'The same name "%s" appears multiple times in the deps section' %
              self.name)
    if not self.should_process:
      # Return early, no need to set requirements.
      return not any(d.name == self.name for d in self.root.subtree(True))

    # This require a full tree traversal with locks.
    siblings = [d for d in self.root.subtree(False) if d.name == self.name]
    for sibling in siblings:
      # Allow to have only one to be None or ''.
      if self.url != sibling.url and bool(self.url) == bool(sibling.url):
        raise gclient_utils.Error(
            ('Dependency %s specified more than once:\n'
            '  %s [%s]\n'
            'vs\n'
            '  %s [%s]') % (
              self.name,
              sibling.hierarchy(),
              sibling.url,
              self.hierarchy(),
              self.url))
      # In theory we could keep it as a shadow of the other one. In
      # practice, simply ignore it.
      logging.warn('Won\'t process duplicate dependency %s' % sibling)
      return False
    return True

  def _postprocess_deps(self, deps, rel_prefix):
    """Performs post-processing of deps compared to what's in the DEPS file."""
    # Make sure the dict is mutable, e.g. in case it's frozen.
    deps = dict(deps)

    # If a line is in custom_deps, but not in the solution, we want to append
    # this line to the solution.
    for dep_name, dep_info in six.iteritems(self.custom_deps):
      if dep_name not in deps:
        deps[dep_name] = {'url': dep_info, 'dep_type': 'git'}

    # Make child deps conditional on any parent conditions. This ensures that,
    # when flattened, recursed entries have the correct restrictions, even if
    # not explicitly set in the recursed DEPS file. For instance, if
    # "src/ios_foo" is conditional on "checkout_ios=True", then anything
    # recursively included by "src/ios_foo/DEPS" should also require
    # "checkout_ios=True".
    if self.condition:
      for value in six.itervalues(deps):
        gclient_eval.UpdateCondition(value, 'and', self.condition)

    if rel_prefix:
      logging.warning('use_relative_paths enabled.')
      rel_deps = {}
      for d, url in six.iteritems(deps):
        # normpath is required to allow DEPS to use .. in their
        # dependency local path.
        rel_deps[os.path.normpath(os.path.join(rel_prefix, d))] = url
      logging.warning('Updating deps by prepending %s.', rel_prefix)
      deps = rel_deps

    return deps

  def _deps_to_objects(self, deps, use_relative_paths):
    """Convert a deps dict to a dict of Dependency objects."""
    deps_to_add = []
    for name, dep_value in six.iteritems(deps):
      should_process = self.should_process
      if dep_value is None:
        continue

      condition = dep_value.get('condition')
      dep_type = dep_value.get('dep_type')

      if condition and not self._get_option('process_all_deps', False):
        should_process = should_process and gclient_eval.EvaluateCondition(
            condition, self.get_vars())

      # The following option is only set by the 'revinfo' command.
      if self._get_option('ignore_dep_type', None) == dep_type:
        continue

      if dep_type == 'cipd':
        cipd_root = self.GetCipdRoot()
        for package in dep_value.get('packages', []):
          deps_to_add.append(
              CipdDependency(
                  parent=self,
                  name=name,
                  dep_value=package,
                  cipd_root=cipd_root,
                  custom_vars=self.custom_vars,
                  should_process=should_process,
                  relative=use_relative_paths,
                  condition=condition))
      else:
        url = dep_value.get('url')
        deps_to_add.append(
            GitDependency(
                parent=self,
                name=name,
                url=url,
                managed=True,
                custom_deps=None,
                custom_vars=self.custom_vars,
                custom_hooks=None,
                deps_file=self.recursedeps.get(name, self.deps_file),
                should_process=should_process,
                should_recurse=name in self.recursedeps,
                relative=use_relative_paths,
                condition=condition))

    deps_to_add.sort(key=lambda x: x.name)
    return deps_to_add

  def ParseDepsFile(self):
    """Parses the DEPS file for this dependency."""
    assert not self.deps_parsed
    assert not self.dependencies

    deps_content = None

    # First try to locate the configured deps file.  If it's missing, fallback
    # to DEPS.
    deps_files = [self.deps_file]
    if 'DEPS' not in deps_files:
      deps_files.append('DEPS')
    for deps_file in deps_files:
      filepath = os.path.join(self.root.root_dir, self.name, deps_file)
      if os.path.isfile(filepath):
        logging.info(
            'ParseDepsFile(%s): %s file found at %s', self.name, deps_file,
            filepath)
        break
      logging.info(
          'ParseDepsFile(%s): No %s file found at %s', self.name, deps_file,
          filepath)

    if os.path.isfile(filepath):
      deps_content = gclient_utils.FileRead(filepath)
      logging.debug('ParseDepsFile(%s) read:\n%s', self.name, deps_content)

    local_scope = {}
    if deps_content:
      try:
        local_scope = gclient_eval.Parse(
            deps_content, self._get_option('validate_syntax', False),
            filepath, self.get_vars(), self.get_builtin_vars())
      except SyntaxError as e:
        gclient_utils.SyntaxErrorToError(filepath, e)

    if 'allowed_hosts' in local_scope:
      try:
        self._allowed_hosts = frozenset(local_scope.get('allowed_hosts'))
      except TypeError:  # raised if non-iterable
        pass
      if not self._allowed_hosts:
        logging.warning("allowed_hosts is specified but empty %s",
                        self._allowed_hosts)
        raise gclient_utils.Error(
            'ParseDepsFile(%s): allowed_hosts must be absent '
            'or a non-empty iterable' % self.name)

    self._gn_args_from = local_scope.get('gclient_gn_args_from')
    self._gn_args_file = local_scope.get('gclient_gn_args_file')
    self._gn_args = local_scope.get('gclient_gn_args', [])
    # It doesn't make sense to set all of these, since setting gn_args_from to
    # another DEPS will make gclient ignore any other local gn_args* settings.
    assert not (self._gn_args_from and self._gn_args_file), \
        'Only specify one of "gclient_gn_args_from" or ' \
        '"gclient_gn_args_file + gclient_gn_args".'

    self._vars = local_scope.get('vars', {})
    if self.parent:
      for key, value in six.iteritems(self.parent.get_vars()):
        if key in self._vars:
          self._vars[key] = value
    # Since we heavily post-process things, freeze ones which should
    # reflect original state of DEPS.
    self._vars = gclient_utils.freeze(self._vars)

    # If use_relative_paths is set in the DEPS file, regenerate
    # the dictionary using paths relative to the directory containing
    # the DEPS file.  Also update recursedeps if use_relative_paths is
    # enabled.
    # If the deps file doesn't set use_relative_paths, but the parent did
    # (and therefore set self.relative on this Dependency object), then we
    # want to modify the deps and recursedeps by prepending the parent
    # directory of this dependency.
    use_relative_paths = local_scope.get('use_relative_paths', False)
    rel_prefix = None
    if use_relative_paths:
      rel_prefix = self.name
    elif self._relative:
      rel_prefix = os.path.dirname(self.name)

    if 'recursion' in local_scope:
      logging.warning(
          '%s: Ignoring recursion = %d.', self.name, local_scope['recursion'])

    if 'recursedeps' in local_scope:
      for ent in local_scope['recursedeps']:
        if isinstance(ent, basestring):
          self.recursedeps[ent] = self.deps_file
        else:  # (depname, depsfilename)
          self.recursedeps[ent[0]] = ent[1]
      logging.warning('Found recursedeps %r.', repr(self.recursedeps))

      if rel_prefix:
        logging.warning('Updating recursedeps by prepending %s.', rel_prefix)
        rel_deps = {}
        for depname, options in six.iteritems(self.recursedeps):
          rel_deps[
              os.path.normpath(os.path.join(rel_prefix, depname))] = options
        self.recursedeps = rel_deps
    # To get gn_args from another DEPS, that DEPS must be recursed into.
    if self._gn_args_from:
      assert self.recursedeps and self._gn_args_from in self.recursedeps, \
              'The "gclient_gn_args_from" value must be in recursedeps.'

    # If present, save 'target_os' in the local_target_os property.
    if 'target_os' in local_scope:
      self.local_target_os = local_scope['target_os']

    deps = local_scope.get('deps', {})
    deps_to_add = self._deps_to_objects(
        self._postprocess_deps(deps, rel_prefix), use_relative_paths)

    # compute which working directory should be used for hooks
    use_relative_hooks = local_scope.get('use_relative_hooks', False)
    hooks_cwd = self.root.root_dir
    if use_relative_hooks:
      if not use_relative_paths:
        raise gclient_utils.Error(
            'ParseDepsFile(%s): use_relative_hooks must be used with '
            'use_relative_paths' % self.name)
      hooks_cwd = os.path.join(hooks_cwd, self.name)
      logging.warning('Updating hook base working directory to %s.',
                      hooks_cwd)

    # override named sets of hooks by the custom hooks
    hooks_to_run = []
    hook_names_to_suppress = [c.get('name', '') for c in self.custom_hooks]
    for hook in local_scope.get('hooks', []):
      if hook.get('name', '') not in hook_names_to_suppress:
        hooks_to_run.append(hook)

    # add the replacements and any additions
    for hook in self.custom_hooks:
      if 'action' in hook:
        hooks_to_run.append(hook)

    if self.should_recurse:
      self._pre_deps_hooks = [
          Hook.from_dict(hook, variables=self.get_vars(), verbose=True,
                         conditions=self.condition, cwd_base=hooks_cwd)
          for hook in local_scope.get('pre_deps_hooks', [])
      ]

    self.add_dependencies_and_close(deps_to_add, hooks_to_run,
                                    hooks_cwd=hooks_cwd)
    logging.info('ParseDepsFile(%s) done' % self.name)

  def _get_option(self, attr, default):
    obj = self
    while not hasattr(obj, '_options'):
      obj = obj.parent
    return getattr(obj._options, attr, default)

  def add_dependencies_and_close(self, deps_to_add, hooks, hooks_cwd=None):
    """Adds the dependencies, hooks and mark the parsing as done."""
    if hooks_cwd == None:
      hooks_cwd = self.root.root_dir

    for dep in deps_to_add:
      if dep.verify_validity():
        self.add_dependency(dep)
    self._mark_as_parsed([
        Hook.from_dict(
            h, variables=self.get_vars(), verbose=self.root._options.verbose,
            conditions=self.condition, cwd_base=hooks_cwd)
        for h in hooks
    ])

  def findDepsFromNotAllowedHosts(self):
    """Returns a list of dependencies from not allowed hosts.

    If allowed_hosts is not set, allows all hosts and returns empty list.
    """
    if not self._allowed_hosts:
      return []
    bad_deps = []
    for dep in self._dependencies:
      # Don't enforce this for custom_deps.
      if dep.name in self._custom_deps:
        continue
      if isinstance(dep.url, basestring):
        parsed_url = urlparse.urlparse(dep.url)
        if parsed_url.netloc and parsed_url.netloc not in self._allowed_hosts:
          bad_deps.append(dep)
    return bad_deps

  def FuzzyMatchUrl(self, candidates):
    """Attempts to find this dependency in the list of candidates.

    It looks first for the URL of this dependency in the list of
    candidates. If it doesn't succeed, and the URL ends in '.git', it will try
    looking for the URL minus '.git'. Finally it will try to look for the name
    of the dependency.

    Args:
      candidates: list, dict. The list of candidates in which to look for this
          dependency. It can contain URLs as above, or dependency names like
          "src/some/dep".

    Returns:
      If this dependency is not found in the list of candidates, returns None.
      Otherwise, it returns under which name did we find this dependency:
       - Its parsed url: "https://example.com/src.git'
       - Its parsed url minus '.git': "https://example.com/src"
       - Its name: "src"
    """
    if self.url:
      origin, _ = gclient_utils.SplitUrlRevision(self.url)
      if origin in candidates:
        return origin
      if origin.endswith('.git') and origin[:-len('.git')] in candidates:
        return origin[:-len('.git')]
      if origin + '.git' in candidates:
        return origin + '.git'
    if self.name in candidates:
      return self.name
    return None

  # Arguments number differs from overridden method
  # pylint: disable=arguments-differ
  def run(self, revision_overrides, command, args, work_queue, options,
          patch_refs, target_branches):
    """Runs |command| then parse the DEPS file."""
    logging.info('Dependency(%s).run()' % self.name)
    assert self._file_list == []
    if not self.should_process:
      return
    # When running runhooks, there's no need to consult the SCM.
    # All known hooks are expected to run unconditionally regardless of working
    # copy state, so skip the SCM status check.
    run_scm = command not in (
        'flatten', 'runhooks', 'recurse', 'validate', None)
    file_list = [] if not options.nohooks else None
    revision_override = revision_overrides.pop(
        self.FuzzyMatchUrl(revision_overrides), None)
    if not revision_override and not self.managed:
      revision_override = 'unmanaged'
    if run_scm and self.url:
      # Create a shallow copy to mutate revision.
      options = copy.copy(options)
      options.revision = revision_override
      self._used_revision = options.revision
      self._used_scm = self.CreateSCM(out_cb=work_queue.out_cb)
      self._got_revision = self._used_scm.RunCommand(command, options, args,
                                                     file_list)

      patch_repo = self.url.split('@')[0]
      patch_ref = patch_refs.pop(self.FuzzyMatchUrl(patch_refs), None)
      target_branch = target_branches.pop(
          self.FuzzyMatchUrl(target_branches), None)
      if command == 'update' and patch_ref is not None:
        self._used_scm.apply_patch_ref(patch_repo, patch_ref, target_branch,
                                       options, file_list)

      if file_list:
        file_list = [os.path.join(self.name, f.strip()) for f in file_list]

      # TODO(phajdan.jr): We should know exactly when the paths are absolute.
      # Convert all absolute paths to relative.
      for i in range(len(file_list or [])):
        # It depends on the command being executed (like runhooks vs sync).
        if not os.path.isabs(file_list[i]):
          continue
        prefix = os.path.commonprefix(
            [self.root.root_dir.lower(), file_list[i].lower()])
        file_list[i] = file_list[i][len(prefix):]
        # Strip any leading path separators.
        while file_list[i].startswith(('\\', '/')):
          file_list[i] = file_list[i][1:]

    if self.should_recurse:
      self.ParseDepsFile()

    self._run_is_done(file_list or [])

    if self.should_recurse:
      if command in ('update', 'revert') and not options.noprehooks:
        self.RunPreDepsHooks()
      # Parse the dependencies of this dependency.
      for s in self.dependencies:
        if s.should_process:
          work_queue.enqueue(s)

    if command == 'recurse':
      # Skip file only checkout.
      scm = self.GetScmName()
      if not options.scm or scm in options.scm:
        cwd = os.path.normpath(os.path.join(self.root.root_dir, self.name))
        # Pass in the SCM type as an env variable.  Make sure we don't put
        # unicode strings in the environment.
        env = os.environ.copy()
        if scm:
          env['GCLIENT_SCM'] = str(scm)
        if self.url:
          env['GCLIENT_URL'] = str(self.url)
        env['GCLIENT_DEP_PATH'] = str(self.name)
        if options.prepend_dir and scm == 'git':
          print_stdout = False
          def filter_fn(line):
            """Git-specific path marshaling. It is optimized for git-grep."""

            def mod_path(git_pathspec):
              match = re.match('^(\\S+?:)?([^\0]+)$', git_pathspec)
              modified_path = os.path.join(self.name, match.group(2))
              branch = match.group(1) or ''
              return '%s%s' % (branch, modified_path)

            match = re.match('^Binary file ([^\0]+) matches$', line)
            if match:
              print('Binary file %s matches\n' % mod_path(match.group(1)))
              return

            items = line.split('\0')
            if len(items) == 2 and items[1]:
              print('%s : %s' % (mod_path(items[0]), items[1]))
            elif len(items) >= 2:
              # Multiple null bytes or a single trailing null byte indicate
              # git is likely displaying filenames only (such as with -l)
              print('\n'.join(mod_path(path) for path in items if path))
            else:
              print(line)
        else:
          print_stdout = True
          filter_fn = None

        if self.url is None:
          print('Skipped omitted dependency %s' % cwd, file=sys.stderr)
        elif os.path.isdir(cwd):
          try:
            gclient_utils.CheckCallAndFilter(
                args, cwd=cwd, env=env, print_stdout=print_stdout,
                filter_fn=filter_fn,
                )
          except subprocess2.CalledProcessError:
            if not options.ignore:
              raise
        else:
          print('Skipped missing %s' % cwd, file=sys.stderr)

  def GetScmName(self):
    raise NotImplementedError()

  def CreateSCM(self, out_cb=None):
    raise NotImplementedError()

  def HasGNArgsFile(self):
    return self._gn_args_file is not None

  def WriteGNArgsFile(self):
    lines = ['# Generated from %r' % self.deps_file]
    variables = self.get_vars()
    for arg in self._gn_args:
      value = variables[arg]
      if isinstance(value, basestring):
        value = gclient_eval.EvaluateCondition(value, variables)
      lines.append('%s = %s' % (arg, ToGNString(value)))
    with open(os.path.join(self.root.root_dir, self._gn_args_file), 'w') as f:
      f.write('\n'.join(lines))

  @gclient_utils.lockedmethod
  def _run_is_done(self, file_list):
    # Both these are kept for hooks that are run as a separate tree traversal.
    self._file_list = file_list
    self._processed = True

  def GetHooks(self, options):
    """Evaluates all hooks, and return them in a flat list.

    RunOnDeps() must have been called before to load the DEPS.
    """
    result = []
    if not self.should_process or not self.should_recurse:
      # Don't run the hook when it is above recursion_limit.
      return result
    # If "--force" was specified, run all hooks regardless of what files have
    # changed.
    if self.deps_hooks:
      # TODO(maruel): If the user is using git, then we don't know
      # what files have changed so we always run all hooks. It'd be nice to fix
      # that.
      result.extend(self.deps_hooks)
    for s in self.dependencies:
      result.extend(s.GetHooks(options))
    return result

  def RunHooksRecursively(self, options, progress):
    assert self.hooks_ran == False
    self._hooks_ran = True
    hooks = self.GetHooks(options)
    if progress:
      progress._total = len(hooks)
    for hook in hooks:
      if progress:
        progress.update(extra=hook.name or '')
      hook.run()
    if progress:
      progress.end()

  def RunPreDepsHooks(self):
    assert self.processed
    assert self.deps_parsed
    assert not self.pre_deps_hooks_ran
    assert not self.hooks_ran
    for s in self.dependencies:
      assert not s.processed
    self._pre_deps_hooks_ran = True
    for hook in self.pre_deps_hooks:
      hook.run()

  def GetCipdRoot(self):
    if self.root is self:
      # Let's not infinitely recurse. If this is root and isn't an
      # instance of GClient, do nothing.
      return None
    return self.root.GetCipdRoot()

  def subtree(self, include_all):
    """Breadth first recursion excluding root node."""
    dependencies = self.dependencies
    for d in dependencies:
      if d.should_process or include_all:
        yield d
    for d in dependencies:
      for i in d.subtree(include_all):
        yield i

  @gclient_utils.lockedmethod
  def add_dependency(self, new_dep):
    self._dependencies.append(new_dep)

  @gclient_utils.lockedmethod
  def _mark_as_parsed(self, new_hooks):
    self._deps_hooks.extend(new_hooks)
    self._deps_parsed = True

  @property
  @gclient_utils.lockedmethod
  def dependencies(self):
    return tuple(self._dependencies)

  @property
  @gclient_utils.lockedmethod
  def deps_hooks(self):
    return tuple(self._deps_hooks)

  @property
  @gclient_utils.lockedmethod
  def pre_deps_hooks(self):
    return tuple(self._pre_deps_hooks)

  @property
  @gclient_utils.lockedmethod
  def deps_parsed(self):
    """This is purely for debugging purposes. It's not used anywhere."""
    return self._deps_parsed

  @property
  @gclient_utils.lockedmethod
  def processed(self):
    return self._processed

  @property
  @gclient_utils.lockedmethod
  def pre_deps_hooks_ran(self):
    return self._pre_deps_hooks_ran

  @property
  @gclient_utils.lockedmethod
  def hooks_ran(self):
    return self._hooks_ran

  @property
  @gclient_utils.lockedmethod
  def allowed_hosts(self):
    return self._allowed_hosts

  @property
  @gclient_utils.lockedmethod
  def file_list(self):
    return tuple(self._file_list)

  @property
  def used_scm(self):
    """SCMWrapper instance for this dependency or None if not processed yet."""
    return self._used_scm

  @property
  @gclient_utils.lockedmethod
  def got_revision(self):
    return self._got_revision

  @property
  def file_list_and_children(self):
    result = list(self.file_list)
    for d in self.dependencies:
      result.extend(d.file_list_and_children)
    return tuple(result)

  def __str__(self):
    out = []
    for i in ('name', 'url', 'custom_deps',
              'custom_vars', 'deps_hooks', 'file_list', 'should_process',
              'processed', 'hooks_ran', 'deps_parsed', 'requirements',
              'allowed_hosts'):
      # First try the native property if it exists.
      if hasattr(self, '_' + i):
        value = getattr(self, '_' + i, False)
      else:
        value = getattr(self, i, False)
      if value:
        out.append('%s: %s' % (i, value))

    for d in self.dependencies:
      out.extend(['  ' + x for x in str(d).splitlines()])
      out.append('')
    return '\n'.join(out)

  def __repr__(self):
    return '%s: %s' % (self.name, self.url)

  def hierarchy(self, include_url=True):
    """Returns a human-readable hierarchical reference to a Dependency."""
    def format_name(d):
      if include_url:
        return '%s(%s)' % (d.name, d.url)
      return d.name
    out = format_name(self)
    i = self.parent
    while i and i.name:
      out = '%s -> %s' % (format_name(i), out)
      i = i.parent
    return out

  def hierarchy_data(self):
    """Returns a machine-readable hierarchical reference to a Dependency."""
    d = self
    out = []
    while d and d.name:
      out.insert(0, (d.name, d.url))
      d = d.parent
    return tuple(out)

  def get_builtin_vars(self):
    return {
        'checkout_android': 'android' in self.target_os,
        'checkout_chromeos': 'chromeos' in self.target_os,
        'checkout_fuchsia': 'fuchsia' in self.target_os,
        'checkout_ios': 'ios' in self.target_os,
        'checkout_linux': 'unix' in self.target_os,
        'checkout_mac': 'mac' in self.target_os,
        'checkout_win': 'win' in self.target_os,
        'host_os': _detect_host_os(),

        'checkout_arm': 'arm' in self.target_cpu,
        'checkout_arm64': 'arm64' in self.target_cpu,
        'checkout_x86': 'x86' in self.target_cpu,
        'checkout_mips': 'mips' in self.target_cpu,
        'checkout_mips64': 'mips64' in self.target_cpu,
        'checkout_ppc': 'ppc' in self.target_cpu,
        'checkout_s390': 's390' in self.target_cpu,
        'checkout_x64': 'x64' in self.target_cpu,
        'host_cpu': detect_host_arch.HostArch(),
    }

  def get_vars(self):
    """Returns a dictionary of effective variable values
    (DEPS file contents with applied custom_vars overrides)."""
    # Variable precedence (last has highest):
    # - DEPS vars
    # - parents, from first to last
    # - built-in
    # - custom_vars overrides
    result = {}
    result.update(self._vars)
    if self.parent:
      parent_vars = self.parent.get_vars()
      result.update(parent_vars)
    # Provide some built-in variables.
    result.update(self.get_builtin_vars())
    result.update(self.custom_vars or {})
    return result


_PLATFORM_MAPPING = {
  'cygwin': 'win',
  'darwin': 'mac',
  'linux2': 'linux',
  'linux': 'linux',
  'win32': 'win',
  'aix6': 'aix',
}


def _detect_host_os():
  return _PLATFORM_MAPPING[sys.platform]


class GitDependency(Dependency):
  """A Dependency object that represents a single git checkout."""

  #override
  def GetScmName(self):
    """Always 'git'."""
    return 'git'

  #override
  def CreateSCM(self, out_cb=None):
    """Create a Wrapper instance suitable for handling this git dependency."""
    return gclient_scm.GitWrapper(
        self.url, self.root.root_dir, self.name, self.outbuf, out_cb,
        print_outbuf=self.print_outbuf)


class GClient(GitDependency):
  """Object that represent a gclient checkout. A tree of Dependency(), one per
  solution or DEPS entry."""

  DEPS_OS_CHOICES = {
    "aix6": "unix",
    "win32": "win",
    "win": "win",
    "cygwin": "win",
    "darwin": "mac",
    "mac": "mac",
    "unix": "unix",
    "linux": "unix",
    "linux2": "unix",
    "linux3": "unix",
    "android": "android",
    "ios": "ios",
    "fuchsia": "fuchsia",
    "chromeos": "chromeos",
  }

  DEFAULT_CLIENT_FILE_TEXT = ("""\
solutions = [
  { "name"        : "%(solution_name)s",
    "url"         : "%(solution_url)s",
    "deps_file"   : "%(deps_file)s",
    "managed"     : %(managed)s,
    "custom_deps" : {
    },
    "custom_vars": %(custom_vars)r,
  },
]
""")

  DEFAULT_CLIENT_CACHE_DIR_TEXT = ("""\
cache_dir = %(cache_dir)r
""")


  DEFAULT_SNAPSHOT_FILE_TEXT = ("""\
# Snapshot generated with gclient revinfo --snapshot
solutions = %(solution_list)s
""")

  def __init__(self, root_dir, options):
    # Do not change previous behavior. Only solution level and immediate DEPS
    # are processed.
    self._recursion_limit = 2
    super(GClient, self).__init__(
        parent=None,
        name=None,
        url=None,
        managed=True,
        custom_deps=None,
        custom_vars=None,
        custom_hooks=None,
        deps_file='unused',
        should_process=True,
        should_recurse=True,
        relative=None,
        condition=None,
        print_outbuf=True)

    self._options = options
    if options.deps_os:
      enforced_os = options.deps_os.split(',')
    else:
      enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')]
    if 'all' in enforced_os:
      enforced_os = self.DEPS_OS_CHOICES.values()
    self._enforced_os = tuple(set(enforced_os))
    self._enforced_cpu = detect_host_arch.HostArch(),
    self._root_dir = root_dir
    self._cipd_root = None
    self.config_content = None

  def _CheckConfig(self):
    """Verify that the config matches the state of the existing checked-out
    solutions."""
    for dep in self.dependencies:
      if dep.managed and dep.url:
        scm = dep.CreateSCM()
        actual_url = scm.GetActualRemoteURL(self._options)
        if actual_url and not scm.DoesRemoteURLMatch(self._options):
          mirror = scm.GetCacheMirror()
          if mirror:
            mirror_string = '%s (exists=%s)' % (mirror.mirror_path,
                                                mirror.exists())
          else:
            mirror_string = 'not used'
          raise gclient_utils.Error(
              '''
Your .gclient file seems to be broken. The requested URL is different from what
is actually checked out in %(checkout_path)s.

The .gclient file contains:
URL: %(expected_url)s (%(expected_scm)s)
Cache mirror: %(mirror_string)s

The local checkout in %(checkout_path)s reports:
%(actual_url)s (%(actual_scm)s)

You should ensure that the URL listed in .gclient is correct and either change
it or fix the checkout.
'''  % {'checkout_path': os.path.join(self.root_dir, dep.name),
        'expected_url': dep.url,
        'expected_scm': dep.GetScmName(),
        'mirror_string': mirror_string,
        'actual_url': actual_url,
        'actual_scm': dep.GetScmName()})

  def SetConfig(self, content):
    assert not self.dependencies
    config_dict = {}
    self.config_content = content
    try:
      exec(content, config_dict)
    except SyntaxError as e:
      gclient_utils.SyntaxErrorToError('.gclient', e)

    # Append any target OS that is not already being enforced to the tuple.
    target_os = config_dict.get('target_os', [])
    if config_dict.get('target_os_only', False):
      self._enforced_os = tuple(set(target_os))
    else:
      self._enforced_os = tuple(set(self._enforced_os).union(target_os))

    # Append any target CPU that is not already being enforced to the tuple.
    target_cpu = config_dict.get('target_cpu', [])
    if config_dict.get('target_cpu_only', False):
      self._enforced_cpu = tuple(set(target_cpu))
    else:
      self._enforced_cpu = tuple(set(self._enforced_cpu).union(target_cpu))

    cache_dir = config_dict.get('cache_dir', UNSET_CACHE_DIR)
    if cache_dir is not UNSET_CACHE_DIR:
      if cache_dir:
        cache_dir = os.path.join(self.root_dir, cache_dir)
        cache_dir = os.path.abspath(cache_dir)

      git_cache.Mirror.SetCachePath(cache_dir)

    if not target_os and config_dict.get('target_os_only', False):
      raise gclient_utils.Error('Can\'t use target_os_only if target_os is '
                                'not specified')

    if not target_cpu and config_dict.get('target_cpu_only', False):
      raise gclient_utils.Error('Can\'t use target_cpu_only if target_cpu is '
                                'not specified')

    deps_to_add = []
    for s in config_dict.get('solutions', []):
      try:
        deps_to_add.append(GitDependency(
            parent=self,
            name=s['name'],
            url=s['url'],
            managed=s.get('managed', True),
            custom_deps=s.get('custom_deps', {}),
            custom_vars=s.get('custom_vars', {}),
            custom_hooks=s.get('custom_hooks', []),
            deps_file=s.get('deps_file', 'DEPS'),
            should_process=True,
            should_recurse=True,
            relative=None,
            condition=None,
            print_outbuf=True))
      except KeyError:
        raise gclient_utils.Error('Invalid .gclient file. Solution is '
                                  'incomplete: %s' % s)
    metrics.collector.add(
        'project_urls',
        [
            dep.FuzzyMatchUrl(metrics_utils.KNOWN_PROJECT_URLS)
            for dep in deps_to_add
            if dep.FuzzyMatchUrl(metrics_utils.KNOWN_PROJECT_URLS)
        ]
    )

    self.add_dependencies_and_close(deps_to_add, config_dict.get('hooks', []))
    logging.info('SetConfig() done')

  def SaveConfig(self):
    gclient_utils.FileWrite(os.path.join(self.root_dir,
                                         self._options.config_filename),
                            self.config_content)

  @staticmethod
  def LoadCurrentConfig(options):
    """Searches for and loads a .gclient file relative to the current working
    dir. Returns a GClient object."""
    if options.spec:
      client = GClient('.', options)
      client.SetConfig(options.spec)
    else:
      if options.verbose:
        print('Looking for %s starting from %s\n' % (
            options.config_filename, os.getcwd()))
      path = gclient_paths.FindGclientRoot(os.getcwd(), options.config_filename)
      if not path:
        if options.verbose:
          print('Couldn\'t find configuration file.')
        return None
      client = GClient(path, options)
      client.SetConfig(gclient_utils.FileRead(
          os.path.join(path, options.config_filename)))

    if (options.revisions and
        len(client.dependencies) > 1 and
        any('@' not in r for r in options.revisions)):
      print(
          ('You must specify the full solution name like --revision %s@%s\n'
           'when you have multiple solutions setup in your .gclient file.\n'
           'Other solutions present are: %s.') % (
              client.dependencies[0].name,
              options.revisions[0],
              ', '.join(s.name for s in client.dependencies[1:])),
          file=sys.stderr)
    return client

  def SetDefaultConfig(self, solution_name, deps_file, solution_url,
                       managed=True, cache_dir=UNSET_CACHE_DIR,
                       custom_vars=None):
    text = self.DEFAULT_CLIENT_FILE_TEXT
    format_dict = {
      'solution_name': solution_name,
      'solution_url': solution_url,
      'deps_file': deps_file,
      'managed': managed,
      'custom_vars': custom_vars or {},
    }

    if cache_dir is not UNSET_CACHE_DIR:
      text += self.DEFAULT_CLIENT_CACHE_DIR_TEXT
      format_dict['cache_dir'] = cache_dir

    self.SetConfig(text % format_dict)

  def _SaveEntries(self):
    """Creates a .gclient_entries file to record the list of unique checkouts.

    The .gclient_entries file lives in the same directory as .gclient.
    """
    # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It
    # makes testing a bit too fun.
    result = 'entries = {\n'
    for entry in self.root.subtree(False):
      result += '  %s: %s,\n' % (pprint.pformat(entry.name),
          pprint.pformat(entry.url))
    result += '}\n'
    file_path = os.path.join(self.root_dir, self._options.entries_filename)
    logging.debug(result)
    gclient_utils.FileWrite(file_path, result)

  def _ReadEntries(self):
    """Read the .gclient_entries file for the given client.

    Returns:
      A sequence of solution names, which will be empty if there is the
      entries file hasn't been created yet.
    """
    scope = {}
    filename = os.path.join(self.root_dir, self._options.entries_filename)
    if not os.path.exists(filename):
      return {}
    try:
      exec(gclient_utils.FileRead(filename), scope)
    except SyntaxError as e:
      gclient_utils.SyntaxErrorToError(filename, e)
    return scope.get('entries', {})

  def _EnforceRevisions(self):
    """Checks for revision overrides."""
    revision_overrides = {}
    if self._options.head:
      return revision_overrides
    if not self._options.revisions:
      return revision_overrides
    solutions_names = [s.name for s in self.dependencies]
    index = 0
    for revision in self._options.revisions:
      if not '@' in revision:
        # Support for --revision 123
        revision = '%s@%s' % (solutions_names[index], revision)
      name, rev = revision.split('@', 1)
      revision_overrides[name] = rev
      index += 1
    return revision_overrides

  def _EnforcePatchRefsAndBranches(self):
    """Checks for patch refs."""
    patch_refs = {}
    target_branches = {}
    if not self._options.patch_refs:
      return patch_refs, target_branches
    for given_patch_ref in self._options.patch_refs:
      patch_repo, _, patch_ref = given_patch_ref.partition('@')
      if not patch_repo or not patch_ref or ':' not in patch_ref:
        raise gclient_utils.Error(
            'Wrong revision format: %s should be of the form '
            'patch_repo@target_branch:patch_ref.' % given_patch_ref)
      target_branch, _, patch_ref = patch_ref.partition(':')
      target_branches[patch_repo] = target_branch
      patch_refs[patch_repo] = patch_ref
    return patch_refs, target_branches

  def _RemoveUnversionedGitDirs(self):
    """Remove directories that are no longer part of the checkout.

    Notify the user if there is an orphaned entry in their working copy.
    Only delete the directory if there are no changes in it, and
    delete_unversioned_trees is set to true.
    """

    entries = [i.name for i in self.root.subtree(False) if i.url]
    full_entries = [os.path.join(self.root_dir, e.replace('/', os.path.sep))
                    for e in entries]

    for entry, prev_url in six.iteritems(self._ReadEntries()):
      if not prev_url:
        # entry must have been overridden via .gclient custom_deps
        continue
      # Fix path separator on Windows.
      entry_fixed = entry.replace('/', os.path.sep)
      e_dir = os.path.join(self.root_dir, entry_fixed)
      # Use entry and not entry_fixed there.
      if (entry not in entries and
          (not any(path.startswith(entry + '/') for path in entries)) and
          os.path.exists(e_dir)):
        # The entry has been removed from DEPS.
        scm = gclient_scm.GitWrapper(
            prev_url, self.root_dir, entry_fixed, self.outbuf)

        # Check to see if this directory is now part of a higher-up checkout.
        scm_root = None
        try:
          scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(scm.checkout_path)
        except subprocess2.CalledProcessError:
          pass
        if not scm_root:
          logging.warning('Could not find checkout root for %s. Unable to '
                          'determine whether it is part of a higher-level '
                          'checkout, so not removing.' % entry)
          continue

        # This is to handle the case of third_party/WebKit migrating from
        # being a DEPS entry to being part of the main project.
        # If the subproject is a Git project, we need to remove its .git
        # folder. Otherwise git operations on that folder will have different
        # effects depending on the current working directory.
        if os.path.abspath(scm_root) == os.path.abspath(e_dir):
          e_par_dir = os.path.join(e_dir, os.pardir)
          if gclient_scm.scm.GIT.IsInsideWorkTree(e_par_dir):
            par_scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(e_par_dir)
            # rel_e_dir : relative path of entry w.r.t. its parent repo.
            rel_e_dir = os.path.relpath(e_dir, par_scm_root)
            if gclient_scm.scm.GIT.IsDirectoryVersioned(
                par_scm_root, rel_e_dir):
              save_dir = scm.GetGitBackupDirPath()
              # Remove any eventual stale backup dir for the same project.
              if os.path.exists(save_dir):
                gclient_utils.rmtree(save_dir)
              os.rename(os.path.join(e_dir, '.git'), save_dir)
              # When switching between the two states (entry/ is a subproject
              # -> entry/ is part of the outer project), it is very likely
              # that some files are changed in the checkout, unless we are
              # jumping *exactly* across the commit which changed just DEPS.
              # In such case we want to cleanup any eventual stale files
              # (coming from the old subproject) in order to end up with a
              # clean checkout.
              gclient_scm.scm.GIT.CleanupDir(par_scm_root, rel_e_dir)
              assert not os.path.exists(os.path.join(e_dir, '.git'))
              print('\nWARNING: \'%s\' has been moved from DEPS to a higher '
                    'level checkout. The git folder containing all the local'
                    ' branches has been saved to %s.\n'
                    'If you don\'t care about its state you can safely '
                    'remove that folder to free up space.' % (entry, save_dir))
              continue

        if scm_root in full_entries:
          logging.info('%s is part of a higher level checkout, not removing',
                       scm.GetCheckoutRoot())
          continue

        file_list = []
        scm.status(self._options, [], file_list)
        modified_files = file_list != []
        if (not self._options.delete_unversioned_trees or
            (modified_files and not self._options.force)):
          # There are modified files in this entry. Keep warning until
          # removed.
          self.add_dependency(
              GitDependency(
                  parent=self,
                  name=entry,
                  url=prev_url,
                  managed=False,
                  custom_deps={},
                  custom_vars={},
                  custom_hooks=[],
                  deps_file=None,
                  should_process=True,
                  should_recurse=False,
                  relative=None,
                  condition=None))
          print('\nWARNING: \'%s\' is no longer part of this client.\n'
                'It is recommended that you manually remove it or use '
                '\'gclient sync -D\' next time.' % entry_fixed)
        else:
          # Delete the entry
          print('\n________ deleting \'%s\' in \'%s\'' % (
              entry_fixed, self.root_dir))
          gclient_utils.rmtree(e_dir)
    # record the current list of entries for next time
    self._SaveEntries()

  def RunOnDeps(self, command, args, ignore_requirements=False, progress=True):
    """Runs a command on each dependency in a client and its dependencies.

    Args:
      command: The command to use (e.g., 'status' or 'diff')
      args: list of str - extra arguments to add to the command line.
    """
    if not self.dependencies:
      raise gclient_utils.Error('No solution specified')

    revision_overrides = {}
    patch_refs = {}
    target_branches = {}
    # It's unnecessary to check for revision overrides for 'recurse'.
    # Save a few seconds by not calling _EnforceRevisions() in that case.
    if command not in ('diff', 'recurse', 'runhooks', 'status', 'revert',
                       'validate'):
      self._CheckConfig()
      revision_overrides = self._EnforceRevisions()

    if command == 'update':
      patch_refs, target_branches = self._EnforcePatchRefsAndBranches()
    # Disable progress for non-tty stdout.
    should_show_progress = (
        setup_color.IS_TTY and not self._options.verbose and progress)
    pm = None
    if should_show_progress:
      if command in ('update', 'revert'):
        pm = Progress('Syncing projects', 1)
      elif command in ('recurse', 'validate'):
        pm = Progress(' '.join(args), 1)
    work_queue = gclient_utils.ExecutionQueue(
        self._options.jobs, pm, ignore_requirements=ignore_requirements,
        verbose=self._options.verbose)
    for s in self.dependencies:
      if s.should_process:
        work_queue.enqueue(s)
    work_queue.flush(revision_overrides, command, args, options=self._options,
                     patch_refs=patch_refs, target_branches=target_branches)

    if revision_overrides:
      print('Please fix your script, having invalid --revision flags will soon '
            'be considered an error.', file=sys.stderr)

    if patch_refs:
      raise gclient_utils.Error(
          'The following --patch-ref flags were not used. Please fix it:\n%s' %
          ('\n'.join(
              patch_repo + '@' + patch_ref
              for patch_repo, patch_ref in six.iteritems(patch_refs))))

    # Once all the dependencies have been processed, it's now safe to write
    # out the gn_args_file and run the hooks.
    if command == 'update':
      gn_args_dep = self.dependencies[0]
      if gn_args_dep._gn_args_from:
        deps_map = dict([(dep.name, dep) for dep in gn_args_dep.dependencies])
        gn_args_dep = deps_map.get(gn_args_dep._gn_args_from)
      if gn_args_dep and gn_args_dep.HasGNArgsFile():
        gn_args_dep.WriteGNArgsFile()

      self._RemoveUnversionedGitDirs()

    # Sync CIPD dependencies once removed deps are deleted. In case a git
    # dependency was moved to CIPD, we want to remove the old git directory
    # first and then sync the CIPD dep.
    if self._cipd_root:
      self._cipd_root.run(command)

    if not self._options.nohooks:
      if should_show_progress:
        pm = Progress('Running hooks', 1)
      self.RunHooksRecursively(self._options, pm)


    return 0

  def PrintRevInfo(self):
    if not self.dependencies:
      raise gclient_utils.Error('No solution specified')
    # Load all the settings.
    work_queue = gclient_utils.ExecutionQueue(
        self._options.jobs, None, False, verbose=self._options.verbose)
    for s in self.dependencies:
      if s.should_process:
        work_queue.enqueue(s)
    work_queue.flush({}, None, [], options=self._options, patch_refs=None,
                     target_branches=None)

    def ShouldPrintRevision(dep):
      return (not self._options.filter
              or dep.FuzzyMatchUrl(self._options.filter))

    if self._options.snapshot:
      json_output = []
      # First level at .gclient
      for d in self.dependencies:
        entries = {}
        def GrabDeps(dep):
          """Recursively grab dependencies."""
          for d in dep.dependencies:
            d.PinToActualRevision()
            if ShouldPrintRevision(d):
              entries[d.name] = d.url
            GrabDeps(d)
        GrabDeps(d)
        json_output.append({
            'name': d.name,
            'solution_url': d.url,
            'deps_file': d.deps_file,
            'managed': d.managed,
            'custom_deps': entries,
        })
      if self._options.output_json == '-':
        print(json.dumps(json_output, indent=2, separators=(',', ': ')))
      elif self._options.output_json:
        with open(self._options.output_json, 'w') as f:
          json.dump(json_output, f)
      else:
        # Print the snapshot configuration file
        print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {
            'solution_list': pprint.pformat(json_output, indent=2),
        })
    else:
      entries = {}
      for d in self.root.subtree(False):
        if self._options.actual:
          d.PinToActualRevision()
        if ShouldPrintRevision(d):
          entries[d.name] = d.url
      if self._options.output_json:
        json_output = {
            name: {
                'url': rev.split('@')[0] if rev else None,
                'rev': rev.split('@')[1] if rev and '@' in rev else None,
            }
            for name, rev in six.iteritems(entries)
        }
        if self._options.output_json == '-':
          print(json.dumps(json_output, indent=2, separators=(',', ': ')))
        else:
          with open(self._options.output_json, 'w') as f:
            json.dump(json_output, f)
      else:
        keys = sorted(entries.keys())
        for x in keys:
          print('%s: %s' % (x, entries[x]))
    logging.info(str(self))

  def ParseDepsFile(self):
    """No DEPS to parse for a .gclient file."""
    raise gclient_utils.Error('Internal error')

  def PrintLocationAndContents(self):
    # Print out the .gclient file.  This is longer than if we just printed the
    # client dict, but more legible, and it might contain helpful comments.
    print('Loaded .gclient config in %s:\n%s' % (
        self.root_dir, self.config_content))

  def GetCipdRoot(self):
    if not self._cipd_root:
      self._cipd_root = gclient_scm.CipdRoot(
          self.root_dir,
          # TODO(jbudorick): Support other service URLs as necessary.
          # Service URLs should be constant over the scope of a cipd
          # root, so a var per DEPS file specifying the service URL
          # should suffice.
          'https://chrome-infra-packages.appspot.com')
    return self._cipd_root

  @property
  def root_dir(self):
    """Root directory of gclient checkout."""
    return self._root_dir

  @property
  def enforced_os(self):
    """What deps_os entries that are to be parsed."""
    return self._enforced_os

  @property
  def target_os(self):
    return self._enforced_os

  @property
  def target_cpu(self):
    return self._enforced_cpu


class CipdDependency(Dependency):
  """A Dependency object that represents a single CIPD package."""

  def __init__(
      self, parent, name, dep_value, cipd_root,
      custom_vars, should_process, relative, condition):
    package = dep_value['package']
    version = dep_value['version']
    url = urlparse.urljoin(
        cipd_root.service_url, '%s@%s' % (package, version))
    super(CipdDependency, self).__init__(
        parent=parent,
        name=name + ':' + package,
        url=url,
        managed=None,
        custom_deps=None,
        custom_vars=custom_vars,
        custom_hooks=None,
        deps_file=None,
        should_process=should_process,
        should_recurse=False,
        relative=relative,
        condition=condition)
    self._cipd_package = None
    self._cipd_root = cipd_root
    # CIPD wants /-separated paths, even on Windows.
    native_subdir_path = os.path.relpath(
        os.path.join(self.root.root_dir, name), cipd_root.root_dir)
    self._cipd_subdir = posixpath.join(*native_subdir_path.split(os.sep))
    self._package_name = package
    self._package_version = version

  #override
  def run(self, revision_overrides, command, args, work_queue, options,
          patch_refs, target_branches):
    """Runs |command| then parse the DEPS file."""
    logging.info('CipdDependency(%s).run()' % self.name)
    if not self.should_process:
      return
    self._CreatePackageIfNecessary()
    super(CipdDependency, self).run(revision_overrides, command, args,
                                    work_queue, options, patch_refs,
                                    target_branches)

  def _CreatePackageIfNecessary(self):
    # We lazily create the CIPD package to make sure that only packages
    # that we want (as opposed to all packages defined in all DEPS files
    # we parse) get added to the root and subsequently ensured.
    if not self._cipd_package:
      self._cipd_package = self._cipd_root.add_package(
          self._cipd_subdir, self._package_name, self._package_version)

  def ParseDepsFile(self):
    """CIPD dependencies are not currently allowed to have nested deps."""
    self.add_dependencies_and_close([], [])

  #override
  def verify_validity(self):
    """CIPD dependencies allow duplicate name for packages in same directory."""
    logging.info('Dependency(%s).verify_validity()' % self.name)
    return True

  #override
  def GetScmName(self):
    """Always 'cipd'."""
    return 'cipd'

  #override
  def CreateSCM(self, out_cb=None):
    """Create a Wrapper instance suitable for handling this CIPD dependency."""
    self._CreatePackageIfNecessary()
    return gclient_scm.CipdWrapper(
        self.url, self.root.root_dir, self.name, self.outbuf, out_cb,
        root=self._cipd_root, package=self._cipd_package)

  def hierarchy(self, include_url=False):
    return self.parent.hierarchy(include_url) + ' -> ' + self._cipd_subdir

  def ToLines(self):
    """Return a list of lines representing this in a DEPS file."""
    def escape_cipd_var(package):
      return package.replace('{', '{{').replace('}', '}}')

    s = []
    self._CreatePackageIfNecessary()
    if self._cipd_package.authority_for_subdir:
      condition_part = (['    "condition": %r,' % self.condition]
                        if self.condition else [])
      s.extend([
          '  # %s' % self.hierarchy(include_url=False),
          '  "%s": {' % (self.name.split(':')[0],),
          '    "packages": [',
      ])
      for p in sorted(
          self._cipd_root.packages(self._cipd_subdir),
          key=lambda x: x.name):
        s.extend([
            '      {',
            '        "package": "%s",' % escape_cipd_var(p.name),
            '        "version": "%s",' % p.version,
            '      },',
        ])

      s.extend([
          '    ],',
          '    "dep_type": "cipd",',
      ] + condition_part + [
          '  },',
          '',
      ])
    return s


#### gclient commands.


@subcommand.usage('[command] [args ...]')
@metrics.collector.collect_metrics('gclient recurse')
def CMDrecurse(parser, args):
  """Operates [command args ...] on all the dependencies.

  Runs a shell command on all entries.
  Sets GCLIENT_DEP_PATH environment variable as the dep's relative location to
  root directory of the checkout.
  """
  # Stop parsing at the first non-arg so that these go through to the command
  parser.disable_interspersed_args()
  parser.add_option('-s', '--scm', action='append', default=[],
                    help='Choose scm types to operate upon.')
  parser.add_option('-i', '--ignore', action='store_true',
                    help='Ignore non-zero return codes from subcommands.')
  parser.add_option('--prepend-dir', action='store_true',
                    help='Prepend relative dir for use with git <cmd> --null.')
  parser.add_option('--no-progress', action='store_true',
                    help='Disable progress bar that shows sub-command updates')
  options, args = parser.parse_args(args)
  if not args:
    print('Need to supply a command!', file=sys.stderr)
    return 1
  root_and_entries = gclient_utils.GetGClientRootAndEntries()
  if not root_and_entries:
    print(
        'You need to run gclient sync at least once to use \'recurse\'.\n'
        'This is because .gclient_entries needs to exist and be up to date.',
        file=sys.stderr)
    return 1

  # Normalize options.scm to a set()
  scm_set = set()
  for scm in options.scm:
    scm_set.update(scm.split(','))
  options.scm = scm_set

  options.nohooks = True
  client = GClient.LoadCurrentConfig(options)
  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')
  return client.RunOnDeps('recurse', args, ignore_requirements=True,
                          progress=not options.no_progress)


@subcommand.usage('[args ...]')
@metrics.collector.collect_metrics('gclient fetch')
def CMDfetch(parser, args):
  """Fetches upstream commits for all modules.

  Completely git-specific. Simply runs 'git fetch [args ...]' for each module.
  """
  (options, args) = parser.parse_args(args)
  return CMDrecurse(OptionParser(), [
      '--jobs=%d' % options.jobs, '--scm=git', 'git', 'fetch'] + args)


class Flattener(object):
  """Flattens a gclient solution."""

  def __init__(self, client, pin_all_deps=False):
    """Constructor.

    Arguments:
      client (GClient): client to flatten
      pin_all_deps (bool): whether to pin all deps, even if they're not pinned
          in DEPS
    """
    self._client = client

    self._deps_string = None
    self._deps_files = set()

    self._allowed_hosts = set()
    self._deps = {}
    self._hooks = []
    self._pre_deps_hooks = []
    self._vars = {}

    self._flatten(pin_all_deps=pin_all_deps)

  @property
  def deps_string(self):
    assert self._deps_string is not None
    return self._deps_string

  @property
  def deps_files(self):
    return self._deps_files

  def _pin_dep(self, dep):
    """Pins a dependency to specific full revision sha.

    Arguments:
      dep (Dependency): dependency to process
    """
    if dep.url is None:
      return

    # Make sure the revision is always fully specified (a hash),
    # as opposed to refs or tags which might change. Similarly,
    # shortened shas might become ambiguous; make sure to always
    # use full one for pinning.
    revision = gclient_utils.SplitUrlRevision(dep.url)[1]
    if not revision or not gclient_utils.IsFullGitSha(revision):
      dep.PinToActualRevision()

  def _flatten(self, pin_all_deps=False):
    """Runs the flattener. Saves resulting DEPS string.

    Arguments:
      pin_all_deps (bool): whether to pin all deps, even if they're not pinned
          in DEPS
    """
    for solution in self._client.dependencies:
      self._add_dep(solution)
      self._flatten_dep(solution)

    if pin_all_deps:
      for dep in six.itervalues(self._deps):
        self._pin_dep(dep)

    def add_deps_file(dep):
      # Only include DEPS files referenced by recursedeps.
      if not dep.should_recurse:
        return
      deps_file = dep.deps_file
      deps_path = os.path.join(self._client.root_dir, dep.name, deps_file)
      if not os.path.exists(deps_path):
        # gclient has a fallback that if deps_file doesn't exist, it'll try
        # DEPS. Do the same here.
        deps_file = 'DEPS'
        deps_path = os.path.join(self._client.root_dir, dep.name, deps_file)
        if not os.path.exists(deps_path):
          return
      assert dep.url
      self._deps_files.add((dep.url, deps_file, dep.hierarchy_data()))
    for dep in six.itervalues(self._deps):
      add_deps_file(dep)

    gn_args_dep = self._deps.get(self._client.dependencies[0]._gn_args_from,
                                 self._client.dependencies[0])
    self._deps_string = '\n'.join(
        _GNSettingsToLines(gn_args_dep._gn_args_file, gn_args_dep._gn_args) +
        _AllowedHostsToLines(self._allowed_hosts) +
        _DepsToLines(self._deps) +
        _HooksToLines('hooks', self._hooks) +
        _HooksToLines('pre_deps_hooks', self._pre_deps_hooks) +
        _VarsToLines(self._vars) +
        ['# %s, %s' % (url, deps_file)
         for url, deps_file, _ in sorted(self._deps_files)] +
        [''])  # Ensure newline at end of file.

  def _add_dep(self, dep):
    """Helper to add a dependency to flattened DEPS.

    Arguments:
      dep (Dependency): dependency to add
    """
    assert dep.name not in self._deps or self._deps.get(dep.name) == dep, (
        dep.name, self._deps.get(dep.name))
    if dep.url:
      self._deps[dep.name] = dep

  def _flatten_dep(self, dep):
    """Visits a dependency in order to flatten it (see CMDflatten).

    Arguments:
      dep (Dependency): dependency to process
    """
    logging.debug('_flatten_dep(%s)', dep.name)

    assert dep.deps_parsed, (
        "Attempted to flatten %s but it has not been processed." % dep.name)

    self._allowed_hosts.update(dep.allowed_hosts)

    # Only include vars explicitly listed in the DEPS files or gclient solution,
    # not automatic, local overrides (i.e. not all of dep.get_vars()).
    hierarchy = dep.hierarchy(include_url=False)
    for key, value in six.iteritems(dep._vars):
      # Make sure there are no conflicting variables. It is fine however
      # to use same variable name, as long as the value is consistent.
      assert key not in self._vars or self._vars[key][1] == value, (
        "dep:%s key:%s value:%s != %s" % (
          dep.name, key, value, self._vars[key][1]))
      self._vars[key] = (hierarchy, value)
    # Override explicit custom variables.
    for key, value in six.iteritems(dep.custom_vars):
      # Do custom_vars that don't correspond to DEPS vars ever make sense? DEPS
      # conditionals shouldn't be using vars that aren't also defined in the
      # DEPS (presubmit actually disallows this), so any new custom_var must be
      # unused in the DEPS, so no need to add it to the flattened output either.
      if key not in self._vars:
        continue
      # Don't "override" existing vars if it's actually the same value.
      elif self._vars[key][1] == value:
        continue
      # Anything else is overriding a default value from the DEPS.
      self._vars[key] = (hierarchy + ' [custom_var override]', value)

    self._pre_deps_hooks.extend([(dep, hook) for hook in dep.pre_deps_hooks])
    self._hooks.extend([(dep, hook) for hook in dep.deps_hooks])

    for sub_dep in dep.dependencies:
      self._add_dep(sub_dep)

    for d in dep.dependencies:
      if d.should_recurse:
        self._flatten_dep(d)


@metrics.collector.collect_metrics('gclient flatten')
def CMDflatten(parser, args):
  """Flattens the solutions into a single DEPS file."""
  parser.add_option('--output-deps', help='Path to the output DEPS file')
  parser.add_option(
      '--output-deps-files',
      help=('Path to the output metadata about DEPS files referenced by '
            'recursedeps.'))
  parser.add_option(
      '--pin-all-deps', action='store_true',
      help=('Pin all deps, even if not pinned in DEPS. CAVEAT: only does so '
            'for checked out deps, NOT deps_os.'))
  options, args = parser.parse_args(args)

  options.nohooks = True
  options.process_all_deps = True
  client = GClient.LoadCurrentConfig(options)

  # Only print progress if we're writing to a file. Otherwise, progress updates
  # could obscure intended output.
  code = client.RunOnDeps('flatten', args, progress=options.output_deps)
  if code != 0:
    return code

  flattener = Flattener(client, pin_all_deps=options.pin_all_deps)

  if options.output_deps:
    with open(options.output_deps, 'w') as f:
      f.write(flattener.deps_string)
  else:
    print(flattener.deps_string)

  deps_files = [{'url': d[0], 'deps_file': d[1], 'hierarchy': d[2]}
                for d in sorted(flattener.deps_files)]
  if options.output_deps_files:
    with open(options.output_deps_files, 'w') as f:
      json.dump(deps_files, f)

  return 0


def _GNSettingsToLines(gn_args_file, gn_args):
  s = []
  if gn_args_file:
    s.extend([
        'gclient_gn_args_file = "%s"' % gn_args_file,
        'gclient_gn_args = %r' % gn_args,
    ])
  return s


def _AllowedHostsToLines(allowed_hosts):
  """Converts |allowed_hosts| set to list of lines for output."""
  if not allowed_hosts:
    return []
  s = ['allowed_hosts = [']
  for h in sorted(allowed_hosts):
    s.append('  "%s",' % h)
  s.extend([']', ''])
  return s


def _DepsToLines(deps):
  """Converts |deps| dict to list of lines for output."""
  if not deps:
    return []
  s = ['deps = {']
  for _, dep in sorted(deps.items()):
    s.extend(dep.ToLines())
  s.extend(['}', ''])
  return s


def _DepsOsToLines(deps_os):
  """Converts |deps_os| dict to list of lines for output."""
  if not deps_os:
    return []
  s = ['deps_os = {']
  for dep_os, os_deps in sorted(deps_os.items()):
    s.append('  "%s": {' % dep_os)
    for name, dep in sorted(os_deps.items()):
      condition_part = (['      "condition": %r,' % dep.condition]
                        if dep.condition else [])
      s.extend([
          '    # %s' % dep.hierarchy(include_url=False),
          '    "%s": {' % (name,),
          '      "url": "%s",' % (dep.url,),
      ] + condition_part + [
          '    },',
          '',
      ])
    s.extend(['  },', ''])
  s.extend(['}', ''])
  return s


def _HooksToLines(name, hooks):
  """Converts |hooks| list to list of lines for output."""
  if not hooks:
    return []
  s = ['%s = [' % name]
  for dep, hook in hooks:
    s.extend([
        '  # %s' % dep.hierarchy(include_url=False),
        '  {',
    ])
    if hook.name is not None:
      s.append('    "name": "%s",' % hook.name)
    if hook.pattern is not None:
      s.append('    "pattern": "%s",' % hook.pattern)
    if hook.condition is not None:
      s.append('    "condition": %r,' % hook.condition)
    # Flattened hooks need to be written relative to the root gclient dir
    cwd = os.path.relpath(os.path.normpath(hook.effective_cwd))
    s.extend(
        ['    "cwd": "%s",' % cwd] +
        ['    "action": ['] +
        ['        "%s",' % arg for arg in hook.action] +
        ['    ]', '  },', '']
    )
  s.extend([']', ''])
  return s


def _HooksOsToLines(hooks_os):
  """Converts |hooks| list to list of lines for output."""
  if not hooks_os:
    return []
  s = ['hooks_os = {']
  for hook_os, os_hooks in six.iteritems(hooks_os):
    s.append('  "%s": [' % hook_os)
    for dep, hook in os_hooks:
      s.extend([
          '    # %s' % dep.hierarchy(include_url=False),
          '    {',
      ])
      if hook.name is not None:
        s.append('      "name": "%s",' % hook.name)
      if hook.pattern is not None:
        s.append('      "pattern": "%s",' % hook.pattern)
      if hook.condition is not None:
        s.append('    "condition": %r,' % hook.condition)
      # Flattened hooks need to be written relative to the root gclient dir
      cwd = os.path.relpath(os.path.normpath(hook.effective_cwd))
      s.extend(
          ['    "cwd": "%s",' % cwd] +
          ['      "action": ['] +
          ['          "%s",' % arg for arg in hook.action] +
          ['      ]', '    },', '']
      )
    s.extend(['  ],', ''])
  s.extend(['}', ''])
  return s


def _VarsToLines(variables):
  """Converts |variables| dict to list of lines for output."""
  if not variables:
    return []
  s = ['vars = {']
  for key, tup in sorted(variables.items()):
    hierarchy, value = tup
    s.extend([
        '  # %s' % hierarchy,
        '  "%s": %r,' % (key, value),
        '',
    ])
  s.extend(['}', ''])
  return s


@metrics.collector.collect_metrics('gclient grep')
def CMDgrep(parser, args):
  """Greps through git repos managed by gclient.

  Runs 'git grep [args...]' for each module.
  """
  # We can't use optparse because it will try to parse arguments sent
  # to git grep and throw an error. :-(
  if not args or re.match('(-h|--help)$', args[0]):
    print(
        'Usage: gclient grep [-j <N>] git-grep-args...\n\n'
        'Example: "gclient grep -j10 -A2 RefCountedBase" runs\n"git grep '
        '-A2 RefCountedBase" on each of gclient\'s git\nrepos with up to '
        '10 jobs.\n\nBonus: page output by appending "|& less -FRSX" to the'
        ' end of your query.',
        file=sys.stderr)
    return 1

  jobs_arg = ['--jobs=1']
  if re.match(r'(-j|--jobs=)\d+$', args[0]):
    jobs_arg, args = args[:1], args[1:]
  elif re.match(r'(-j|--jobs)$', args[0]):
    jobs_arg, args = args[:2], args[2:]

  return CMDrecurse(
      parser,
      jobs_arg + ['--ignore', '--prepend-dir', '--no-progress', '--scm=git',
                  'git', 'grep', '--null', '--color=Always'] + args)


@metrics.collector.collect_metrics('gclient root')
def CMDroot(parser, args):
  """Outputs the solution root (or current dir if there isn't one)."""
  (options, args) = parser.parse_args(args)
  client = GClient.LoadCurrentConfig(options)
  if client:
    print(os.path.abspath(client.root_dir))
  else:
    print(os.path.abspath('.'))


@subcommand.usage('[url]')
@metrics.collector.collect_metrics('gclient config')
def CMDconfig(parser, args):
  """Creates a .gclient file in the current directory.

  This specifies the configuration for further commands. After update/sync,
  top-level DEPS files in each module are read to determine dependent
  modules to operate on as well. If optional [url] parameter is
  provided, then configuration is read from a specified Subversion server
  URL.
  """
  # We do a little dance with the --gclientfile option.  'gclient config' is the
  # only command where it's acceptable to have both '--gclientfile' and '--spec'
  # arguments.  So, we temporarily stash any --gclientfile parameter into
  # options.output_config_file until after the (gclientfile xor spec) error
  # check.
  parser.remove_option('--gclientfile')
  parser.add_option('--gclientfile', dest='output_config_file',
                    help='Specify an alternate .gclient file')
  parser.add_option('--name',
                    help='overrides the default name for the solution')
  parser.add_option('--deps-file', default='DEPS',
                    help='overrides the default name for the DEPS file for the '
                         'main solutions and all sub-dependencies')
  parser.add_option('--unmanaged', action='store_true', default=False,
                    help='overrides the default behavior to make it possible '
                         'to have the main solution untouched by gclient '
                         '(gclient will check out unmanaged dependencies but '
                         'will never sync them)')
  parser.add_option('--cache-dir', default=UNSET_CACHE_DIR,
                    help='Cache all git repos into this dir and do shared '
                         'clones from the cache, instead of cloning directly '
                         'from the remote. Pass "None" to disable cache, even '
                         'if globally enabled due to $GIT_CACHE_PATH.')
  parser.add_option('--custom-var', action='append', dest='custom_vars',
                    default=[],
                    help='overrides variables; key=value syntax')
  parser.set_defaults(config_filename=None)
  (options, args) = parser.parse_args(args)
  if options.output_config_file:
    setattr(options, 'config_filename', getattr(options, 'output_config_file'))
  if ((options.spec and args) or len(args) > 2 or
      (not options.spec and not args)):
    parser.error('Inconsistent arguments. Use either --spec or one or 2 args')

  if (options.cache_dir is not UNSET_CACHE_DIR
      and options.cache_dir.lower() == 'none'):
    options.cache_dir = None

  custom_vars = {}
  for arg in options.custom_vars:
    kv = arg.split('=', 1)
    if len(kv) != 2:
      parser.error('Invalid --custom-var argument: %r' % arg)
    custom_vars[kv[0]] = gclient_eval.EvaluateCondition(kv[1], {})

  client = GClient('.', options)
  if options.spec:
    client.SetConfig(options.spec)
  else:
    base_url = args[0].rstrip('/')
    if not options.name:
      name = base_url.split('/')[-1]
      if name.endswith('.git'):
        name = name[:-4]
    else:
      # specify an alternate relpath for the given URL.
      name = options.name
      if not os.path.abspath(os.path.join(os.getcwd(), name)).startswith(
          os.getcwd()):
        parser.error('Do not pass a relative path for --name.')
      if any(x in ('..', '.', '/', '\\') for x in name.split(os.sep)):
        parser.error('Do not include relative path components in --name.')

    deps_file = options.deps_file
    client.SetDefaultConfig(name, deps_file, base_url,
                            managed=not options.unmanaged,
                            cache_dir=options.cache_dir,
                            custom_vars=custom_vars)
  client.SaveConfig()
  return 0


@subcommand.epilog("""Example:
  gclient pack > patch.txt
    generate simple patch for configured client and dependences
""")
@metrics.collector.collect_metrics('gclient pack')
def CMDpack(parser, args):
  """Generates a patch which can be applied at the root of the tree.

  Internally, runs 'git diff' on each checked out module and
  dependencies, and performs minimal postprocessing of the output. The
  resulting patch is printed to stdout and can be applied to a freshly
  checked out tree via 'patch -p0 < patchfile'.
  """
  parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
                    help='override deps for the specified (comma-separated) '
                         'platform(s); \'all\' will process all deps_os '
                         'references')
  parser.remove_option('--jobs')
  (options, args) = parser.parse_args(args)
  # Force jobs to 1 so the stdout is not annotated with the thread ids
  options.jobs = 1
  client = GClient.LoadCurrentConfig(options)
  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')
  if options.verbose:
    client.PrintLocationAndContents()
  return client.RunOnDeps('pack', args)


@metrics.collector.collect_metrics('gclient status')
def CMDstatus(parser, args):
  """Shows modification status for every dependencies."""
  parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
                    help='override deps for the specified (comma-separated) '
                         'platform(s); \'all\' will process all deps_os '
                         'references')
  (options, args) = parser.parse_args(args)
  client = GClient.LoadCurrentConfig(options)
  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')
  if options.verbose:
    client.PrintLocationAndContents()
  return client.RunOnDeps('status', args)


@subcommand.epilog("""Examples:
  gclient sync
      update files from SCM according to current configuration,
      *for modules which have changed since last update or sync*
  gclient sync --force
      update files from SCM according to current configuration, for
      all modules (useful for recovering files deleted from local copy)
  gclient sync --revision src@31000
      update src directory to r31000

JSON output format:
If the --output-json option is specified, the following document structure will
be emitted to the provided file. 'null' entries may occur for subprojects which
are present in the gclient solution, but were not processed (due to custom_deps,
os_deps, etc.)

{
  "solutions" : {
    "<name>": {  # <name> is the posix-normalized path to the solution.
      "revision": [<git id hex string>|null],
      "scm": ["git"|null],
    }
  }
}
""")
@metrics.collector.collect_metrics('gclient sync')
def CMDsync(parser, args):
  """Checkout/update all modules."""
  parser.add_option('-f', '--force', action='store_true',
                    help='force update even for unchanged modules')
  parser.add_option('-n', '--nohooks', action='store_true',
                    help='don\'t run hooks after the update is complete')
  parser.add_option('-p', '--noprehooks', action='store_true',
                    help='don\'t run pre-DEPS hooks', default=False)
  parser.add_option('-r', '--revision', action='append',
                    dest='revisions', metavar='REV', default=[],
                    help='Enforces revision/hash for the solutions with the '
                         'format src@rev. The src@ part is optional and can be '
                         'skipped. You can also specify URLs instead of paths '
                         'and gclient will find the solution corresponding to '
                         'the given URL. If a path is also specified, the URL '
                         'takes precedence. -r can be used multiple times when '
                         '.gclient has multiple solutions configured, and will '
                         'work even if the src@ part is skipped.')
  parser.add_option('--patch-ref', action='append',
                    dest='patch_refs', metavar='GERRIT_REF', default=[],
                    help='Patches the given reference with the format '
                         'dep@target-ref:patch-ref. '
                         'For |dep|, you can specify URLs as well as paths, '
                         'with URLs taking preference. '
                         '|patch-ref| will be applied to |dep|, rebased on top '
                         'of what |dep| was synced to, and a soft reset will '
                         'be done. Use --no-rebase-patch-ref and '
                         '--no-reset-patch-ref to disable this behavior. '
                         '|target-ref| is the target branch against which a '
                         'patch was created, it is used to determine which '
                         'commits from the |patch-ref| actually constitute a '
                         'patch.')
  parser.add_option('--with_branch_heads', action='store_true',
                    help='Clone git "branch_heads" refspecs in addition to '
                         'the default refspecs. This adds about 1/2GB to a '
                         'full checkout. (git only)')
  parser.add_option('--with_tags', action='store_true',
                    help='Clone git tags in addition to the default refspecs.')
  parser.add_option('-H', '--head', action='store_true',
                    help='DEPRECATED: only made sense with safesync urls.')
  parser.add_option('-D', '--delete_unversioned_trees', action='store_true',
                    help='Deletes from the working copy any dependencies that '
                         'have been removed since the last sync, as long as '
                         'there are no local modifications. When used with '
                         '--force, such dependencies are removed even if they '
                         'have local modifications. When used with --reset, '
                         'all untracked directories are removed from the '
                         'working copy, excluding those which are explicitly '
                         'ignored in the repository.')
  parser.add_option('-R', '--reset', action='store_true',
                    help='resets any local changes before updating (git only)')
  parser.add_option('-M', '--merge', action='store_true',
                    help='merge upstream changes instead of trying to '
                         'fast-forward or rebase')
  parser.add_option('-A', '--auto_rebase', action='store_true',
                    help='Automatically rebase repositories against local '
                         'checkout during update (git only).')
  parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
                    help='override deps for the specified (comma-separated) '
                         'platform(s); \'all\' will process all deps_os '
                         'references')
  parser.add_option('--process-all-deps', action='store_true',
                    help='Check out all deps, even for different OS-es, '
                         'or with conditions evaluating to false')
  parser.add_option('--upstream', action='store_true',
                    help='Make repo state match upstream branch.')
  parser.add_option('--output-json',
                    help='Output a json document to this path containing '
                         'summary information about the sync.')
  parser.add_option('--no-history', action='store_true',
                    help='GIT ONLY - Reduces the size/time of the checkout at '
                    'the cost of no history. Requires Git 1.9+')
  parser.add_option('--shallow', action='store_true',
                    help='GIT ONLY - Do a shallow clone into the cache dir. '
                         'Requires Git 1.9+')
  parser.add_option('--no_bootstrap', '--no-bootstrap',
                    action='store_true',
                    help='Don\'t bootstrap from Google Storage.')
  parser.add_option('--ignore_locks', action='store_true',
                    help='GIT ONLY - Ignore cache locks.')
  parser.add_option('--break_repo_locks', action='store_true',
                    help='GIT ONLY - Forcibly remove repo locks (e.g. '
                      'index.lock). This should only be used if you know for '
                      'certain that this invocation of gclient is the only '
                      'thing operating on the git repos (e.g. on a bot).')
  parser.add_option('--lock_timeout', type='int', default=5000,
                    help='GIT ONLY - Deadline (in seconds) to wait for git '
                         'cache lock to become available. Default is %default.')
  # TODO(agable): Remove these when the oldest CrOS release milestone is M56.
  parser.add_option('-t', '--transitive', action='store_true',
                    help='DEPRECATED: This is a no-op.')
  parser.add_option('-m', '--manually_grab_svn_rev', action='store_true',
                    help='DEPRECATED: This is a no-op.')
  # TODO(phajdan.jr): Remove validation options once default (crbug/570091).
  parser.add_option('--validate-syntax', action='store_true', default=True,
                    help='Validate the .gclient and DEPS syntax')
  parser.add_option('--disable-syntax-validation', action='store_false',
                    dest='validate_syntax',
                    help='Disable validation of .gclient and DEPS syntax.')
  parser.add_option('--no-rebase-patch-ref', action='store_false',
                    dest='rebase_patch_ref', default=True,
                    help='Bypass rebase of the patch ref after checkout.')
  parser.add_option('--no-reset-patch-ref', action='store_false',
                    dest='reset_patch_ref', default=True,
                    help='Bypass calling reset after patching the ref.')
  (options, args) = parser.parse_args(args)
  client = GClient.LoadCurrentConfig(options)

  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')

  if options.revisions and options.head:
    # TODO(maruel): Make it a parser.error if it doesn't break any builder.
    print('Warning: you cannot use both --head and --revision')

  if options.verbose:
    client.PrintLocationAndContents()
  ret = client.RunOnDeps('update', args)
  if options.output_json:
    slns = {}
    for d in client.subtree(True):
      normed = d.name.replace('\\', '/').rstrip('/') + '/'
      slns[normed] = {
          'revision': d.got_revision,
          'scm': d.used_scm.name if d.used_scm else None,
          'url': str(d.url) if d.url else None,
          'was_processed': d.should_process,
      }
    with open(options.output_json, 'wb') as f:
      json.dump({'solutions': slns}, f)
  return ret


CMDupdate = CMDsync


@metrics.collector.collect_metrics('gclient validate')
def CMDvalidate(parser, args):
  """Validates the .gclient and DEPS syntax."""
  options, args = parser.parse_args(args)
  options.validate_syntax = True
  client = GClient.LoadCurrentConfig(options)
  rv = client.RunOnDeps('validate', args)
  if rv == 0:
    print('validate: SUCCESS')
  else:
    print('validate: FAILURE')
  return rv


@metrics.collector.collect_metrics('gclient diff')
def CMDdiff(parser, args):
  """Displays local diff for every dependencies."""
  parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
                    help='override deps for the specified (comma-separated) '
                         'platform(s); \'all\' will process all deps_os '
                         'references')
  (options, args) = parser.parse_args(args)
  client = GClient.LoadCurrentConfig(options)
  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')
  if options.verbose:
    client.PrintLocationAndContents()
  return client.RunOnDeps('diff', args)


@metrics.collector.collect_metrics('gclient revert')
def CMDrevert(parser, args):
  """Reverts all modifications in every dependencies.

  That's the nuclear option to get back to a 'clean' state. It removes anything
  that shows up in git status."""
  parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
                    help='override deps for the specified (comma-separated) '
                         'platform(s); \'all\' will process all deps_os '
                         'references')
  parser.add_option('-n', '--nohooks', action='store_true',
                    help='don\'t run hooks after the revert is complete')
  parser.add_option('-p', '--noprehooks', action='store_true',
                    help='don\'t run pre-DEPS hooks', default=False)
  parser.add_option('--upstream', action='store_true',
                    help='Make repo state match upstream branch.')
  parser.add_option('--break_repo_locks', action='store_true',
                    help='GIT ONLY - Forcibly remove repo locks (e.g. '
                      'index.lock). This should only be used if you know for '
                      'certain that this invocation of gclient is the only '
                      'thing operating on the git repos (e.g. on a bot).')
  (options, args) = parser.parse_args(args)
  # --force is implied.
  options.force = True
  options.reset = False
  options.delete_unversioned_trees = False
  options.merge = False
  client = GClient.LoadCurrentConfig(options)
  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')
  return client.RunOnDeps('revert', args)


@metrics.collector.collect_metrics('gclient runhooks')
def CMDrunhooks(parser, args):
  """Runs hooks for files that have been modified in the local working copy."""
  parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
                    help='override deps for the specified (comma-separated) '
                         'platform(s); \'all\' will process all deps_os '
                         'references')
  parser.add_option('-f', '--force', action='store_true', default=True,
                    help='Deprecated. No effect.')
  (options, args) = parser.parse_args(args)
  client = GClient.LoadCurrentConfig(options)
  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')
  if options.verbose:
    client.PrintLocationAndContents()
  options.force = True
  options.nohooks = False
  return client.RunOnDeps('runhooks', args)


@metrics.collector.collect_metrics('gclient revinfo')
def CMDrevinfo(parser, args):
  """Outputs revision info mapping for the client and its dependencies.

  This allows the capture of an overall 'revision' for the source tree that
  can be used to reproduce the same tree in the future. It is only useful for
  'unpinned dependencies', i.e. DEPS/deps references without a git hash.
  A git branch name isn't 'pinned' since the actual commit can change.
  """
  parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
                    help='override deps for the specified (comma-separated) '
                         'platform(s); \'all\' will process all deps_os '
                         'references')
  parser.add_option('-a', '--actual', action='store_true',
                    help='gets the actual checked out revisions instead of the '
                         'ones specified in the DEPS and .gclient files')
  parser.add_option('-s', '--snapshot', action='store_true',
                    help='creates a snapshot .gclient file of the current '
                         'version of all repositories to reproduce the tree, '
                         'implies -a')
  parser.add_option('--filter', action='append', dest='filter',
                     help='Display revision information only for the specified '
                          'dependencies (filtered by URL or path).')
  parser.add_option('--output-json',
                    help='Output a json document to this path containing '
                         'information about the revisions.')
  parser.add_option('--ignore-dep-type', choices=['git', 'cipd'],
                    help='Specify to skip processing of a certain type of dep.')
  (options, args) = parser.parse_args(args)
  client = GClient.LoadCurrentConfig(options)
  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')
  client.PrintRevInfo()
  return 0


@metrics.collector.collect_metrics('gclient getdep')
def CMDgetdep(parser, args):
  """Gets revision information and variable values from a DEPS file."""
  parser.add_option('--var', action='append',
                    dest='vars', metavar='VAR', default=[],
                    help='Gets the value of a given variable.')
  parser.add_option('-r', '--revision', action='append',
                    dest='getdep_revisions', metavar='DEP', default=[],
                    help='Gets the revision/version for the given dependency. '
                         'If it is a git dependency, dep must be a path. If it '
                         'is a CIPD dependency, dep must be of the form '
                         'path:package.')
  parser.add_option('--deps-file', default='DEPS',
                    # TODO(ehmaldonado): Try to find the DEPS file pointed by
                    # .gclient first.
                    help='The DEPS file to be edited. Defaults to the DEPS '
                         'file in the current directory.')
  (options, args) = parser.parse_args(args)

  if not os.path.isfile(options.deps_file):
    raise gclient_utils.Error(
        'DEPS file %s does not exist.' % options.deps_file)
  with open(options.deps_file) as f:
    contents = f.read()
  client = GClient.LoadCurrentConfig(options)
  if client is not None:
    builtin_vars = client.get_builtin_vars()
  else:
    logging.warn(
        'Couldn\'t find a valid gclient config. Will attempt to parse the DEPS '
        'file without support for built-in variables.')
    builtin_vars = None
  local_scope = gclient_eval.Exec(contents, options.deps_file,
                                  builtin_vars=builtin_vars)

  for var in options.vars:
    print(gclient_eval.GetVar(local_scope, var))

  for name in options.getdep_revisions:
    if ':' in name:
      name, _, package = name.partition(':')
      if not name or not package:
        parser.error(
            'Wrong CIPD format: %s:%s should be of the form path:pkg.'
            % (name, package))
      print(gclient_eval.GetCIPD(local_scope, name, package))
    else:
      print(gclient_eval.GetRevision(local_scope, name))


@metrics.collector.collect_metrics('gclient setdep')
def CMDsetdep(parser, args):
  """Modifies dependency revisions and variable values in a DEPS file"""
  parser.add_option('--var', action='append',
                    dest='vars', metavar='VAR=VAL', default=[],
                    help='Sets a variable to the given value with the format '
                         'name=value.')
  parser.add_option('-r', '--revision', action='append',
                    dest='setdep_revisions', metavar='DEP@REV', default=[],
                    help='Sets the revision/version for the dependency with '
                         'the format dep@rev. If it is a git dependency, dep '
                         'must be a path and rev must be a git hash or '
                         'reference (e.g. src/dep@deadbeef). If it is a CIPD '
                         'dependency, dep must be of the form path:package and '
                         'rev must be the package version '
                         '(e.g. src/pkg:chromium/pkg@2.1-cr0).')
  parser.add_option('--deps-file', default='DEPS',
                    # TODO(ehmaldonado): Try to find the DEPS file pointed by
                    # .gclient first.
                    help='The DEPS file to be edited. Defaults to the DEPS '
                         'file in the current directory.')
  (options, args) = parser.parse_args(args)
  if args:
    parser.error('Unused arguments: "%s"' % '" "'.join(args))
  if not options.setdep_revisions and not options.vars:
    parser.error(
        'You must specify at least one variable or revision to modify.')

  if not os.path.isfile(options.deps_file):
    raise gclient_utils.Error(
        'DEPS file %s does not exist.' % options.deps_file)
  with open(options.deps_file) as f:
    contents = f.read()

  client = GClient.LoadCurrentConfig(options)
  if client is not None:
    builtin_vars = client.get_builtin_vars()
  else:
    logging.warn(
        'Couldn\'t find a valid gclient config. Will attempt to parse the DEPS '
        'file without support for built-in variables.')
    builtin_vars = None

  local_scope = gclient_eval.Exec(contents, options.deps_file,
                                  builtin_vars=builtin_vars)

  for var in options.vars:
    name, _, value = var.partition('=')
    if not name or not value:
      parser.error(
          'Wrong var format: %s should be of the form name=value.' % var)
    if name in local_scope['vars']:
      gclient_eval.SetVar(local_scope, name, value)
    else:
      gclient_eval.AddVar(local_scope, name, value)

  for revision in options.setdep_revisions:
    name, _, value = revision.partition('@')
    if not name or not value:
      parser.error(
          'Wrong dep format: %s should be of the form dep@rev.' % revision)
    if ':' in name:
      name, _, package = name.partition(':')
      if not name or not package:
        parser.error(
            'Wrong CIPD format: %s:%s should be of the form path:pkg@version.'
            % (name, package))
      gclient_eval.SetCIPD(local_scope, name, package, value)
    else:
      gclient_eval.SetRevision(local_scope, name, value)

  with open(options.deps_file, 'w') as f:
    f.write(gclient_eval.RenderDEPSFile(local_scope))


@metrics.collector.collect_metrics('gclient verify')
def CMDverify(parser, args):
  """Verifies the DEPS file deps are only from allowed_hosts."""
  (options, args) = parser.parse_args(args)
  client = GClient.LoadCurrentConfig(options)
  if not client:
    raise gclient_utils.Error('client not configured; see \'gclient config\'')
  client.RunOnDeps(None, [])
  # Look at each first-level dependency of this gclient only.
  for dep in client.dependencies:
    bad_deps = dep.findDepsFromNotAllowedHosts()
    if not bad_deps:
      continue
    print("There are deps from not allowed hosts in file %s" % dep.deps_file)
    for bad_dep in bad_deps:
      print("\t%s at %s" % (bad_dep.name, bad_dep.url))
    print("allowed_hosts:", ', '.join(dep.allowed_hosts))
    sys.stdout.flush()
    raise gclient_utils.Error(
        'dependencies from disallowed hosts; check your DEPS file.')
  return 0


@subcommand.epilog("""For more information on what metrics are we collecting and
why, please read metrics.README.md or visit https://bit.ly/2ufRS4p""")
@metrics.collector.collect_metrics('gclient metrics')
def CMDmetrics(parser, args):
  """Reports, and optionally modifies, the status of metric collection."""
  parser.add_option('--opt-in', action='store_true', dest='enable_metrics',
                    help='Opt-in to metrics collection.',
                    default=None)
  parser.add_option('--opt-out', action='store_false', dest='enable_metrics',
                    help='Opt-out of metrics collection.')
  options, args = parser.parse_args(args)
  if args:
    parser.error('Unused arguments: "%s"' % '" "'.join(args))
  if not metrics.collector.config.is_googler:
    print("You're not a Googler. Metrics collection is disabled for you.")
    return 0

  if options.enable_metrics is not None:
    metrics.collector.config.opted_in = options.enable_metrics

  if metrics.collector.config.opted_in is None:
    print("You haven't opted in or out of metrics collection.")
  elif metrics.collector.config.opted_in:
    print("You have opted in. Thanks!")
  else:
    print("You have opted out. Please consider opting in.")
  return 0


class OptionParser(optparse.OptionParser):
  gclientfile_default = os.environ.get('GCLIENT_FILE', '.gclient')

  def __init__(self, **kwargs):
    optparse.OptionParser.__init__(
        self, version='%prog ' + __version__, **kwargs)

    # Some arm boards have issues with parallel sync.
    if platform.machine().startswith('arm'):
      jobs = 1
    else:
      jobs = max(8, gclient_utils.NumLocalCpus())

    self.add_option(
        '-j', '--jobs', default=jobs, type='int',
        help='Specify how many SCM commands can run in parallel; defaults to '
             '%default on this machine')
    self.add_option(
        '-v', '--verbose', action='count', default=0,
        help='Produces additional output for diagnostics. Can be used up to '
             'three times for more logging info.')
    self.add_option(
        '--gclientfile', dest='config_filename',
        help='Specify an alternate %s file' % self.gclientfile_default)
    self.add_option(
        '--spec',
        help='create a gclient file containing the provided string. Due to '
            'Cygwin/Python brokenness, it can\'t contain any newlines.')
    self.add_option(
        '--no-nag-max', default=False, action='store_true',
        help='Ignored for backwards compatibility.')

  def parse_args(self, args=None, _values=None):
    """Integrates standard options processing."""
    # Create an optparse.Values object that will store only the actual passed
    # options, without the defaults.
    actual_options = optparse.Values()
    _, args = optparse.OptionParser.parse_args(self, args, actual_options)
    # Create an optparse.Values object with the default options.
    options = optparse.Values(self.get_default_values().__dict__)
    # Update it with the options passed by the user.
    options._update_careful(actual_options.__dict__)
    # Store the options passed by the user in an _actual_options attribute.
    # We store only the keys, and not the values, since the values can contain
    # arbitrary information, which might be PII.
    metrics.collector.add('arguments', list(actual_options.__dict__))

    levels = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG]
    logging.basicConfig(
        level=levels[min(options.verbose, len(levels) - 1)],
        format='%(module)s(%(lineno)d) %(funcName)s:%(message)s')
    if options.config_filename and options.spec:
      self.error('Cannot specifiy both --gclientfile and --spec')
    if (options.config_filename and
        options.config_filename != os.path.basename(options.config_filename)):
      self.error('--gclientfile target must be a filename, not a path')
    if not options.config_filename:
      options.config_filename = self.gclientfile_default
    options.entries_filename = options.config_filename + '_entries'
    if options.jobs < 1:
      self.error('--jobs must be 1 or higher')

    # These hacks need to die.
    if not hasattr(options, 'revisions'):
      # GClient.RunOnDeps expects it even if not applicable.
      options.revisions = []
    if not hasattr(options, 'head'):
      options.head = None
    if not hasattr(options, 'nohooks'):
      options.nohooks = True
    if not hasattr(options, 'noprehooks'):
      options.noprehooks = True
    if not hasattr(options, 'deps_os'):
      options.deps_os = None
    if not hasattr(options, 'force'):
      options.force = None
    return (options, args)


def disable_buffering():
  # Make stdout auto-flush so buildbot doesn't kill us during lengthy
  # operations. Python as a strong tendency to buffer sys.stdout.
  sys.stdout = gclient_utils.MakeFileAutoFlush(sys.stdout)
  # Make stdout annotated with the thread ids.
  sys.stdout = gclient_utils.MakeFileAnnotated(sys.stdout)


def path_contains_tilde():
  for element in os.environ['PATH'].split(os.pathsep):
    if element.startswith('~') and os.path.abspath(
        os.path.realpath(os.path.expanduser(element))) == DEPOT_TOOLS_DIR:
      return True
  return False


def can_run_gclient_and_helpers():
  if sys.hexversion < 0x02060000:
    print(
        '\nYour python version %s is unsupported, please upgrade.\n' %
        sys.version.split(' ', 1)[0],
        file=sys.stderr)
    return False
  if not sys.executable:
    print(
        '\nPython cannot find the location of it\'s own executable.\n',
        file=sys.stderr)
    return False
  if path_contains_tilde():
    print(
        '\nYour PATH contains a literal "~", which works in some shells ' +
        'but will break when python tries to run subprocesses. ' +
        'Replace the "~" with $HOME.\n' +
        'See https://crbug.com/952865.\n',
        file=sys.stderr)
    return False
  return True


def main(argv):
  """Doesn't parse the arguments here, just find the right subcommand to
  execute."""
  if not can_run_gclient_and_helpers():
    return 2
  fix_encoding.fix_encoding()
  disable_buffering()
  setup_color.init()
  dispatcher = subcommand.CommandDispatcher(__name__)
  try:
    return dispatcher.execute(OptionParser(), argv)
  except KeyboardInterrupt:
    gclient_utils.GClientChildren.KillAllRemainingChildren()
    raise
  except (gclient_utils.Error, subprocess2.CalledProcessError) as e:
    print('Error: %s' % str(e), file=sys.stderr)
    return 1
  finally:
    gclient_utils.PrintWarnings()
  return 0


if '__main__' == __name__:
  with metrics.collector.print_notice_and_exit():
    sys.exit(main(sys.argv[1:]))

# vim: ts=2:sw=2:tw=80:et:
