| #!/usr/bin/env python3 |
| # Copyright (c) 2021, 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 utils |
| from html.parser import HTMLParser |
| import urllib.request |
| import os |
| import subprocess |
| import sys |
| import xml.etree.ElementTree |
| |
| |
| JETBRAINS_KOTLIN_STABLE_URL = "https://github.com/JetBrains/kotlin/releases/download" |
| JETBRAINS_KOTLIN_MAVEN_URL = "https://maven.pkg.jetbrains.space/kotlin/p/" \ |
| "kotlin/bootstrap/org/jetbrains/kotlin/" |
| KOTLIN_RELEASE_URL = JETBRAINS_KOTLIN_MAVEN_URL + "kotlin-compiler/" |
| KOTLINC_LIB = os.path.join(utils.THIRD_PARTY, "kotlin", |
| "kotlin-compiler-dev", "kotlinc", "lib") |
| |
| def ParseOptions(args): |
| parser = argparse.ArgumentParser(description='Update third_party Kotlin') |
| parser.add_argument( |
| '--version', |
| required=True, |
| help="The Kotlin version, use 'dev' for the latest dev compiler") |
| return parser.parse_args() |
| |
| def download_stable(version): |
| with utils.TempDir() as temp: |
| unzip_dir = os.path.join( |
| utils.THIRD_PARTY, |
| 'kotlin', |
| 'kotlin-compiler-{version}'.format(version=version)) |
| if os.path.exists(unzip_dir): |
| print('Destination dir {dir} exists. Please remove and retry.'.format(dir=unzip_dir)) |
| sys.exit(-1) |
| url = ( |
| '{download_url_base}/v{version}/kotlin-compiler-{version}.zip' |
| .format(download_url_base=JETBRAINS_KOTLIN_STABLE_URL, version=version)) |
| kotlin_compiler_download_zip = os.path.join(temp, 'kotlin-compiler.zip') |
| download_and_save(url, kotlin_compiler_download_zip) |
| cmd = ['unzip', '-q', kotlin_compiler_download_zip, '-d', unzip_dir] |
| subprocess.check_call(cmd) |
| with open(os.path.join(unzip_dir, 'README.google'), 'w') as readme: |
| readme.write('Name: Kotlin\n') |
| readme.write('URL: {url}\n'.format(url=url)) |
| readme.write('Version: {version}\n'.format(version=version)) |
| readme.write('Revision: NA\n') |
| readme.write('License: Apache License Version 2.0\n') |
| print('If you want to upload this run:') |
| print(' (cd {dir}; upload_to_google_storage.py -a --bucket r8-deps {file})' |
| .format(dir=os.path.dirname(unzip_dir), file=os.path.basename(unzip_dir))) |
| |
| |
| |
| |
| |
| def download_newest(): |
| response = url_request.urlopen(KOTLIN_RELEASE_URL) |
| if response.getcode() != 200: |
| raise Exception('Url: %s \n returned %s' % |
| (KOTLIN_RELEASE_URL, response.getcode())) |
| content = str(response.read()) |
| release_candidates = [] |
| |
| class HTMLContentParser(HTMLParser): |
| |
| def handle_data(self, data): |
| if ('-dev-' in data): |
| release_candidates.append(data) |
| |
| parser = HTMLContentParser() |
| parser.feed(content) |
| |
| top_most_version = (0, 0, 0, 0) |
| top_most_version_and_build = None |
| |
| for version in release_candidates: |
| # The compiler version is on the form <major>.<minor>.<revision>-dev-<build>/ |
| version = version.replace('/', '') |
| version_build_args = version.split('-') |
| version_components = version_build_args[0].split('.') |
| version_components.append(version_build_args[2]) |
| current_version = tuple(map(int, version_components)) |
| if (current_version > top_most_version): |
| top_most_version = current_version |
| top_most_version_and_build = version |
| |
| if (top_most_version_and_build is None): |
| raise Exception('Url: %s \n returned %s' % |
| (KOTLIN_RELEASE_URL, response.getcode())) |
| |
| # Download checked in kotlin dev compiler before owerlaying with the new. |
| # TODO(sgjesse): This should just ensure an empty directory instead of |
| # relying on overlaying and reusing some jars. |
| utils.DownloadFromGoogleCloudStorage( |
| os.path.join(utils.THIRD_PARTY, "kotlin", |
| "kotlin-compiler-dev.tar.gz.sha1")) |
| |
| # Check POM for expected dependencies. |
| check_pom(top_most_version_and_build) |
| |
| # We can now download all files related to the kotlin compiler version. |
| print("Downloading version: " + top_most_version_and_build) |
| |
| download_and_save( |
| JETBRAINS_KOTLIN_MAVEN_URL + |
| "kotlin-compiler/{0}/kotlin-compiler-{0}.jar".format( |
| top_most_version_and_build), KOTLINC_LIB, "kotlin-compiler.jar") |
| download_and_save( |
| JETBRAINS_KOTLIN_MAVEN_URL + |
| "kotlin-stdlib/{0}/kotlin-stdlib-{0}.jar".format( |
| top_most_version_and_build), KOTLINC_LIB, "kotlin-stdlib.jar") |
| download_and_save( |
| JETBRAINS_KOTLIN_MAVEN_URL + |
| "kotlin-stdlib-jdk8/{0}/kotlin-stdlib-jdk8-{0}.jar".format( |
| top_most_version_and_build), KOTLINC_LIB, "kotlin-stdlib-jdk8.jar") |
| # POM file has dependency on version 1.6.10 - download latest anyway. |
| download_and_save( |
| JETBRAINS_KOTLIN_MAVEN_URL + |
| "kotlin-reflect/{0}/kotlin-reflect-{0}.jar".format( |
| top_most_version_and_build), KOTLINC_LIB, "kotlin-reflect.jar") |
| download_and_save( |
| JETBRAINS_KOTLIN_MAVEN_URL + |
| "kotlin-script-runtime/{0}/kotlin-script-runtime-{0}.jar".format( |
| top_most_version_and_build), KOTLINC_LIB, |
| "kotlin-script-runtime.jar") |
| download_and_save( |
| "https://repo1.maven.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.8.0/kotlinx-coroutines-core-jvm-1.8.0.jar", KOTLINC_LIB, "kotlinx-coroutines-core-jvm.jar") |
| download_and_save( |
| "https://repo1.maven.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar", KOTLINC_LIB, "trove4j.jar") |
| |
| |
| def check_pom(top_most_version_and_build): |
| # Download POM, and check the expected dependencies. |
| download_and_save( |
| JETBRAINS_KOTLIN_MAVEN_URL + |
| "kotlin-compiler/{0}/kotlin-compiler-{0}.pom".format( |
| top_most_version_and_build), KOTLINC_LIB, "kotlin-compiler.pom") |
| pom_file = os.path.join(KOTLINC_LIB, "kotlin-compiler.pom") |
| 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}dependencies" % ns).text |
| for dependency in tree.getroot().find("{%s}dependencies" % ns): |
| groupId = dependency.find("{%s}groupId" % ns).text |
| artifactId = dependency.find("{%s}artifactId" % ns).text |
| version = dependency.find("{%s}version" % ns).text |
| coordinates = ( |
| '{groupId}:{artifactId}:{version}' |
| .format(groupId=groupId, artifactId=artifactId, version=version)) |
| print('Dependecy: ' + coordinates) |
| expected_dependencies = set() |
| for artifactId in ("kotlin-stdlib", "kotlin-stdlib-jdk8", "kotlin-script-runtime"): |
| expected_dependencies.add( |
| 'org.jetbrains.kotlin:{artifactId}:{version}' |
| .format(artifactId=artifactId, version=top_most_version_and_build)) |
| expected_dependencies.add('org.jetbrains.kotlin:kotlin-reflect:1.6.10') |
| expected_dependencies.add('org.jetbrains.intellij.deps:trove4j:1.0.20200330') |
| expected_dependencies.add('org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0') |
| if not coordinates in expected_dependencies: |
| raise Exception('Unexpected dependency: ' + coordinates) |
| |
| |
| def download_and_save(url, path, name): |
| download_and_save(url, dest) |
| |
| |
| def download_and_save(url, dest): |
| print('Downloading: ' + url + ' to: ' + dest) |
| urllib.request.urlretrieve(url, dest) |
| |
| |
| def main(args): |
| options = ParseOptions(args) |
| print(options.version) |
| if options.version == 'dev': |
| download_newest() |
| else: |
| download_stable(options.version) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |