| #!/usr/bin/env python3 | |
| # Copyright (c) 2026, 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 os | |
| import shutil | |
| import sys | |
| import subprocess | |
| import tarfile | |
| import zipfile | |
| import utils | |
| # This script is a rewrite of scripts/add-openjdk.sh. | |
| # It is used to add a new OpenJDK version to third_party by: | |
| # 1. Cleaning up existing platform directories and archives. | |
| # 2. Extracting platform-specific JDK archives from ~/Downloads. | |
| # 3. Dereferencing symlinks and copying README.google into the platform directory. | |
| # 4. Uploading to Google Storage using upload_to_google_storage.py. | |
| # 5. Cleaning up temporary files and adding generated .sha1 files to git. | |
| def parse_options(): | |
| parser = argparse.ArgumentParser( | |
| description='Add a new OpenJDK version to third_party') | |
| parser.add_argument('--jdk-version', | |
| '--jdk_version', | |
| required=True, | |
| help='JDK version (e.g., 25)') | |
| parser.add_argument( | |
| '--jdk-version-full', | |
| '--jdk_version_full', | |
| help='Full JDK version name (e.g., 25-ea+33). Defaults to --jdk-version.' | |
| ) | |
| return parser.parse_args() | |
| def run_command(command, cwd=None): | |
| print('Running: %s' % ' '.join(command)) | |
| subprocess.check_call(command, cwd=cwd) | |
| def main(): | |
| args = parse_options() | |
| jdk_version = args.jdk_version | |
| jdk_version_full = args.jdk_version_full if args.jdk_version_full else jdk_version | |
| # The script expects to be run in third_party/openjdk/jdk-XX | |
| target_dir = os.path.join(utils.REPO_ROOT, 'third_party', 'openjdk', | |
| 'jdk-%s' % jdk_version) | |
| if not os.path.exists(target_dir): | |
| print('Error: Target directory does not exist: %s' % target_dir) | |
| print('Please create it first.') | |
| return 1 | |
| if not os.path.exists(os.path.join(target_dir, 'README.google')): | |
| print('Error: README.google not found in %s' % target_dir) | |
| print( | |
| 'Prepare README.google by copying from a previous JDK version and update it.' | |
| ) | |
| return 1 | |
| os.chdir(target_dir) | |
| downloads = os.path.expanduser('~/Downloads') | |
| platforms = [('linux', 'linux-x64_bin.tar.gz', 'jdk-%s' % jdk_version), | |
| ('osx', 'macos-aarch64_bin.tar.gz', | |
| 'jdk-%s.jdk' % jdk_version), | |
| ('windows', 'windows-x64_bin.zip', 'jdk-%s' % jdk_version)] | |
| # Check that all archives are present in ~/Downloads before processing | |
| missing_archives = [] | |
| for platform, suffix, extract_dir in platforms: | |
| archive_name = 'openjdk-%s_%s' % (jdk_version_full, suffix) | |
| archive_path = os.path.join(downloads, archive_name) | |
| if not os.path.exists(archive_path): | |
| missing_archives.append(archive_path) | |
| if missing_archives: | |
| print('Download OpenJDK for all required platforms') | |
| for path in missing_archives: | |
| print('Error: Archive not found: %s' % path) | |
| return 1 | |
| for platform, suffix, extract_dir in platforms: | |
| print('Processing %s...' % platform) | |
| # Clean up existing files and directories | |
| if os.path.exists(platform): | |
| shutil.rmtree(platform) | |
| for ext in ['', '.sha1']: | |
| filename = platform + '.tar.gz' + ext | |
| if os.path.exists(filename): | |
| os.remove(filename) | |
| # Extract | |
| archive_name = 'openjdk-%s_%s' % (jdk_version_full, suffix) | |
| archive_path = os.path.join(downloads, archive_name) | |
| print('Extracting %s' % archive_path) | |
| if archive_path.endswith('.tar.gz'): | |
| with tarfile.open(archive_path, 'r:gz') as tar: | |
| tar.extractall() | |
| elif archive_path.endswith('.zip'): | |
| with zipfile.ZipFile(archive_path, 'r') as zip_ref: | |
| zip_ref.extractall() | |
| if not os.path.exists(extract_dir): | |
| print('Error: Extraction did not create expected directory: %s' % | |
| extract_dir) | |
| return 1 | |
| # Move and prepare | |
| # Use copytree(symlinks=False) to dereference symlinks (mimics cp -rL) | |
| shutil.copytree(extract_dir, platform, symlinks=False) | |
| shutil.copy('README.google', platform) | |
| # Upload | |
| run_command([ | |
| 'upload_to_google_storage.py', '-a', '--bucket', 'r8-deps', platform | |
| ]) | |
| # Cleanup | |
| shutil.rmtree(extract_dir) | |
| shutil.rmtree(platform) | |
| if os.path.exists(platform + '.tar.gz'): | |
| os.remove(platform + '.tar.gz') | |
| # git add *.sha1 | |
| run_command(['git', 'add', '*.sha1']) | |
| print('\nJDK version %s added successfully.' % jdk_version) | |
| print( | |
| 'Update additional files, see https://r8-review.googlesource.com/c/r8/+/111040' | |
| ) | |
| return 0 | |
| if __name__ == '__main__': | |
| sys.exit(main()) |