#!/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 shutil
import stat
import subprocess
import sys
import urllib.request
import xml.etree.ElementTree
import zipfile

import utils

R8_DEV_BRANCH = '8.11'
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 install_gerrit_change_id_hook(checkout_dir):
    with utils.ChangedWorkingDirectory(checkout_dir):
        # Fancy way of getting the string ".git".
        git_dir = subprocess.check_output(['git', 'rev-parse', '--git-dir'
                                          ]).decode('utf-8').strip()
        commit_msg_hooks = '%s/hooks/commit-msg' % git_dir
        if not os.path.exists(os.path.dirname(commit_msg_hooks)):
            os.mkdir(os.path.dirname(commit_msg_hooks))
        # Install commit hook to generate Gerrit 'Change-Id:'.
        urllib.request.urlretrieve(
            'https://gerrit-review.googlesource.com/tools/hooks/commit-msg',
            commit_msg_hooks)
        st = os.stat(commit_msg_hooks)
        os.chmod(commit_msg_hooks,
                 st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)


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'
        ])
    install_gerrit_change_id_hook(temp)
    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(r'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)

                cmd = ['git', 'cl', 'upload', '--no-squash', '--bypass-hooks']
                maybe_check_call(args, cmd)

                if args.dry_run:
                    input(
                        'DryRun: check %s for content of version %s [enter to continue]:'
                        % (temp, version))

                return "%s dev version %s from hash %s for review" % (
                    'DryRun: omitted upload of' if args.dry_run else 'Uploaded',
                    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, keepanno=False):
    path = os.path.join(r8_checkout, 'tools', 'update_prebuilds_in_android.py')
    commit_arg = '--commit_hash=' if len(version) == 40 else '--version='
    cmd = [path, '--targets=lib', '--maps', commit_arg + version, checkout]
    if keepanno:
        cmd.append("--keepanno")
    subprocess.check_call(cmd)


def prepare_maven(args):
    assert args.version

    def release_maven(options):
        gfiles = []
        for version in args.version:
            gfiles.append('/bigstore/r8-releases/raw/%s/r8lib.zip' % version)

        release_id = gmaven_publisher_stage(options, gfiles)

        print("Staged Release ID " + release_id + ".\n")
        gmaven_publisher_stage_redir_test_info(
            release_id, "com.android.tools:r8:%s" % args.version[0], "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


def bug_fmt(bug):
    return "b/%s" % bug


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, commit_info):
    message = f'Update R8 to {version}'
    if version == 'main':
        message = f'DO NOT SUBMIT: {message}'
    if commit_info:
        message += f'\n\n{commit_info}'
    message = message.replace("'", r"\'")
    return subprocess.check_output(
        f"g4 change --desc $'{message}\n'",
        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):
    if version == 'main':
        src = os.path.join(utils.LIBS, file)
        if os.path.exists(src):
            shutil.copyfile(src, dst)
        else:
            print(f"WARNING: no file found for {src}. Skipping.")
        return
    dir = 'raw' if len(version) != 40 else 'raw/main'
    urllib.request.urlretrieve(
        ('https://storage.googleapis.com/r8-releases/%s/%s/%s' %
         (dir, 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 find_r8_version_hash(branch, version):
    if not branch.startswith('origin/'):
        print('Expected branch to start with origin/')
        return 1
    output = subprocess.check_output([
        'git',
        'log',
        '--pretty=format:%H\t%s',
        '--grep',
        r'^Version [[:digit:]]\+.[[:digit:]]\+.[[:digit:]]\+\(\|-dev\)$',
        branch]).decode('utf-8')
    for l in output.split('\n'):
        (hash, subject) = l.split('\t')
        m = re.search('Version (.+)', subject)
        if not m:
            print('Unable to find a version for line: %s' % l)
            continue
        if (m.group(1) == version):
            return hash
    print(f'ERROR: Did not find commit for {version} on branch {branch}')


def find_2nd(string, substring):
    return string.find(substring, string.find(substring) + 1)


def branch_from_version(version):
    return version[0:find_2nd(version, '.')]


def prepare_google3(args):
    assert len(args.version) == 1

    # 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):
        assert len(options.version) == 1
        version = options.version[0]
        print("Releasing for Google 3")
        if options.dry_run:
            return 'DryRun: omitting g3 release for %s' % 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()
        commit_info = 'No info on changes merged.'
        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('desugar_jdk_libs_configuration.jar')
            g4_open('threading-module-blocking.jar')
            g4_open('threading-module-single-threaded.jar')
            download_file(version,
                          'r8-full-exclude-deps.jar',
                          'full.jar')
            download_file(version,
                          'r8-src.jar',
                          'src.jar')
            download_file(version,
                          'r8lib-exclude-deps.jar',
                          'lib.jar')
            download_file(version,
                          'r8lib-exclude-deps.jar.map',
                          'lib.jar.map')
            download_file(version,
                          'desugar_jdk_libs_configuration.jar',
                          'desugar_jdk_libs_configuration.jar')
            download_file(version,
                          'threading-module-blocking.jar',
                          'threading-module-blocking.jar')
            download_file(version,
                          'threading-module-single-threaded.jar',
                          'threading-module-single-threaded.jar')
            if version != 'main':
                g4_open('METADATA')
                metadata_path = os.path.join(third_party_r8, 'METADATA')
                match_count = 0
                match_count_expected = 10
                match_value = None
                version_match_regexp = r'([1-9]\.[0-9]{1,2}\.[0-9]{1,3}-dev)'
                for line in open(metadata_path, 'r'):
                    result = re.search(version_match_regexp, line)
                    if result:
                        match_count = match_count + 1
                        if not match_value:
                            match_value = result.group(1)
                        else:
                            if match_value != result.group(1):
                                print(f"""ERROR:
                                Multiple -dev release strings ({match_value} and
                                {result.group(0)}) found in METADATA. Please update
                                {metadata_path} manually and run again with options
                                --google3 --use-existing-work-branch.
                                """)
                                sys.exit(1)
                if match_count != match_count_expected:
                    print(f"""ERROR:
                    Could not find the previous -dev release string to replace in METADATA.
                    Expected to find it mentioned {match_count_expected} times, but found
                    {match_count} occurrences. Please update {metadata_path} manually and
                    run again with options --google3 --use-existing-work-branch.
                    """)
                    sys.exit(1)
                sed(version_match_regexp, version, metadata_path)
                sed(r'\{ year.*\}',
                    f'{{ year: {today.year} month: {today.month} day: {today.day} }}',
                    metadata_path)
            subprocess.check_output('chmod u+w *', shell=True)
            previous_version = match_value
            if not version.endswith('-dev') or not previous_version.endswith('-dev'):
                print(f'ERROR: At least one of {version} (new version) '
                    + f'and {previous_version} (previous version) is not a -dev version. '
                    + 'Expected both to be.')
                sys.exit(1)
            print(f'Previous version was: {previous_version}')
            with utils.TempDir() as temp:
                subprocess.check_call(['git', 'clone', utils.REPO_SOURCE, temp])
                with utils.ChangedWorkingDirectory(temp):
                    current_version_hash = find_r8_version_hash(
                        'origin/' + branch_from_version(previous_version), previous_version)
                    new_version_hash = find_r8_version_hash(
                        'origin/' + branch_from_version(version), version)
                    if not current_version_hash or not new_version_hash:
                        print('ERROR: Failed to generate merged commits log, missing version')
                        sys.exit(1)
                    commits_merged = subprocess.check_output([
                        'git',
                        'log',
                        '--oneline',
                        f"{current_version_hash}..{new_version_hash}"]).decode('utf-8')
                    if len(commits_merged) == 0:
                        print('ERROR: Failed to generate merged commits log, commit log is empty')
                        sys.exit(1)
                    commit_info = (
                        f'Commits merged (since {previous_version}):\n'
                        + f'{commits_merged}\n'
                        + f'See https://r8.googlesource.com/r8/+log/{new_version_hash}')

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

            assert version in blaze_result

            if not options.no_upload:
                change_result = g4_change(version, commit_info)
                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(map(bug_fmt, 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]

        # TODO(b/237636871): Cleanup and generalize.
        if (not (library_version.startswith('1.1') or
                 library_version.startswith('1.2') or
                 library_version.startswith('2.0') or
                 library_version.startswith('2.1'))):
            print(
                "Release script does not support desugared library version %s" %
                library_version)
            sys.exit(1)

        postfixes = ['']
        if library_version.startswith('1.2'):
            postfixes = ['_legacy']
        if library_version.startswith('2.0') or library_version.startswith('2.1'):
            postfixes = ['_minimal', '', '_nio']

        with utils.TempDir() as temp:
            with utils.ChangedWorkingDirectory(temp):
                artifacts = []
                for postfix in postfixes:
                    group_postfix = ('' if postfix == '_legacy' else postfix)
                    archive_postfix = (postfix
                                       if library_version.startswith('1.1') else
                                       '_jdk11' + postfix)
                    library_jar = DESUGAR_JDK_LIBS + postfix + '.jar'
                    library_archive = DESUGAR_JDK_LIBS + archive_postfix + '.zip'
                    configuration_archive = DESUGAR_JDK_LIBS_CONFIGURATION + archive_postfix + '.zip'
                    library_gfile = ('/bigstore/r8-releases/raw/%s/%s/%s' %
                                     (DESUGAR_JDK_LIBS + group_postfix,
                                      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, group_postfix)
                    artifacts.append(library_gfile)
                    artifacts.append(configuration_gfile)

                release_id = gmaven_publisher_stage(args, artifacts)

                print("Staged Release ID " + release_id + ".\n")
                library_artifact_id = \
                    '%s:%s:%s' % (ANDROID_TOOLS_PACKAGE, DESUGAR_JDK_LIBS, library_version)
                gmaven_publisher_stage_redir_test_info(release_id,
                                                       library_artifact_id,
                                                       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, postfix):
    zip = zipfile.ZipFile(configuration_archive)
    zip.extractall()
    dirs = os.listdir(
        os.path.join('com', 'android', 'tools',
                     DESUGAR_JDK_LIBS_CONFIGURATION + postfix))
    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 + postfix,
        version,
        '%s-%s.pom' % (DESUGAR_JDK_LIBS_CONFIGURATION + postfix, 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:
            if args.delete_work_branch:
                subprocess.check_call('g4 citc -d -f %s' % client_name,
                                      shell=True)
            else:
                print(("Remove the existing '%s' client before continuing " +
                       "(force delete: 'g4 citc -d -f %s'), " +
                       "or use either --use-existing-work-branch or " +
                       "--delete-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(
    r'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=/bigstore/gmaven-staging/${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

Then add the following repository to settings.gradle.kts (Kotlin Script) to
search the 'redir' repository:

dependencyResolutionManagement {
  repositories {
    maven {
      url = uri("http://localhost:1480")
      isAllowInsecureProtocol = true
    }
  }
}

or the following to settings.gradle (Groovy);

dependencyResolutionManagement {
  repositories {
    maven {
      url 'http://localhost:1480'
      allowInsecureProtocol true
    }
  }
}

and add the following repository to gradle.build.kts (Kotlin Script) for the
staged version:

coreLibraryDesugaring("%s") {
  isChanging = true
}

or the following to settings.gradle (Groovy);

dependencies {
  coreLibraryDesugaring('%s') {
    changing = true
  }
}

Use this commands to get artifact from 'redir':

rm -rf /tmp/maven_repo_local
%s
""" % (redir_command, artifact, artifact, 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):
    if (len(args.new_dev_branch) < 1 or len(args.new_dev_branch) > 2):
        print("One or two arguments required for --new-dev-branch")
        sys.exit(1)
    branch_version = args.new_dev_branch[0]

    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):
                if len(options.new_dev_branch) == 1:
                    # Calculate the usual branch hash.
                    subprocess.check_call(['git',  'fetch', 'origin', R8_DEV_BRANCH])
                    hashes = subprocess.check_output(
                      ['git',
                      'show',
                      '-s',
                      '--pretty=%P',
                      'origin/%s~1' % R8_DEV_BRANCH]).decode('utf-8').strip()
                    if (len(hashes.split()) != 2):
                        print('Expected two parent hashes for commit origin/%s~1'
                            % R8_DEV_BRANCH)
                        sys.exit(0)
                    commithash = hashes.split()[1]
                    print()
                    print('Calculated branch hash: %s' % commithash)
                    print('Please double check that this is the correct branch hash. It'
                        ' is obtained as the second parent of origin/%s~1.' % R8_DEV_BRANCH)
                    print('If not rerun the script passing an explicit hash to branch from.')
                else:
                    commithash = options.new_dev_branch[1]
                    print()
                    print('Using explicit branch hash %s' % commithash)
                print()
                print('Use the Gerrit admin UI at'
                     ' https://r8-review.googlesource.com/admin/repos/r8,branches'
                     ' to create the %s branch from %s.' % (branch_version, commithash))
                answer = input("Branch created in Gerrit UI? [y/N]:")
                if answer != 'y':
                    print('Aborting preparing branch for %s' % branch_version)
                    sys.exit(1)

                # Fetch and checkout the new branch created through the Gerrit UI.
                subprocess.check_call(['git',  'fetch', 'origin', branch_version])
                subprocess.check_call(['git', 'checkout', branch_version])

                # Rewrite the version on the branch, commit and validate.
                old_version = 'main'
                full_version = branch_version + '.0-dev'
                version_prefix = 'public static final String 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)

                if options.dry_run:
                    input(
                        'DryRun: check %s for content of version %s [enter to continue]:'
                        % (temp, branch_version))

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

                maybe_check_call(
                    options,
                    ['git', 'cl', 'upload', '--bypass-hooks'])

                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)

                if options.dry_run:
                    input(
                        'DryRun: check %s for content of version main [enter to continue]:'
                        % temp)

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

                print('')
                print('Make sure to send out the two branch change CL for review'
                      ' (on %s and main).' % branch_version)
                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(s)>'),
        default=[],
        action='append',
        help=
        'The new version(s) 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='+',
        metavar=('<version>', '<branch hash>'),
        help=('Prepare new branch for a version line (e.g. 8.0)'
             ' Suggested branch hash is calculated '
             ' if not explicitly specified'))
    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('--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 CL in google3')
    result.add_argument('--delete-work-branch',
                        '--delete_work_branch',
                        default=False,
                        action='store_true',
                        help='Delete CL in 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.google3:
        if len(args.version) != 1:
            print("ERROR: only one version supported for google 3")
            sys.exit(1)
        if not 'dev' in args.version[0]:
            print("WARNING: You should not roll a release version into google 3")

    return args


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

    if args.new_dev_branch:
        if args.google3 or args.maven:
            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.maven:
            print('Cannot create a dev release and roll at the same time.')
            sys.exit(1)
        targets_to_run.append(prepare_release(args))

    utils.check_gcert()

    if args.google3:
        targets_to_run.append(prepare_google3(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())
