#!/usr/bin/env python3
# Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import argparse
import datetime
import os.path
import re
import subprocess
import sys
import urllib.request
import xml.etree.ElementTree
import zipfile

import utils

R8_DEV_BRANCH = '3.1'
R8_VERSION_FILE = os.path.join(
    'src', 'main', 'java', 'com', 'android', 'tools', 'r8', 'Version.java')
THIS_FILE_RELATIVE = os.path.join('tools', 'r8_release.py')
GMAVEN_PUBLISHER = '/google/bin/releases/android-devtools/gmaven/publisher/gmaven-publisher'

DESUGAR_JDK_LIBS = 'desugar_jdk_libs'
DESUGAR_JDK_LIBS_CONFIGURATION = DESUGAR_JDK_LIBS + '_configuration'
ANDROID_TOOLS_PACKAGE = 'com.android.tools'

GITHUB_DESUGAR_JDK_LIBS = 'https://github.com/google/desugar_jdk_libs'

def checkout_r8(temp, branch):
  subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
  with utils.ChangedWorkingDirectory(temp):
    subprocess.check_call([
      'git',
      'new-branch',
      '--upstream',
      'origin/%s' % branch,
      'dev-release'])
  return temp


def prepare_release(args):
  if args.version:
    print("Cannot manually specify version when making a dev release.")
    sys.exit(1)

  def make_release(args):
    commithash = args.dev_release

    with utils.TempDir() as temp:
      with utils.ChangedWorkingDirectory(checkout_r8(temp, R8_DEV_BRANCH)):
        # Compute the current and new version on the branch.
        result = None
        for line in open(R8_VERSION_FILE, 'r'):
          result = re.match(
              r'.*LABEL = "%s\.(\d+)\-dev";' % R8_DEV_BRANCH, line)
          if result:
            break
        if not result or not result.group(1):
          print('Failed to find version label matching %s(\d+)-dev'\
                % R8_DEV_BRANCH)
          sys.exit(1)
        try:
          patch_version = int(result.group(1))
        except ValueError:
          print('Failed to convert version to integer: %s' % result.group(1))

        old_version = '%s.%s-dev' % (R8_DEV_BRANCH, patch_version)
        version = '%s.%s-dev' % (R8_DEV_BRANCH, patch_version + 1)

        # Verify that the merge point from main is not empty.
        merge_diff_output = subprocess.check_output([
          'git', 'diff', 'HEAD..%s' % commithash]).decode('utf-8')
        other_diff = version_change_diff(
            merge_diff_output, old_version, "main")
        if not other_diff:
          print('Merge point from main (%s)' % commithash, \
            'is the same as exiting release (%s).' % old_version)
          sys.exit(1)

        if args.dev_pre_cherry_pick:
          for pre_commit in args.dev_pre_cherry_pick:
            subprocess.check_call([
                'git', 'cherry-pick', '--no-edit', pre_commit])

        # Merge the desired commit from main on to the branch.
        subprocess.check_call([
          'git', 'merge', '--no-ff', '--no-edit', commithash])

        # Rewrite the version, commit and validate.
        sed(old_version, version, R8_VERSION_FILE)

        subprocess.check_call([
          'git', 'commit', '-a', '-m', 'Version %s' % version])

        version_diff_output = subprocess.check_output([
          'git', 'diff', '%s..HEAD' % commithash]).decode('utf-8')

        validate_version_change_diff(version_diff_output, "main", version)

        # Double check that we want to push the release.
        if not args.dry_run:
          answer = input('Publish dev release version %s [y/N]:' % version)
          if answer != 'y':
            print('Aborting dev release for %s' % version)
            sys.exit(1)

        maybe_check_call(args, [
          'git', 'push', 'origin', 'HEAD:%s' % R8_DEV_BRANCH])
        maybe_tag(args, version)

        return "%s dev version %s from hash %s" % (
          'DryRun: omitted publish of' if args.dry_run else 'Published',
          version,
          commithash)

  return make_release


