#!/usr/bin/env python
# Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.

"""Script to automatically roll dependencies in the WebRTC DEPS file."""

import argparse
import base64
import collections
import logging
import os
import re
import subprocess
import sys
import urllib2

def FindSrcDirPath():
  """Returns the abs path to the src/ dir of the project."""
  src_dir = os.path.dirname(os.path.abspath(__file__))
  while os.path.basename(src_dir) != 'src':
    src_dir = os.path.normpath(os.path.join(src_dir, os.pardir))
  return src_dir

# Skip these dependencies (list without solution name prefix).
DONT_AUTOROLL_THESE = [
  'src/examples/androidtests/third_party/gradle',
]

# These dependencies are missing in chromium/src/DEPS, either unused or already
# in-tree. For instance, src/base is a part of the Chromium source git repo,
# but we pull it through a subtree mirror, so therefore it isn't listed in
# Chromium's deps but it is in ours.
WEBRTC_ONLY_DEPS = [
  'src/base',
  'src/build',
  'src/buildtools',
  'src/ios',
  'src/testing',
  'src/third_party',
  'src/third_party/findbugs',
  'src/third_party/gtest-parallel',
  'src/third_party/yasm/binaries',
  'src/tools',
]


WEBRTC_URL = 'https://webrtc.googlesource.com/src'
CHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src'
CHROMIUM_COMMIT_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s'
CHROMIUM_LOG_TEMPLATE = CHROMIUM_SRC_URL + '/+log/%s'
CHROMIUM_FILE_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s/%s'

COMMIT_POSITION_RE = re.compile('^Cr-Commit-Position: .*#([0-9]+).*$')
CLANG_REVISION_RE = re.compile(r'^CLANG_REVISION = \'([-0-9a-z]+)\'$')
ROLL_BRANCH_NAME = 'roll_chromium_revision'

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
CHECKOUT_SRC_DIR = FindSrcDirPath()
CHECKOUT_ROOT_DIR = os.path.realpath(os.path.join(CHECKOUT_SRC_DIR, os.pardir))

# Copied from tools/android/roll/android_deps/.../BuildConfigGenerator.groovy.
ANDROID_DEPS_START = r'=== ANDROID_DEPS Generated Code Start ==='
ANDROID_DEPS_END = r'=== ANDROID_DEPS Generated Code End ==='
# Location of automically gathered android deps.
ANDROID_DEPS_PATH = 'src/third_party/android_deps/'

NOTIFY_EMAIL = 'webrtc-trooper@grotations.appspotmail.com'


sys.path.append(os.path.join(CHECKOUT_SRC_DIR, 'build'))
import find_depot_tools

find_depot_tools.add_depot_tools_to_path()

CLANG_UPDATE_SCRIPT_URL_PATH = 'tools/clang/scripts/update.py'
CLANG_UPDATE_SCRIPT_LOCAL_PATH = os.path.join(CHECKOUT_SRC_DIR, 'tools',
                                              'clang', 'scripts', 'update.py')

DepsEntry = collections.namedtuple('DepsEntry', 'path url revision')
ChangedDep = collections.namedtuple(
    'ChangedDep', 'path url current_rev new_rev')
CipdDepsEntry = collections.namedtuple('CipdDepsEntry', 'path packages')
ChangedCipdPackage = collections.namedtuple(
    'ChangedCipdPackage', 'path package current_version new_version')

ChromiumRevisionUpdate = collections.namedtuple('ChromiumRevisionUpdate',
                                                ('current_chromium_rev '
                                                 'new_chromium_rev '))


class RollError(Exception):
  pass


def StrExpansion():
  return lambda str_value: str_value


def VarLookup(local_scope):
  return lambda var_name: local_scope['vars'][var_name]


def ParseDepsDict(deps_content):
  local_scope = {}
  global_scope = {
    'Str': StrExpansion(),
    'Var': VarLookup(local_scope),
    'deps_os': {},
  }
  exec (deps_content, global_scope, local_scope)
  return local_scope


