| #!/usr/bin/env dart |
| // Copyright 2024, the Dart 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. |
| |
| /// Updates the CIPD packages used for browser testing on Luci. |
| |
| import 'dart:async'; |
| import 'dart:io' as io; |
| |
| import 'package:args/args.dart'; |
| import 'package:deps/browsers/chrome.dart'; |
| import 'package:deps/browsers/firefox.dart'; |
| import 'package:deps/package.dart'; |
| import 'package:deps/provenance.dart'; |
| import 'package:file/local.dart'; |
| import 'package:io/io.dart'; |
| import 'package:logging/logging.dart'; |
| |
| const platforms = { |
| 'chrome': { |
| 'linux-amd64': 'linux64', |
| 'mac-amd64': 'mac64', |
| 'mac-arm64': 'mac-arm64', |
| 'windows-amd64': 'win64-clang' |
| }, |
| 'firefox': {'linux-amd64': 'linux-x86_64', 'windows-amd64': 'win64'}, |
| }; |
| const chromedriverPlatforms = { |
| 'linux-amd64': 'linux64', |
| 'mac-amd64': 'mac64', |
| 'mac-arm64': 'mac64_m1', |
| 'windows-amd64': 'win32' |
| }; |
| |
| void main(List<String> args) async { |
| final options = _parse(args); |
| if (options['verbose'] == true) { |
| Logger.root.level = Level.ALL; |
| } else { |
| Logger.root.level = Level.WARNING; |
| } |
| Logger.root.onRecord.listen((record) { |
| print('${record.level.name} (${record.time}): ${record.message}'); |
| }); |
| final isDryRun = options['dry-run']; |
| final version = options['version']; |
| final browser = options['browser']; |
| final provenance = options['provenance']; |
| final temp = await LocalFileSystem().systemTempDirectory.createTemp(); |
| |
| // TODO: Restructure to download and upload all the packages in phases. |
| if (provenance) { |
| await provenanceReportStage('compile'); |
| await provenanceReportStage('upload'); |
| } |
| |
| Future<void> updateFirefox(String platform, String os) async { |
| await FirefoxPackage(platform, os, version).create(temp, provenance); |
| } |
| |
| Future<void> updateChrome(String platform, String os) async { |
| await ChromeDriverPackage(platform, version).create(temp, provenance); |
| await ChromePackage(platform, version).create(temp, provenance); |
| } |
| |
| final update = { |
| 'chrome': updateChrome, |
| 'firefox': updateFirefox, |
| }[browser]!; |
| try { |
| await dryRun(() async { |
| for (final entry in platforms[browser]!.entries) { |
| await update(entry.key, entry.value); |
| } |
| }, isDryRun); |
| } on FormatException catch (e) { |
| io.stderr.writeln(e.message); |
| io.exitCode = ExitCode.data.code; |
| } on StateError catch (e) { |
| io.stderr.writeln(e.message); |
| io.exitCode = ExitCode.config.code; |
| } on io.IOException catch (e) { |
| io.stderr.writeln(e); |
| io.exitCode = ExitCode.ioError.code; |
| } finally { |
| await temp.delete(recursive: true); |
| } |
| |
| if (provenance) { |
| await provenanceReportStage('upload-complete'); |
| } |
| } |
| |
| ArgResults _parse(List<String> args) { |
| final parser = ArgParser(); |
| parser.addOption('browser', |
| abbr: 'b', |
| allowed: ['chrome', 'firefox'], |
| help: 'Which browser to update.'); |
| parser.addOption('version', abbr: 'V', help: ''' |
| The version of the browser to update to. |
| For Firefox, specify the candidate build number with "+": 67.0.4+1'''); |
| parser.addFlag('verbose', |
| abbr: 'v', help: 'Produce verbose output.', negatable: false); |
| parser.addFlag('help', help: 'Show the program usage.', negatable: false); |
| parser.addFlag('dry-run', |
| abbr: 'n', help: 'Run without creating packages', negatable: false); |
| parser.addFlag('provenance', |
| abbr: 'p', help: 'Attach provenance to the packages', negatable: false); |
| |
| final options = parser.parse(args); |
| if (options['help'] || |
| options['browser'] == null || |
| options['version'] == null) { |
| print(''' |
| Usage: deps.dart --browser=BROWSER --version=VERSION [OPTION...] |
| Downloads the version of BROWSER and re-packages and uploads it as a CIPD |
| package. Update the test_matrix.json to use the new version. |
| |
| The options are as follows: |
| |
| ${parser.usage}'''); |
| io.exit(options['help'] ? 0 : 1); |
| } |
| return options; |
| } |