def maybe_tag(args, version):
  maybe_check_call(args, [
    'git', 'tag', '-a', version, '-m', '"%s"' % version])
  maybe_check_call(args, [
    'git', 'push', 'origin', 'refs/tags/%s' % version])


def version_change_diff(diff, old_version, new_version):
  invalid_line = None
  for line in str(diff).splitlines():
    if line.startswith('-  ') and \
        line != '-  public static final String LABEL = "%s";' % old_version:
      invalid_line = line
    elif line.startswith('+  ') and \
        line != '+  public static final String LABEL = "%s";' % new_version:
      invalid_line = line
  return invalid_line


def validate_version_change_diff(version_diff_output, old_version, new_version):
  invalid = version_change_diff(version_diff_output, old_version, new_version)
  if invalid:
    print("Unexpected diff:")
    print("=" * 80)
    print(version_diff_output)
    print("=" * 80)
    accept_string = 'THE DIFF IS OK!'
    answer = input(
      "Accept the additonal diff as part of the release? "
      "Type '%s' to accept: " % accept_string)
    if answer != accept_string:
      print("You did not type '%s'" % accept_string)
      print('Aborting dev release for %s' % version)
      sys.exit(1)


def maybe_check_call(args, cmd):
  if args.dry_run:
    print('DryRun:', ' '.join(cmd))
  else:
    print(' '.join(cmd))
    return subprocess.check_call(cmd)


def update_prebuilds(r8_checkout, version, checkout):
  path = os.path.join(r8_checkout, 'tools', 'update_prebuilds_in_android.py')
  commit_arg = '--commit_hash=' if len(version) == 40 else '--version='
  subprocess.check_call([path, '--targets=lib', '--maps', commit_arg + version, checkout])


def release_studio_or_aosp(r8_checkout, path, options, git_message):
  with utils.ChangedWorkingDirectory(path):
    if not options.use_existing_work_branch:
      subprocess.call(['repo', 'abandon', 'update-r8'])
    if not options.no_sync:
      subprocess.check_call(['repo', 'sync', '-cq', '-j', '16'])

    prebuilts_r8 = os.path.join(path, 'prebuilts', 'r8')

    if not options.use_existing_work_branch:
      with utils.ChangedWorkingDirectory(prebuilts_r8):
        subprocess.check_call(['repo', 'start', 'update-r8'])

    update_prebuilds(r8_checkout, options.version, path)

    with utils.ChangedWorkingDirectory(prebuilts_r8):
      if not options.use_existing_work_branch:
        subprocess.check_call(['git', 'commit', '-a', '-m', git_message])
      else:
        print('Not committing when --use-existing-work-branch. '
            + 'Commit message should be:\n\n'
            + git_message
            + '\n')
      # Don't upload if requested not to, or if changes are not committed due
      # to --use-existing-work-branch
      if not options.no_upload and not options.use_existing_work_branch:
        process = subprocess.Popen(['repo', 'upload', '.', '--verify'],
                                   stdin=subprocess.PIPE)
        return process.communicate(input=b'y\n')[0]


def prepare_aosp(args):
  assert args.version
  assert os.path.exists(args.aosp), "Could not find AOSP path %s" % args.aosp

  def release_aosp(options):
    print("Releasing for AOSP")
    if options.dry_run:
      return 'DryRun: omitting AOSP release for %s' % options.version

    git_message = ("""Update D8 and R8 to %s

Version: %s
This build IS NOT suitable for preview or public release.

Built here: go/r8-releases/raw/%s

Test: TARGET_PRODUCT=aosp_arm64 m -j core-oj"""
                   % (args.version, args.version, args.version))
    return release_studio_or_aosp(
      utils.REPO_ROOT, args.aosp, options, git_message)

  return release_aosp