def ParseLocalDepsFile(filename):
  with open(filename, 'rb') as f:
    deps_content = f.read()
  return ParseDepsDict(deps_content)


def ParseCommitPosition(commit_message):
  for line in reversed(commit_message.splitlines()):
    m = COMMIT_POSITION_RE.match(line.strip())
    if m:
      return int(m.group(1))
  logging.error('Failed to parse commit position id from:\n%s\n',
                commit_message)
  sys.exit(-1)


def _RunCommand(command, working_dir=None, ignore_exit_code=False,
    extra_env=None, input_data=None):
  """Runs a command and returns the output from that command.

  If the command fails (exit code != 0), the function will exit the process.

  Returns:
    A tuple containing the stdout and stderr outputs as strings.
  """
  working_dir = working_dir or CHECKOUT_SRC_DIR
  logging.debug('CMD: %s CWD: %s', ' '.join(command), working_dir)
  env = os.environ.copy()
  if extra_env:
    assert all(isinstance(value, str) for value in extra_env.values())
    logging.debug('extra env: %s', extra_env)
    env.update(extra_env)
  p = subprocess.Popen(command,
                       stdin=subprocess.PIPE,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE, env=env,
                       cwd=working_dir, universal_newlines=True)
  std_output, err_output = p.communicate(input_data)
  p.stdout.close()
  p.stderr.close()
  if not ignore_exit_code and p.returncode != 0:
    logging.error('Command failed: %s\n'
                  'stdout:\n%s\n'
                  'stderr:\n%s\n', ' '.join(command), std_output, err_output)
    sys.exit(p.returncode)
  return std_output, err_output


def _GetBranches():
  """Returns a tuple of active,branches.

  The 'active' is the name of the currently active branch and 'branches' is a
  list of all branches.
  """
  lines = _RunCommand(['git', 'branch'])[0].split('\n')
  branches = []
  active = ''
  for line in lines:
    if '*' in line:
      # The assumption is that the first char will always be the '*'.
      active = line[1:].strip()
      branches.append(active)
    else:
      branch = line.strip()
      if branch:
        branches.append(branch)
  return active, branches


def _ReadGitilesContent(url):
  # Download and decode BASE64 content until
  # https://code.google.com/p/gitiles/issues/detail?id=7 is fixed.
  base64_content = ReadUrlContent(url + '?format=TEXT')
  return base64.b64decode(base64_content[0])


def ReadRemoteCrFile(path_below_src, revision):
  """Reads a remote Chromium file of a specific revision. Returns a string."""
  return _ReadGitilesContent(CHROMIUM_FILE_TEMPLATE % (revision,
                                                       path_below_src))


def ReadRemoteCrCommit(revision):
  """Reads a remote Chromium commit message. Returns a string."""
  return _ReadGitilesContent(CHROMIUM_COMMIT_TEMPLATE % revision)


def ReadUrlContent(url):
  """Connect to a remote host and read the contents. Returns a list of lines."""
  conn = urllib2.urlopen(url)
  try:
    return conn.readlines()
  except IOError as e:
    logging.exception('Error connecting to %s. Error: %s', url, e)
    raise
  finally:
    conn.close()


def GetMatchingDepsEntries(depsentry_dict, dir_path):
  """Gets all deps entries matching the provided path.

  This list may contain more than one DepsEntry object.
  Example: dir_path='src/testing' would give results containing both
  'src/testing/gtest' and 'src/testing/gmock' deps entries for Chromium's DEPS.
  Example 2: dir_path='src/build' should return 'src/build' but not
  'src/buildtools'.

  Returns:
    A list of DepsEntry objects.
  """
  result = []
  for path, depsentry in depsentry_dict.iteritems():
    if path == dir_path:
      result.append(depsentry)
    else:
      parts = path.split('/')
      if all(part == parts[i]
             for i, part in enumerate(dir_path.split('/'))):
        result.append(depsentry)
  return result


