#!/usr/bin/env vpython3

# 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 urllib.request


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',
    'src/third_party/mockito/src',
]

# 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/gtest-parallel',
    'src/third_party/pipewire/linux-amd64',
    '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')
VersionEntry = collections.namedtuple('VersionEntry', 'version')
ChangedCipdPackage = collections.namedtuple(
    'ChangedCipdPackage', 'path package current_version new_version')
ChangedVersionEntry = collections.namedtuple(
    'ChangedVersionEntry', 'path 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().decode('utf-8')
  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]).decode('utf-8')


def ReadRemoteCrFile(path_below_src, revision):
  """Reads a remote Chromium file of a specific revision.

    Args:
      path_below_src: A path to the target file relative to src dir.
      revision: Revision to read.
    Returns:
      A string with file content.
    """
  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.

    Args:
      url: URL to connect to.
    Returns:
      A list of lines.
    """
  conn = urllib.request.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.items():
    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 deps dict."""
  result = {}

  def AddDepsEntries(deps_subdict):
    for path, dep in deps_subdict.items():
      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)

  def AddVersionEntry(vars_subdict):
    for key, value in vars_subdict.items():
      if key in result:
        continue
      if not key.endswith('_version'):
        continue
      key = re.sub('_version$', '', key)
      result[key] = VersionEntry(value)

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


def _FindChangedCipdPackages(path, old_pkgs, new_pkgs):
  old_pkgs_names = {p['package'] for p in old_pkgs}
  new_pkgs_names = {p['package'] for p in new_pkgs}
  pkgs_equal = (old_pkgs_names == new_pkgs_names)
  added_pkgs = [p for p in new_pkgs_names if p not in old_pkgs_names]
  removed_pkgs = [p for p in old_pkgs_names if p not in new_pkgs_names]

  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.\nMost likely, you should add \"%s\" and '
                      'remove \"%s\"' %
                      (old_pkgs, new_pkgs, added_pkgs, removed_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 _FindChangedVars(name, old_version, new_version):
  if old_version != new_version:
    logging.debug('Roll dependency %s to %s', name, new_version)
    yield ChangedVersionEntry(name, 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 = sorted(
      [path for path in all_removed_deps if path.startswith(ANDROID_DEPS_PATH)])
  # Webrtc-only dependencies are handled in CalculateChangedDeps.
  other_deps = sorted([
      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.items():
    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

      if isinstance(cr_deps_entry, VersionEntry):
        result.extend(
            _FindChangedVars(path, webrtc_deps_entry.version,
                             cr_deps_entry.version))
        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, 'r') 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))

  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))
      elif isinstance(c, ChangedVersionEntry):
        commit_msg.append('* %s_vesion: %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 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')

  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().decode('utf-8')

  # 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)

  for dep in changed_deps:
    if isinstance(dep, ChangedVersionEntry):
      deps_content = deps_content.replace(dep.current_version, dep.new_version)

  with open(deps_filename, 'wb') as deps_file:
    deps_file.write(deps_content.encode('utf-8'))

  # Update each individual DEPS entry.
  for dep in changed_deps:
    # ChangedVersionEntry types are already been processed.
    if isinstance(dep, ChangedVersionEntry):
      continue
    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 _EnsureUpdatedMainBranch(dry_run):
  current_branch = _RunCommand(['git', 'rev-parse', '--abbrev-ref',
                                'HEAD'])[0].splitlines()[0]
  if current_branch != 'main':
    logging.error('Please checkout the main branch and re-run this script.')
    if not dry_run:
      sys.exit(-1)

  logging.info('Updating main 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 = 'main'
  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 _GetCcRecipients(changed_deps_list):
  """Returns a list of emails to notify based on the changed deps list.
    """
  cc_recipients = []
  for c in changed_deps_list:
    if 'libvpx' in c.path or 'libaom' in c.path:
      cc_recipients.append('marpan@webrtc.org')
      cc_recipients.append('jianj@chromium.org')
  return cc_recipients


def _UploadCL(commit_queue_mode, add_cc=None):
  """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.

    add_cc: A list of email addresses to add as CC recipients.
    """
  cc_recipients = [NOTIFY_EMAIL]
  if add_cc:
    cc_recipients.extend(add_cc)
  cmd = ['git', 'cl', 'upload', '--force', '--bypass-hooks']
  if commit_queue_mode >= 2:
    logging.info('Sending the CL to the CQ...')
    cmd.extend(['-o', 'label=Bot-Commit+1'])
    cmd.extend(['-o', 'label=Commit-Queue+2'])
    cmd.extend(['--send-mail', '--cc', ','.join(cc_recipients)])
  elif commit_queue_mode >= 1:
    logging.info('Starting CQ dry run...')
    cmd.extend(['-o', 'label=Commit-Queue+1'])
  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 main 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:
    _EnsureUpdatedMainBranch(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, _GetCcRecipients(changed_deps))
  return 0


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