def prepare_maven(args):
  assert args.version

  def release_maven(options):
    gfile = '/bigstore/r8-releases/raw/%s/r8lib.zip' % args.version
    release_id = gmaven_publisher_stage(options, [gfile])

    print("Staged Release ID " + release_id + ".\n")
    gmaven_publisher_stage_redir_test_info(
        release_id, "com.android.tools:r8:%s" % args.version, "r8lib.jar")

    print
    answer = input("Continue with publishing [y/N]:")

    if answer != 'y':
      print('Aborting release to Google maven')
      sys.exit(1)

    gmaven_publisher_publish(args, release_id)

    print("")
    print("Published. Use the email workflow for approval.")

  return release_maven

# ------------------------------------------------------ column 70 --v
def git_message_dev(version, bugs):
  return """Update D8 R8 to %s

This is a development snapshot, it's fine to use for studio canary
build, but not for BETA or release, for those we would need a release
version of R8 binaries. This build IS suitable for preview release
but IS NOT suitable for public release.

Built here: go/r8-releases/raw/%s
Test: ./gradlew check
Bug: %s""" % (version, version, '\nBug: '.join(bugs))


def git_message_release(version, bugs):
  return """D8 R8 version %s

Built here: go/r8-releases/raw/%s/
Test: ./gradlew check

Bug: %s""" % (version, version, '\nBug: '.join(bugs))


def prepare_studio(args):
  assert args.version
  assert os.path.exists(args.studio), ("Could not find STUDIO path %s"
                                       % args.studio)

  def release_studio(options):
    print("Releasing for STUDIO")
    if options.dry_run:
      return 'DryRun: omitting studio release for %s' % options.version

    if 'dev' in options.version:
      git_message = git_message_dev(options.version, options.bug)
      r8_checkout = utils.REPO_ROOT
      return release_studio_or_aosp(
        r8_checkout, args.studio, options, git_message)
    else:
      with utils.TempDir() as temp:
        checkout_r8(temp, options.version[0:options.version.rindex('.')])
        git_message = git_message_release(options.version, options.bug)
        return release_studio_or_aosp(temp, args.studio, options, git_message)

  return release_studio


def g4_cp(old, new, file):
  subprocess.check_call('g4 cp {%s,%s}/%s' % (old, new, file), shell=True)


def g4_open(file):
  if not os.access(file, os.W_OK):
    subprocess.check_call('g4 open %s' % file, shell=True)


def g4_change(version):
  return subprocess.check_output(
      'g4 change --desc "Update R8 to version %s\n"' % (version),
      shell=True).decode('utf-8')

def get_cl_id(c4_change_output):
  startIndex = c4_change_output.find('Change ') + len('Change ')
  endIndex = c4_change_output.find(' ', startIndex)
  cl = c4_change_output[startIndex:endIndex]
  assert cl.isdigit()
  return cl

def sed(pattern, replace, path):
  with open(path, "r") as sources:
    lines = sources.readlines()
  with open(path, "w") as sources:
    for line in lines:
      sources.write(re.sub(pattern, replace, line))


def download_file(version, file, dst):
  urllib.request.urlretrieve(
      ('https://storage.googleapis.com/r8-releases/raw/%s/%s' % (version, file)),
      dst)

def download_gfile(gfile, dst):
  if not gfile.startswith('/bigstore/r8-releases'):
    print('Unexpected gfile prefix for %s' % gfile)
    sys.exit(1)

  urllib.request.urlretrieve(
      'https://storage.googleapis.com/%s' % gfile[len('/bigstore/'):],
      dst)

def blaze_run(target):
  return subprocess.check_output(
      'blaze run %s' % target, shell=True, stderr=subprocess.STDOUT).decode('utf-8')