def BuildDepsentryDict(deps_dict):
  """Builds a dict of paths to DepsEntry objects from a raw parsed deps dict."""
  result = {}

  def AddDepsEntries(deps_subdict):
    for path, dep in deps_subdict.iteritems():
      if path in result:
        continue
      if not isinstance(dep, dict):
        dep = {'url': dep}
      if dep.get('dep_type') == 'cipd':
        result[path] = CipdDepsEntry(path, dep['packages'])
      else:
        if '@' not in dep['url']:
          continue
        url, revision = dep['url'].split('@')
        result[path] = DepsEntry(path, url, revision)

  AddDepsEntries(deps_dict['deps'])
  for deps_os in ['win', 'mac', 'unix', 'android', 'ios', 'unix']:
    AddDepsEntries(deps_dict.get('deps_os', {}).get(deps_os, {}))
  return result


def _FindChangedCipdPackages(path, old_pkgs, new_pkgs):
  pkgs_equal = ({p['package'] for p in old_pkgs} ==
      {p['package'] for p in new_pkgs})
  assert pkgs_equal, ('Old: %s\n New: %s.\nYou need to do a manual roll '
                      'and remove/add entries in DEPS so the old and new '
                      'list match.' % (old_pkgs, new_pkgs))
  for old_pkg in old_pkgs:
    for new_pkg in new_pkgs:
      old_version = old_pkg['version']
      new_version = new_pkg['version']
      if (old_pkg['package'] == new_pkg['package'] and
          old_version != new_version):
        logging.debug('Roll dependency %s to %s', path, new_version)
        yield ChangedCipdPackage(path, old_pkg['package'],
                                 old_version, new_version)


def _FindNewDeps(old, new):
  """ Gather dependencies only in |new| and return corresponding paths. """
  old_entries = set(BuildDepsentryDict(old))
  new_entries = set(BuildDepsentryDict(new))
  return [path for path in new_entries - old_entries
          if path not in DONT_AUTOROLL_THESE]


def FindAddedDeps(webrtc_deps, new_cr_deps):
  """
  Calculate new deps entries of interest.

  Ideally, that would mean: only appearing in chromium DEPS
  but transitively used in WebRTC.

  Since it's hard to compute, we restrict ourselves to a well defined subset:
  deps sitting in |ANDROID_DEPS_PATH|.
  Otherwise, assumes that's a Chromium-only dependency.

  Args:
    webrtc_deps: dict of deps as defined in the WebRTC DEPS file.
    new_cr_deps: dict of deps as defined in the chromium DEPS file.

  Caveat: Doesn't detect a new package in existing dep.

  Returns:
    A tuple consisting of:
      A list of paths added dependencies sitting in |ANDROID_DEPS_PATH|.
      A list of paths for other added dependencies.
  """
  all_added_deps = _FindNewDeps(webrtc_deps, new_cr_deps)
  generated_android_deps = [path for path in all_added_deps
                            if path.startswith(ANDROID_DEPS_PATH)]
  other_deps = [path for path in all_added_deps
                if path not in generated_android_deps]
  return generated_android_deps, other_deps


def FindRemovedDeps(webrtc_deps, new_cr_deps):
  """
  Calculate obsolete deps entries.

  Ideally, that would mean: no more appearing in chromium DEPS
  and not used in WebRTC.

  Since it's hard to compute:
   1/ We restrict ourselves to a well defined subset:
      deps sitting in |ANDROID_DEPS_PATH|.
   2/ We rely on existing behavior of CalculateChangeDeps.
      I.e. Assumes non-CIPD dependencies are WebRTC-only, don't remove them.

  Args:
    webrtc_deps: dict of deps as defined in the WebRTC DEPS file.
    new_cr_deps: dict of deps as defined in the chromium DEPS file.

  Caveat: Doesn't detect a deleted package in existing dep.

  Returns:
    A tuple consisting of:
      A list of paths of dependencies removed from |ANDROID_DEPS_PATH|.
      A list of paths of unexpected disappearing dependencies.
  """
  all_removed_deps = _FindNewDeps(new_cr_deps, webrtc_deps)
  generated_android_deps = [path for path in all_removed_deps
                            if path.startswith(ANDROID_DEPS_PATH)]
  # Webrtc-only dependencies are handled in CalculateChangedDeps.
  other_deps = [path for path in all_removed_deps
                if path not in generated_android_deps and
                   path not in WEBRTC_ONLY_DEPS]
  return generated_android_deps, other_deps


