| #!/usr/bin/env python | 
 | # 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. | 
 |  | 
 | # This script is designed to run on a buildbot to build from the source | 
 | # of https://github.com/google/desugar_jdk_libs and publish to the | 
 | # r8-release Cloud Storage Bucket. | 
 | # | 
 | # These files are uploaded: | 
 | # | 
 | #   raw/desugar_jdk_libs/<VERSION>/desugar_jdk_libs.jar | 
 | #   raw/desugar_jdk_libs/<VERSION>/desugar_jdk_libs.zip | 
 | #   raw/com/android/tools/desugar_jdk_libs/<VERSION>/desugar_jdk_libs-<VERSION>.jar | 
 | # | 
 | # The first two are the raw jar file and the maven compatible zip file. The | 
 | # third is the raw jar file placed and named so that the URL | 
 | # http://storage.googleapis.com/r8-releases/raw can be treated as a maven | 
 | # repository to fetch the artifact com.android.tools:desugar_jdk_libs:1.0.0 | 
 |  | 
 | import archive | 
 | import defines | 
 | import git_utils | 
 | import optparse | 
 | import os | 
 | import re | 
 | import shutil | 
 | import subprocess | 
 | import sys | 
 | import utils | 
 | import zipfile | 
 |  | 
 | if defines.IsLinux(): | 
 |   JDK8_JAVAC = os.path.join( | 
 |       defines.THIRD_PARTY, 'openjdk', 'jdk8', 'linux-x86', 'bin', 'javac') | 
 | elif defines.IsOsX(): | 
 |   JDK8_JAVAC = os.path.join( | 
 |       defines.THIRD_PARTY, 'openjdk', 'jdk8', 'darwin-x86', 'bin', 'javac') | 
 | elif defines.IsWindows(): | 
 |   raise Exception('Cannot compile using JDK8 on Windows hence cannot archive.') | 
 |  | 
 | CONVERSION_FOLDER = os.path.join( | 
 |     defines.REPO_ROOT, 'src', 'test', 'desugaredLibraryConversions') | 
 |  | 
 | VERSION_FILE = 'VERSION.txt' | 
 | LIBRARY_NAME = 'desugar_jdk_libs' | 
 |  | 
 | def ParseOptions(argv): | 
 |   result = optparse.OptionParser() | 
 |   result.add_option('--dry-run', '--dry_run', | 
 |       help='Running on bot, use third_party dependency.', | 
 |       default=False, | 
 |       action='store_true') | 
 |   result.add_option('--dry-run-output', '--dry_run_output', | 
 |       help='Output directory for dry run.', | 
 |       type="string", action="store") | 
 |   result.add_option('--github-account', '--github_account', | 
 |       help='GitHub account to clone from.', | 
 |       default="google", | 
 |       type="string", action="store") | 
 |   (options, args) = result.parse_args(argv) | 
 |   return (options, args) | 
 |  | 
 |  | 
 | def GetVersion(): | 
 |   with open(VERSION_FILE, 'r') as version_file: | 
 |     lines = version_file.readlines() | 
 |     if len(lines) != 1: | 
 |       raise Exception('Version file ' | 
 |           + VERSION_FILE + ' is expected to have exactly one line') | 
 |     version = lines[0].strip() | 
 |     if (version == '1.0.1'): | 
 |       raise Exception('Version file ' + VERSION_FILE + 'cannot have version 1.0.1') | 
 |     if (version == '1.0.0'): | 
 |       version = '1.0.1' | 
 |     utils.check_basic_semver_version( | 
 |         version, 'in version file ' + VERSION_FILE) | 
 |     return version | 
 |  | 
 |  | 
 | def Upload(options, file_name, storage_path, destination, is_master): | 
 |   print('Uploading %s to %s' % (file_name, destination)) | 
 |   if options.dry_run: | 
 |     if options.dry_run_output: | 
 |       dry_run_destination = \ | 
 |           os.path.join(options.dry_run_output, os.path.basename(file_name)) | 
 |       print('Dry run, not actually uploading. Copying to ' | 
 |         + dry_run_destination) | 
 |       shutil.copyfile(file_name, dry_run_destination) | 
 |     else: | 
 |       print('Dry run, not actually uploading') | 
 |   else: | 
 |     utils.upload_file_to_cloud_storage(file_name, destination) | 
 |     print('File available at: %s' % | 
 |         destination.replace('gs://', 'http://storage.googleapis.com/', 1)) | 
 |  | 
 | def GetFilesInFolder(folder): | 
 |   resulting_files = [] | 
 |   for root, dirs, files in os.walk(folder): | 
 |     for name in files: | 
 |       resulting_files.append(os.path.join(root, name)) | 
 |   assert len(resulting_files) > 0 | 
 |   return resulting_files | 
 |  | 
 | def Main(argv): | 
 |   (options, args) = ParseOptions(argv) | 
 |   if (len(args) > 0): | 
 |     raise Exception('Unsupported arguments') | 
 |   if not utils.is_bot() and not options.dry_run: | 
 |     raise Exception('You are not a bot, don\'t archive builds. ' | 
 |         + 'Use --dry-run to test locally') | 
 |   if (options.dry_run_output and | 
 |       (not os.path.exists(options.dry_run_output) or | 
 |        not os.path.isdir(options.dry_run_output))): | 
 |     raise Exception(options.dry_run_output | 
 |         + ' does not exist or is not a directory') | 
 |  | 
 |   if utils.is_bot(): | 
 |     archive.SetRLimitToMax() | 
 |  | 
 |   # Make sure bazel is extracted in third_party. | 
 |   utils.DownloadFromGoogleCloudStorage(utils.BAZEL_SHA_FILE) | 
 |   utils.DownloadFromGoogleCloudStorage(utils.JAVA8_SHA_FILE) | 
 |  | 
 |   # Only handling versioned desugar_jdk_libs. | 
 |   is_master = False | 
 |  | 
 |   with utils.TempDir() as checkout_dir: | 
 |     git_utils.GitClone( | 
 |       'https://github.com/' | 
 |           + options.github_account + '/' + LIBRARY_NAME, checkout_dir) | 
 |     with utils.ChangedWorkingDirectory(checkout_dir): | 
 |       version = GetVersion() | 
 |  | 
 |       destination = archive.GetVersionDestination( | 
 |           'gs://', LIBRARY_NAME + '/' + version, is_master) | 
 |       if utils.cloud_storage_exists(destination) and not options.dry_run: | 
 |         raise Exception( | 
 |             'Target archive directory %s already exists' % destination) | 
 |  | 
 |       bazel = os.path.join(utils.BAZEL_TOOL, 'lib', 'bazel', 'bin', 'bazel') | 
 |       cmd = [bazel, 'build', '--host_force_python=PY2', 'maven_release'] | 
 |       utils.PrintCmd(cmd) | 
 |       subprocess.check_call(cmd) | 
 |       cmd = [bazel, 'shutdown'] | 
 |       utils.PrintCmd(cmd) | 
 |       subprocess.check_call(cmd) | 
 |  | 
 |       # Compile the stubs for conversion files compilation. | 
 |       stub_compiled_folder = os.path.join(checkout_dir, 'stubs') | 
 |       os.mkdir(stub_compiled_folder) | 
 |       all_stubs = GetFilesInFolder(os.path.join(CONVERSION_FOLDER, 'stubs')) | 
 |       cmd = [JDK8_JAVAC, '-d', stub_compiled_folder] + all_stubs | 
 |       utils.PrintCmd(cmd) | 
 |       subprocess.check_call(cmd) | 
 |  | 
 |       # Compile the conversion files. | 
 |       conversions_compiled_folder = os.path.join(checkout_dir, 'conversions') | 
 |       os.mkdir(conversions_compiled_folder) | 
 |       all_conversions = GetFilesInFolder( | 
 |           os.path.join(CONVERSION_FOLDER, 'conversions')) | 
 |       cmd = [JDK8_JAVAC, '-cp', stub_compiled_folder, '-d', | 
 |              conversions_compiled_folder] + all_conversions | 
 |       utils.PrintCmd(cmd) | 
 |       subprocess.check_call(cmd) | 
 |  | 
 |       # Locate the library jar and the maven zip with the jar from the | 
 |       # bazel build. | 
 |       library_jar = os.path.join( | 
 |           'bazel-bin', 'src', 'share', 'classes', 'java', 'libjava.jar') | 
 |       maven_zip = os.path.join('bazel-bin', LIBRARY_NAME +'.zip') | 
 |  | 
 |       # Make a writable copy of the jar. | 
 |       jar_folder = os.path.join(checkout_dir, 'jar') | 
 |       os.mkdir(jar_folder) | 
 |       shutil.copy(library_jar, jar_folder) | 
 |       library_jar = os.path.join(jar_folder,'libjava.jar') | 
 |       os.chmod(library_jar, 0o777) | 
 |  | 
 |       # Add conversion classes into the jar. | 
 |       all_compiled_conversions = GetFilesInFolder(conversions_compiled_folder) | 
 |       with zipfile.ZipFile(library_jar, mode='a', allowZip64=True) as jar: | 
 |         for clazz in all_compiled_conversions: | 
 |           jar.write(clazz,arcname=os.path.relpath( | 
 |               clazz, | 
 |               conversions_compiled_folder), | 
 |               compress_type = zipfile.ZIP_DEFLATED) | 
 |  | 
 |       storage_path = LIBRARY_NAME + '/' + version | 
 |       # Upload the jar file with the library. | 
 |       destination = archive.GetUploadDestination( | 
 |           storage_path, LIBRARY_NAME + '.jar', is_master) | 
 |       Upload(options, library_jar, storage_path, destination, is_master) | 
 |  | 
 |       # Upload the maven zip file with the library. | 
 |       destination = archive.GetUploadDestination( | 
 |           storage_path, LIBRARY_NAME + '.zip', is_master) | 
 |       Upload(options, maven_zip, storage_path, destination, is_master) | 
 |  | 
 |       # Upload the jar file for accessing GCS as a maven repro. | 
 |       maven_destination = archive.GetUploadDestination( | 
 |           utils.get_maven_path('desugar_jdk_libs', version), | 
 |           'desugar_jdk_libs-%s.jar' % version, | 
 |           is_master) | 
 |       if options.dry_run: | 
 |         print('Dry run, not actually creating maven repo') | 
 |       else: | 
 |         utils.upload_file_to_cloud_storage(library_jar, maven_destination) | 
 |         print('Maven repo root available at: %s' % archive.GetMavenUrl(is_master)) | 
 |  | 
 |  | 
 | if __name__ == '__main__': | 
 |   sys.exit(Main(sys.argv[1:])) |