def prepare_google3(args):
  assert args.version
  # Check if an existing client exists.
  if not args.use_existing_work_branch:
    check_no_google3_client(args, args.p4_client)

  def release_google3(options):
    print("Releasing for Google 3")
    if options.dry_run:
      return 'DryRun: omitting g3 release for %s' % options.version

    google3_base = subprocess.check_output(
        ['p4', 'g4d', '-f', args.p4_client]).decode('utf-8').rstrip()
    third_party_r8 = os.path.join(google3_base, 'third_party', 'java', 'r8')
    today = datetime.date.today()
    with utils.ChangedWorkingDirectory(third_party_r8):
      # download files
      g4_open('full.jar')
      g4_open('src.jar')
      g4_open('lib.jar')
      g4_open('lib.jar.map')
      g4_open('retrace_lib.jar')
      g4_open('desugar_jdk_libs_configuration.jar')
      download_file(options.version, 'r8-full-exclude-deps.jar', 'full.jar')
      download_file(options.version, 'r8-src.jar', 'src.jar')
      download_file(options.version, 'r8lib-exclude-deps.jar', 'lib.jar')
      download_file(
          options.version, 'r8lib-exclude-deps.jar.map', 'lib.jar.map')
      download_file(options.version, 'desugar_jdk_libs_configuration.jar',
                    'desugar_jdk_libs_configuration.jar')
      download_file(options.version, 'r8retrace-exclude-deps.jar', 'retrace_lib.jar')
      g4_open('METADATA')
      sed(r'[1-9]\.[0-9]{1,2}\.[0-9]{1,3}-dev',
          options.version,
          os.path.join(third_party_r8, 'METADATA'))
      sed(r'\{ year.*\}',
          ('{ year: %i month: %i day: %i }'
           % (today.year, today.month, today.day)),
          os.path.join(third_party_r8, 'METADATA'))


      subprocess.check_output('chmod u+w *', shell=True)

    with utils.ChangedWorkingDirectory(google3_base):
      blaze_result = blaze_run('//third_party/java/r8:d8 -- --version')

      assert options.version in blaze_result

      if not options.no_upload:
        change_result = g4_change(options.version)
        change_result += 'Run \'(g4d ' + args.p4_client \
                         + ' && tap_presubmit -p all --train -c ' \
                         + get_cl_id(change_result) + ')\' for running TAP global' \
                         + ' presubmit using the train.\n' \
                         + 'Run \'(g4d ' + args.p4_client \
                         + ' && tap_presubmit -p all --notrain --detach --email' \
                         + ' --skip_flaky_targets --skip_already_failing -c ' \
                         + get_cl_id(change_result) + ')\' for running an isolated' \
                         + ' TAP global presubmit.'
        return change_result

  return release_google3


def update_desugar_library_in_studio(args):
  assert os.path.exists(args.studio), ("Could not find STUDIO path %s"
                                       % args.studio)

  def make_release(args):
    library_version = args.update_desugar_library_in_studio[0]
    configuration_version = args.update_desugar_library_in_studio[1]
    change_name = 'update-desugar-library-dependencies'

    with utils.ChangedWorkingDirectory(args.studio):
      if not args.use_existing_work_branch:
        subprocess.call(['repo', 'abandon', change_name])
      if not args.no_sync:
        subprocess.check_call(['repo', 'sync', '-cq', '-j', '16'])

      cmd = ['tools/base/bazel/bazel',
         'run',
         '//tools/base/bazel:add_dependency',
         '--',
         '--repo=https://maven.google.com com.android.tools:desugar_jdk_libs:%s' % library_version]
      utils.PrintCmd(cmd)
      subprocess.check_call(" ".join(cmd), shell=True)
      cmd = ['tools/base/bazel/bazel', 'shutdown']
      utils.PrintCmd(cmd)
      subprocess.check_call(cmd)

    prebuilts_tools = os.path.join(args.studio, 'prebuilts', 'tools')
    with utils.ChangedWorkingDirectory(prebuilts_tools):
      if not args.use_existing_work_branch:
        with utils.ChangedWorkingDirectory(prebuilts_tools):
          subprocess.check_call(['repo', 'start', change_name])
      m2_dir = os.path.join(
        'common', 'm2', 'repository', 'com', 'android', 'tools')
      subprocess.check_call(
        ['git',
         'add',
         os.path.join(m2_dir, DESUGAR_JDK_LIBS, library_version)])
      subprocess.check_call(
        ['git',
         'add',
         os.path.join(
           m2_dir, DESUGAR_JDK_LIBS_CONFIGURATION, configuration_version)])

      git_message = ("""Update library desugaring dependencies

  com.android.tools:desugar_jdk_libs:%s
  com.android.tools:desugar_jdk_libs_configuration:%s

Bug: %s
Test: L8ToolTest, L8DexDesugarTest"""
                     % (library_version,
                        configuration_version,
                        '\nBug: '.join(args.bug)))

      if not args.use_existing_work_branch:
        subprocess.check_call(['git', 'commit', '-a', '-m', git_message])
      else:
        print('Not committing when --use-existing-work-branch. '
            + 'Commit message should be:\n\n'
            + git_message
            + '\n')
      # Don't upload if requested not to, or if changes are not committed due
      # to --use-existing-work-branch
      if not args.no_upload and not args.use_existing_work_branch:
        process = subprocess.Popen(['repo', 'upload', '.', '--verify'],
                                   stdin=subprocess.PIPE)
        return process.communicate(input='y\n')[0]

  return make_release