def CalculateChangedDeps(webrtc_deps, new_cr_deps):
  """
  Calculate changed deps entries based on entries defined in the WebRTC DEPS
  file:
     - If a shared dependency with the Chromium DEPS file: roll it to the same
       revision as Chromium (i.e. entry in the new_cr_deps dict)
     - If it's a Chromium sub-directory, roll it to the HEAD revision (notice
       this means it may be ahead of the chromium_revision, but generally these
       should be close).
     - If it's another DEPS entry (not shared with Chromium), roll it to HEAD
       unless it's configured to be skipped.

  Returns:
    A list of ChangedDep objects representing the changed deps.
  """
  result = []
  webrtc_entries = BuildDepsentryDict(webrtc_deps)
  new_cr_entries = BuildDepsentryDict(new_cr_deps)
  for path, webrtc_deps_entry in webrtc_entries.iteritems():
    if path in DONT_AUTOROLL_THESE:
      continue
    cr_deps_entry = new_cr_entries.get(path)
    if cr_deps_entry:
      assert type(cr_deps_entry) is type(webrtc_deps_entry)

      if isinstance(cr_deps_entry, CipdDepsEntry):
        result.extend(_FindChangedCipdPackages(path, webrtc_deps_entry.packages,
                                               cr_deps_entry.packages))
        continue

      # Use the revision from Chromium's DEPS file.
      new_rev = cr_deps_entry.revision
      assert webrtc_deps_entry.url == cr_deps_entry.url, (
          'WebRTC DEPS entry %s has a different URL (%s) than Chromium (%s).' %
          (path, webrtc_deps_entry.url, cr_deps_entry.url))
    else:
      if isinstance(webrtc_deps_entry, DepsEntry):
        # Use the HEAD of the deps repo.
        stdout, _ = _RunCommand(['git', 'ls-remote', webrtc_deps_entry.url,
                                'HEAD'])
        new_rev = stdout.strip().split('\t')[0]
      else:
        # The dependency has been removed from chromium.
        # This is handled by FindRemovedDeps.
        continue

    # Check if an update is necessary.
    if webrtc_deps_entry.revision != new_rev:
      logging.debug('Roll dependency %s to %s', path, new_rev)
      result.append(ChangedDep(path, webrtc_deps_entry.url,
                               webrtc_deps_entry.revision, new_rev))
  return sorted(result)


def CalculateChangedClang(new_cr_rev):
  def GetClangRev(lines):
    for line in lines:
      match = CLANG_REVISION_RE.match(line)
      if match:
        return match.group(1)
    raise RollError('Could not parse Clang revision!')

  with open(CLANG_UPDATE_SCRIPT_LOCAL_PATH, 'rb') as f:
    current_lines = f.readlines()
  current_rev = GetClangRev(current_lines)

  new_clang_update_py = ReadRemoteCrFile(CLANG_UPDATE_SCRIPT_URL_PATH,
                                         new_cr_rev).splitlines()
  new_rev = GetClangRev(new_clang_update_py)
  return ChangedDep(CLANG_UPDATE_SCRIPT_LOCAL_PATH, None, current_rev, new_rev)


def GenerateCommitMessage(rev_update, current_commit_pos, new_commit_pos,
                          changed_deps_list,
                          added_deps_paths=None,
                          removed_deps_paths=None,
                          clang_change=None,
                          ):
  current_cr_rev = rev_update.current_chromium_rev[0:10]
  new_cr_rev = rev_update.new_chromium_rev[0:10]
  rev_interval = '%s..%s' % (current_cr_rev, new_cr_rev)
  git_number_interval = '%s:%s' % (current_commit_pos, new_commit_pos)

  commit_msg = ['Roll chromium_revision %s (%s)\n' % (rev_interval,
                                                      git_number_interval),
                'Change log: %s' % (CHROMIUM_LOG_TEMPLATE % rev_interval),
                'Full diff: %s\n' % (CHROMIUM_COMMIT_TEMPLATE %
                                     rev_interval)]

  def Section(adjective, deps):
    noun = 'dependency' if len(deps) == 1 else 'dependencies'
    commit_msg.append('%s %s' % (adjective, noun))

  tbr_authors = ''
  if changed_deps_list:
    Section('Changed', changed_deps_list)

    for c in changed_deps_list:
      if isinstance(c, ChangedCipdPackage):
        commit_msg.append('* %s: %s..%s' % (c.path, c.current_version,
                                            c.new_version))
      else:
        commit_msg.append('* %s: %s/+log/%s..%s' % (c.path, c.url,
                                                    c.current_rev[0:10],
                                                    c.new_rev[0:10]))
      if 'libvpx' in c.path:
        tbr_authors += 'marpan@webrtc.org, jianj@chromium.org, '

  if added_deps_paths:
    Section('Added', added_deps_paths)
    commit_msg.extend('* %s' % p for p in added_deps_paths)

  if removed_deps_paths:
    Section('Removed', removed_deps_paths)
    commit_msg.extend('* %s' % p for p in removed_deps_paths)

  if any([changed_deps_list,
          added_deps_paths,
          removed_deps_paths]):
    change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval, 'DEPS')
    commit_msg.append('DEPS diff: %s\n' % change_url)
  else:
    commit_msg.append('No dependencies changed.')

  if clang_change and clang_change.current_rev != clang_change.new_rev:
    commit_msg.append('Clang version changed %s:%s' %
                      (clang_change.current_rev, clang_change.new_rev))
    change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval,
                                           CLANG_UPDATE_SCRIPT_URL_PATH)
    commit_msg.append('Details: %s\n' % change_url)
  else:
    commit_msg.append('No update to Clang.\n')

  # TBR needs to be non-empty for Gerrit to process it.
  git_author = _RunCommand(['git', 'config', 'user.email'],
                           working_dir=CHECKOUT_SRC_DIR)[0].splitlines()[0]
  tbr_authors = git_author + ',' + tbr_authors

  commit_msg.append('TBR=%s' % tbr_authors)
  commit_msg.append('BUG=None')
  return '\n'.join(commit_msg)


def UpdateDepsFile(deps_filename, rev_update, changed_deps, new_cr_content):
  """Update the DEPS file with the new revision."""

  with open(deps_filename, 'rb') as deps_file:
    deps_content = deps_file.read()

  # Update the chromium_revision variable.
  deps_content = deps_content.replace(rev_update.current_chromium_rev,
                                      rev_update.new_chromium_rev)

  # Add and remove dependencies. For now: only generated android deps.
  # Since gclient cannot add or remove deps, we on the fact that
  # these android deps are located in one place we can copy/paste.
  deps_re = re.compile(ANDROID_DEPS_START + '.*' + ANDROID_DEPS_END,
                       re.DOTALL)
  new_deps = deps_re.search(new_cr_content)
  old_deps = deps_re.search(deps_content)
  if not new_deps or not old_deps:
    faulty = 'Chromium' if not new_deps else 'WebRTC'
    raise RollError('Was expecting to find "%s" and "%s"\n'
                    'in %s DEPS'
                    % (ANDROID_DEPS_START, ANDROID_DEPS_END, faulty))
  deps_content = deps_re.sub(new_deps.group(0), deps_content)

  with open(deps_filename, 'wb') as deps_file:
    deps_file.write(deps_content)

  # Update each individual DEPS entry.
  for dep in changed_deps:
    local_dep_dir = os.path.join(CHECKOUT_ROOT_DIR, dep.path)
    if not os.path.isdir(local_dep_dir):
      raise RollError(
          'Cannot find local directory %s. Either run\n'
          'gclient sync --deps=all\n'
          'or make sure the .gclient file for your solution contains all '
          'platforms in the target_os list, i.e.\n'
          'target_os = ["android", "unix", "mac", "ios", "win"];\n'
          'Then run "gclient sync" again.' % local_dep_dir)
    if isinstance(dep, ChangedCipdPackage):
      package = dep.package.format()  # Eliminate double curly brackets
      update = '%s:%s@%s' % (dep.path, package, dep.new_version)
    else:
      update = '%s@%s' % (dep.path, dep.new_rev)
    _RunCommand(['gclient', 'setdep', '--revision', update],
                working_dir=CHECKOUT_SRC_DIR)