def prepare_desugar_library(args):

  def make_release(args):
    library_version = args.desugar_library[0]
    configuration_version = args.desugar_library[1]

    library_archive = DESUGAR_JDK_LIBS + '.zip'
    library_jar = DESUGAR_JDK_LIBS + '.jar'
    library_artifact_id = \
        '%s:%s:%s' % (ANDROID_TOOLS_PACKAGE, DESUGAR_JDK_LIBS, library_version)

    configuration_archive = DESUGAR_JDK_LIBS_CONFIGURATION + '.zip'

    with utils.TempDir() as temp:
      with utils.ChangedWorkingDirectory(temp):
        library_gfile = ('/bigstore/r8-releases/raw/%s/%s/%s'
              % (DESUGAR_JDK_LIBS, library_version, library_archive))
        configuration_gfile = ('/bigstore/r8-releases/raw/main/%s/%s'
              % (configuration_version, configuration_archive))

        download_gfile(library_gfile, library_archive)
        download_gfile(configuration_gfile, configuration_archive)
        check_configuration(configuration_archive)

        release_id = gmaven_publisher_stage(
            args, [library_gfile, configuration_gfile])

        print("Staged Release ID " + release_id + ".\n")
        gmaven_publisher_stage_redir_test_info(
            release_id,
            "com.android.tools:%s:%s" % (DESUGAR_JDK_LIBS, library_version),
            library_jar)

        print("")
        answer = input("Continue with publishing [y/N]:")

        if answer != 'y':
          print('Aborting release to Google maven')
          sys.exit(1)

        gmaven_publisher_publish(args, release_id)

        print("")
        print("Published. Use the email workflow for approval.")

  return make_release


def check_configuration(configuration_archive):
  zip = zipfile.ZipFile(configuration_archive)
  zip.extractall()
  dirs = os.listdir(
    os.path.join('com', 'android', 'tools', DESUGAR_JDK_LIBS_CONFIGURATION))
  if len(dirs) != 1:
    print('Unexpected archive content, %s' + dirs)
    sys.exit(1)

  version = dirs[0]
  pom_file = os.path.join(
    'com',
    'android',
    'tools',
    DESUGAR_JDK_LIBS_CONFIGURATION,
    version,
    '%s-%s.pom' % (DESUGAR_JDK_LIBS_CONFIGURATION, version))
  version_from_pom = extract_version_from_pom(pom_file)
  if version != version_from_pom:
    print('Version mismatch, %s != %s' % (version, version_from_pom))
    sys.exit(1)

def check_no_google3_client(args, client_name):
  if not args.use_existing_work_branch:
    clients = subprocess.check_output('g4 myclients', shell=True).decode('utf-8')
    if ':%s:' % client_name in clients:
      print(("Remove the existing '%s' client before continuing " +
             "(force delete: 'g4 citc -d -f %s'), " +
             "or use option --use-existing-work-branch.") % (client_name, client_name))
      sys.exit(1)


def extract_version_from_pom(pom_file):
    ns = "http://maven.apache.org/POM/4.0.0"
    xml.etree.ElementTree.register_namespace('', ns)
    tree = xml.etree.ElementTree.ElementTree()
    tree.parse(pom_file)
    return tree.getroot().find("{%s}version" % ns).text


GMAVEN_PUBLISH_STAGE_RELEASE_ID_PATTERN = re.compile('Release ID = ([0-9a-f\-]+)')


def gmaven_publisher_stage(args, gfiles):
  if args.dry_run:
    print('Dry-run, would have staged %s' % gfiles)
    return 'dry-run-release-id'

  print("Staging: %s" % ', '.join(gfiles))
  print("")

  cmd = [GMAVEN_PUBLISHER, 'stage', '--gfile', ','.join(gfiles)]
  output = subprocess.check_output(cmd)

  # Expect output to contain:
  # [INFO] 06/19/2020 09:35:12 CEST: >>>>>>>>>> Staged
  # [INFO] 06/19/2020 09:35:12 CEST: Release ID = 9171d015-18f6-4a90-9984-1c362589dc1b
  # [INFO] 06/19/2020 09:35:12 CEST: Stage Path = /bigstore/studio_staging/maven2/sgjesse/9171d015-18f6-4a90-9984-1c362589dc1b

  matches = GMAVEN_PUBLISH_STAGE_RELEASE_ID_PATTERN.findall(output.decode("utf-8"))
  if matches == None or len(matches) > 1:
    print("Could not determine the release ID from the gmaven_publisher " +
          "output. Expected a line with 'Release ID = <release id>'.")
    print("Output was:")
    print(output)
    sys.exit(1)

  print(output)

  release_id = matches[0]
  return release_id


def gmaven_publisher_stage_redir_test_info(release_id, artifact, dst):

  redir_command = ("/google/data/ro/teams/android-devtools-infra/tools/redir "
                 + "--alsologtostderr "
                 + "--gcs_bucket_path=/studio_staging/maven2/${USER}/%s "
                 + "--port=1480") % release_id

  get_command = ("mvn org.apache.maven.plugins:maven-dependency-plugin:2.4:get "
                + "-Dmaven.repo.local=/tmp/maven_repo_local "
                + "-DremoteRepositories=http://localhost:1480 "
                + "-Dartifact=%s "
                + "-Ddest=%s") % (artifact, dst)

  print("""To test the staged content with 'redir' run:

%s

Add the following repository to gradle.build for using 'redir':

repositories {
  maven {
    url 'http://localhost:1480'
  }
}

Use this commands to get artifact from 'redir':

rm -rf /tmp/maven_repo_local
%s
""" % (redir_command, get_command))


def gmaven_publisher_publish(args, release_id):
  if args.dry_run:
    print('Dry-run, would have published %s' % release_id)
    return

  cmd = [GMAVEN_PUBLISHER, 'publish', release_id]
  output = subprocess.check_output(cmd)

def branch_change_diff(diff, old_version, new_version):
  invalid_line = None
  for line in str(diff).splitlines():
    if line.startswith('-R8') and \
        line != "-R8_DEV_BRANCH = '%s'" % old_version:
      print(line)
      invalid_line = line
    elif line.startswith('+R8') and \
        line != "+R8_DEV_BRANCH = '%s'" % new_version:
      print(line)
      invalid_line = line
  return invalid_line


def validate_branch_change_diff(version_diff_output, old_version, new_version):
  invalid = branch_change_diff(version_diff_output, old_version, new_version)
  if invalid:
    print("")
    print("The diff for the branch change in tools/release.py is not as expected:")
    print("")
    print("=" * 80)
    print(version_diff_output)
    print("=" * 80)
    print("")
    print("Validate the uploaded CL before landing.")
    print("")