def _IsTreeClean():
  stdout, _ = _RunCommand(['git', 'status', '--porcelain'])
  if len(stdout) == 0:
    return True

  logging.error('Dirty/unversioned files:\n%s', stdout)
  return False


def _EnsureUpdatedMasterBranch(dry_run):
  current_branch = _RunCommand(
      ['git', 'rev-parse', '--abbrev-ref', 'HEAD'])[0].splitlines()[0]
  if current_branch != 'master':
    logging.error('Please checkout the master branch and re-run this script.')
    if not dry_run:
      sys.exit(-1)

  logging.info('Updating master branch...')
  _RunCommand(['git', 'pull'])


def _CreateRollBranch(dry_run):
  logging.info('Creating roll branch: %s', ROLL_BRANCH_NAME)
  if not dry_run:
    _RunCommand(['git', 'checkout', '-b', ROLL_BRANCH_NAME])


def _RemovePreviousRollBranch(dry_run):
  active_branch, branches = _GetBranches()
  if active_branch == ROLL_BRANCH_NAME:
    active_branch = 'master'
  if ROLL_BRANCH_NAME in branches:
    logging.info('Removing previous roll branch (%s)', ROLL_BRANCH_NAME)
    if not dry_run:
      _RunCommand(['git', 'checkout', active_branch])
      _RunCommand(['git', 'branch', '-D', ROLL_BRANCH_NAME])


def _LocalCommit(commit_msg, dry_run):
  logging.info('Committing changes locally.')
  if not dry_run:
    _RunCommand(['git', 'add', '--update', '.'])
    _RunCommand(['git', 'commit', '-m', commit_msg])


def ChooseCQMode(skip_cq, cq_over, current_commit_pos, new_commit_pos):
  if skip_cq:
    return 0
  if (new_commit_pos - current_commit_pos) < cq_over:
    return 1
  return 2


def _UploadCL(commit_queue_mode):
  """Upload the committed changes as a changelist to Gerrit.

  commit_queue_mode:
    - 2: Submit to commit queue.
    - 1: Run trybots but do not submit to CQ.
    - 0: Skip CQ, upload only.
  """
  cmd = ['git', 'cl', 'upload', '--force', '--bypass-hooks']
  if commit_queue_mode >= 2:
    logging.info('Sending the CL to the CQ...')
    cmd.extend(['--use-commit-queue'])
    cmd.extend(['--send-mail', '--cc', NOTIFY_EMAIL])
  elif commit_queue_mode >= 1:
    logging.info('Starting CQ dry run...')
    cmd.extend(['--cq-dry-run'])
  extra_env = {
      'EDITOR': 'true',
      'SKIP_GCE_AUTH_FOR_GIT': '1',
  }
  stdout, stderr = _RunCommand(cmd, extra_env=extra_env)
  logging.debug('Output from "git cl upload":\nstdout:\n%s\n\nstderr:\n%s',
      stdout, stderr)


def GetRollRevisionRanges(opts, webrtc_deps):
  current_cr_rev = webrtc_deps['vars']['chromium_revision']
  new_cr_rev = opts.revision
  if not new_cr_rev:
    stdout, _ = _RunCommand(['git', 'ls-remote', CHROMIUM_SRC_URL, 'HEAD'])
    head_rev = stdout.strip().split('\t')[0]
    logging.info('No revision specified. Using HEAD: %s', head_rev)
    new_cr_rev = head_rev

  return ChromiumRevisionUpdate(current_cr_rev, new_cr_rev)