def prepare_branch(args):
  branch_version = args.new_dev_branch[0]
  commithash = args.new_dev_branch[1]

  current_semver = utils.check_basic_semver_version(
    R8_DEV_BRANCH, ", current release branch version should be x.y", 2)
  semver = utils.check_basic_semver_version(
    branch_version, ", release branch version should be x.y", 2)
  if not semver.larger_than(current_semver):
    print('New branch version "'
      + branch_version
      + '" must be strictly larger than the current "'
      + R8_DEV_BRANCH
      + '"')
    sys.exit(1)

  def make_branch(options):
    with utils.TempDir() as temp:
      subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
      with utils.ChangedWorkingDirectory(temp):
        subprocess.check_call(['git', 'branch', branch_version, commithash])

        subprocess.check_call(['git', 'checkout', branch_version])

        # Rewrite the version, commit and validate.
        old_version = 'main'
        full_version = branch_version + '.0-dev'
        version_prefix = 'LABEL = "'
        sed(version_prefix + old_version,
          version_prefix + full_version,
          R8_VERSION_FILE)

        subprocess.check_call([
          'git', 'commit', '-a', '-m', 'Version %s' % full_version])

        version_diff_output = subprocess.check_output([
          'git', 'diff', '%s..HEAD' % commithash])

        validate_version_change_diff(version_diff_output, old_version, full_version)

        # Double check that we want to create a new release branch.
        if not options.dry_run:
          answer = input('Create new branch for %s [y/N]:' % branch_version)
          if answer != 'y':
            print('Aborting new branch for %s' % branch_version)
            sys.exit(1)

        maybe_check_call(options, [
          'git', 'push', 'origin', 'HEAD:%s' % branch_version])
        maybe_tag(options, full_version)

        print('Updating tools/r8_release.py to make new dev releases on %s'
          % branch_version)

        subprocess.check_call(['git', 'new-branch', 'update-release-script'])

        # Check this file for the setting of the current dev branch.
        result = None
        for line in open(THIS_FILE_RELATIVE, 'r'):
          result = re.match(
              r"^R8_DEV_BRANCH = '(\d+).(\d+)'", line)
          if result:
            break
        if not result or not result.group(1):
          print('Failed to find version label in %s' % THIS_FILE_RELATIVE)
          sys.exit(1)

        # Update this file with the new dev branch.
        sed("R8_DEV_BRANCH = '%s.%s" % (result.group(1), result.group(2)),
          "R8_DEV_BRANCH = '%s.%s" % (str(semver.major), str(semver.minor)),
          THIS_FILE_RELATIVE)

        message = \
            'Prepare %s for branch %s' % (THIS_FILE_RELATIVE, branch_version)
        subprocess.check_call(['git', 'commit', '-a', '-m', message])

        branch_diff_output = subprocess.check_output(['git', 'diff', 'HEAD~'])

        validate_branch_change_diff(
          branch_diff_output, R8_DEV_BRANCH, branch_version)

        maybe_check_call(options, ['git', 'cl', 'upload', '-f', '-m', message])

        print('')
        print('Make sure to send out the branch change CL for review.')
        print('')

  return make_branch


def parse_options():
  result = argparse.ArgumentParser(description='Release r8')
  group = result.add_mutually_exclusive_group()
  group.add_argument('--dev-release',
                      metavar=('<main hash>'),
                      help='The hash to use for the new dev version of R8')
  group.add_argument('--version',
                      metavar=('<version>'),
                      help='The new version of R8 (e.g., 1.4.51) to release to selected channels')
  group.add_argument('--desugar-library',
                      nargs=2,
                      metavar=('<version>', '<configuration hash>'),
                      help='The new version of com.android.tools:desugar_jdk_libs')
  group.add_argument('--update-desugar-library-in-studio',
                      nargs=2,
                      metavar=('<version>', '<configuration version>'),
                      help='Update studio mirror of com.android.tools:desugar_jdk_libs')
  group.add_argument('--new-dev-branch',
                      nargs=2,
                      metavar=('<version>', '<main hash>'),
                      help='Create a new branch starting a version line (e.g. 2.0)')
  result.add_argument('--dev-pre-cherry-pick',
                      metavar=('<main hash(s)>'),
                      default=[],
                      action='append',
                      help='List of commits to cherry pick before doing full '
                           'merge, mostly used for reverting cherry picks')
  result.add_argument('--no-sync', '--no_sync',
                      default=False,
                      action='store_true',
                      help='Do not sync repos before uploading')
  result.add_argument('--bug',
                      metavar=('<bug(s)>'),
                      default=[],
                      action='append',
                      help='List of bugs for release version')
  result.add_argument('--studio',
                      metavar=('<path>'),
                      help='Release for studio by setting the path to a studio '
                           'checkout')
  result.add_argument('--aosp',
                      metavar=('<path>'),
                      help='Release for aosp by setting the path to the '
                           'checkout')
  result.add_argument('--maven',
                      default=False,
                      action='store_true',
                      help='Release to Google Maven')
  result.add_argument('--google3',
                      default=False,
                      action='store_true',
                      help='Release for google 3')
  result.add_argument('--p4-client',
                      default='update-r8',
                      metavar=('<client name>'),
                      help='P4 client name for google 3')
  result.add_argument('--use-existing-work-branch', '--use_existing_work_branch',
                      default=False,
                      action='store_true',
                      help='Use existing work branch/CL in aosp/studio/google3')
  result.add_argument('--no-upload', '--no_upload',
                      default=False,
                      action='store_true',
                      help="Don't upload for code review")
  result.add_argument('--dry-run',
                      default=False,
                      action='store_true',
                      help='Only perform non-commiting tasks and print others.')
  result.add_argument('--dry-run-output', '--dry_run_output',
                      default=os.getcwd(),
                      metavar=('<path>'),
                      help='Location for dry run output.')
  args = result.parse_args()
  if (args.studio
      and args.version
      and not 'dev' in args.version
      and args.bug == []):
    print("When releasing a release version to Android Studio add the "
           + "list of bugs by using '--bug'")
    sys.exit(1)

  if args.version and not 'dev' in args.version and args.google3:
    print("You should not roll a release version into google 3")
    sys.exit(1)

  return args


def main():
  args = parse_options()
  targets_to_run = []

  if args.new_dev_branch:
    if args.google3 or args.studio or args.aosp:
      print('Cannot create a branch and roll at the same time.')
      sys.exit(1)
    targets_to_run.append(prepare_branch(args))

  if args.dev_release:
    if args.google3 or args.studio or args.aosp:
      print('Cannot create a dev release and roll at the same time.')
      sys.exit(1)
    targets_to_run.append(prepare_release(args))

  if (args.google3
      or args.maven
      or (args.studio and not args.no_sync)
      or (args.desugar_library and not args.dry_run)):
    utils.check_gcert()

  if args.google3:
    targets_to_run.append(prepare_google3(args))
  if args.studio and not args.update_desugar_library_in_studio:
    targets_to_run.append(prepare_studio(args))
  if args.aosp:
    targets_to_run.append(prepare_aosp(args))
  if args.maven:
    targets_to_run.append(prepare_maven(args))

  if args.desugar_library:
    targets_to_run.append(prepare_desugar_library(args))

  if args.update_desugar_library_in_studio:
    if not args.studio:
      print("--studio required")
      sys.exit(1)
    if args.bug == []:
      print("Update studio mirror of com.android.tools:desugar_jdk_libs "
             + "requires at least one bug by using '--bug'")
      sys.exit(1)
    targets_to_run.append(update_desugar_library_in_studio(args))

  final_results = []
  for target_closure in targets_to_run:
    final_results.append(target_closure(args))

  print('\n\n**************************************************************')
  print('PRINTING SUMMARY')
  print('**************************************************************\n\n')

  for result in final_results:
    if result is not None:
      print(result)


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