def main():
  p = argparse.ArgumentParser()
  p.add_argument('--clean', action='store_true', default=False,
                 help='Removes any previous local roll branch.')
  p.add_argument('-r', '--revision',
                 help=('Chromium Git revision to roll to. Defaults to the '
                       'Chromium HEAD revision if omitted.'))
  p.add_argument('--dry-run', action='store_true', default=False,
                 help=('Calculate changes and modify DEPS, but don\'t create '
                       'any local branch, commit, upload CL or send any '
                       'tryjobs.'))
  p.add_argument('-i', '--ignore-unclean-workdir', action='store_true',
                 default=False,
                 help=('Ignore if the current branch is not master or if there '
                       'are uncommitted changes (default: %(default)s).'))
  grp = p.add_mutually_exclusive_group()
  grp.add_argument('--skip-cq', action='store_true', default=False,
                   help='Skip sending the CL to the CQ (default: %(default)s)')
  grp.add_argument('--cq-over', type=int, default=1,
                   help=('Commit queue dry run if the revision difference '
                         'is below this number (default: %(default)s)'))
  p.add_argument('-v', '--verbose', action='store_true', default=False,
                 help='Be extra verbose in printing of log messages.')
  opts = p.parse_args()

  if opts.verbose:
    logging.basicConfig(level=logging.DEBUG)
  else:
    logging.basicConfig(level=logging.INFO)

  if not opts.ignore_unclean_workdir and not _IsTreeClean():
    logging.error('Please clean your local checkout first.')
    return 1

  if opts.clean:
    _RemovePreviousRollBranch(opts.dry_run)

  if not opts.ignore_unclean_workdir:
    _EnsureUpdatedMasterBranch(opts.dry_run)

  deps_filename = os.path.join(CHECKOUT_SRC_DIR, 'DEPS')
  webrtc_deps = ParseLocalDepsFile(deps_filename)

  rev_update = GetRollRevisionRanges(opts, webrtc_deps)

  current_commit_pos = ParseCommitPosition(
      ReadRemoteCrCommit(rev_update.current_chromium_rev))
  new_commit_pos = ParseCommitPosition(
      ReadRemoteCrCommit(rev_update.new_chromium_rev))

  new_cr_content = ReadRemoteCrFile('DEPS', rev_update.new_chromium_rev)
  new_cr_deps = ParseDepsDict(new_cr_content)
  changed_deps = CalculateChangedDeps(webrtc_deps, new_cr_deps)
  # Discard other deps, assumed to be chromium-only dependencies.
  new_generated_android_deps, _ = FindAddedDeps(webrtc_deps, new_cr_deps)
  removed_generated_android_deps, other_deps = FindRemovedDeps(webrtc_deps,
                                                               new_cr_deps)
  if other_deps:
    raise RollError('WebRTC DEPS entries are missing from Chromium: %s.\n'
          'Remove them or add them to either '
          'WEBRTC_ONLY_DEPS or DONT_AUTOROLL_THESE.' % other_deps)
  clang_change = CalculateChangedClang(rev_update.new_chromium_rev)
  commit_msg = GenerateCommitMessage(
      rev_update, current_commit_pos, new_commit_pos, changed_deps,
      added_deps_paths=new_generated_android_deps,
      removed_deps_paths=removed_generated_android_deps,
      clang_change=clang_change)
  logging.debug('Commit message:\n%s', commit_msg)

  _CreateRollBranch(opts.dry_run)
  if not opts.dry_run:
    UpdateDepsFile(deps_filename, rev_update, changed_deps, new_cr_content)
  if _IsTreeClean():
    logging.info("No DEPS changes detected, skipping CL creation.")
  else:
    _LocalCommit(commit_msg, opts.dry_run)
    commit_queue_mode = ChooseCQMode(opts.skip_cq, opts.cq_over,
                                     current_commit_pos, new_commit_pos)
    logging.info('Uploading CL...')
    if not opts.dry_run:
      _UploadCL(commit_queue_mode)
  return 0


if __name__ == '__main__':
  sys.exit(main())
