blob: 3aa804d207cdcecefb805d073008d22783855ccd [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert' show json;
import 'dart:io';
import 'package:path/path.dart' as pathlib;
import 'package:yaml/yaml.dart';
import 'environment.dart';
import 'utils.dart';
/// Rolls CanvasKit to the version specified in `dev/canvaskit_lock.yaml`.
///
/// Detailed instructions for how to use this script can be found in
/// `lib/web_ui/README.md`.
Future<void> main(List<String> args) async {
final String canvaskitVersion = _readCanvaskitVersion();
print('Rolling CanvasKit to version $canvaskitVersion');
final Directory canvaskitDirectory = await Directory.systemTemp.createTemp('canvaskit-roll-$canvaskitVersion-');
print('Will use ${canvaskitDirectory.path} as staging directory.');
final String baseUrl = 'https://unpkg.com/canvaskit-wasm@$canvaskitVersion/bin/';
print('Downloading CanvasKit from $baseUrl');
final HttpClient client = HttpClient();
for (final String assetPath in _canvaskitAssets) {
final String assetUrl = '$baseUrl/$assetPath';
final File assetFile = File(pathlib.joinAll(<String>[
canvaskitDirectory.path,
'canvaskit',
...assetPath.split('/'), // so it's compatible with Windows
]));
await assetFile.parent.create(recursive: true);
final HttpClientRequest request = await client.getUrl(Uri.parse(assetUrl));
final HttpClientResponse response = await request.close();
final IOSink fileSink = assetFile.openWrite();
await response.pipe(fileSink);
}
client.close();
final File cipdConfigFile = File(pathlib.join(
canvaskitDirectory.path,
'cipd.yaml',
));
await cipdConfigFile.writeAsString('''
package: flutter/web/canvaskit_bundle
description: A build of CanvasKit bundled with Flutter Web apps
data:
- dir: canvaskit
''');
print('Uploading to CIPD');
await runProcess('cipd', <String>[
'create',
'--tag=version:$canvaskitVersion',
'--pkg-def=cipd.yaml',
'--json-output=result.json',
], workingDirectory: canvaskitDirectory.path);
final Map<String, dynamic> cipdResult = json.decode(File(pathlib.join(
canvaskitDirectory.path,
'result.json',
)).readAsStringSync()) as Map<String, dynamic>;
final String cipdInstanceId = cipdResult['result']['instance_id'] as String;
print('CIPD instance information:');
final String cipdInfo = await evalProcess('cipd', <String>[
'describe',
'flutter/web/canvaskit_bundle',
'--version=$cipdInstanceId',
], workingDirectory: canvaskitDirectory.path);
print(cipdInfo.trim().split('\n').map((String line) => ' • $line').join('\n'));
print('Updating DEPS file');
await _updateDepsFile(cipdInstanceId);
await _updateCanvaskitInitializationCode(canvaskitVersion);
print('\nATTENTION: the roll process is not complete yet.');
print('Last step: for the roll to take effect submit an engine pull request from local git changes.');
}
const List<String> _canvaskitAssets = <String>[
'canvaskit.js',
'canvaskit.wasm',
'profiling/canvaskit.js',
'profiling/canvaskit.wasm',
];
String _readCanvaskitVersion() {
final YamlMap canvaskitLock = loadYaml(File(pathlib.join(
environment.webUiDevDir.path,
'canvaskit_lock.yaml',
)).readAsStringSync()) as YamlMap;
return canvaskitLock['canvaskit_version'] as String;
}
Future<void> _updateDepsFile(String cipdInstanceId) async {
final File depsFile = File(pathlib.join(
environment.flutterDirectory.path,
'DEPS',
));
final String originalDepsCode = await depsFile.readAsString();
final List<String> rewrittenDepsCode = <String>[];
const String kCanvasKitDependencyKeyInDeps = '\'canvaskit_cipd_instance\': \'';
bool canvaskitDependencyFound = false;
for (final String line in originalDepsCode.split('\n')) {
if (line.trim().startsWith(kCanvasKitDependencyKeyInDeps)) {
canvaskitDependencyFound = true;
rewrittenDepsCode.add(
" 'canvaskit_cipd_instance': '$cipdInstanceId',",
);
} else {
rewrittenDepsCode.add(line);
}
}
if (!canvaskitDependencyFound) {
stderr.writeln(
'Failed to update the DEPS file.\n'
'Could not to locate CanvasKit dependency in the DEPS file. Make sure the '
'DEPS file contains a line like this:\n'
'\n'
' \'canvaskit_cipd_instance\': \'SOME_VALUE\','
);
exit(1);
}
await depsFile.writeAsString(rewrittenDepsCode.join('\n'));
}
Future<void> _updateCanvaskitInitializationCode(String canvaskitVersion) async {
const String kCanvasKitVersionKey = 'const String _canvaskitVersion';
const String kPathToConfigurationCode = 'lib/src/engine/configuration.dart';
final File initializationFile = File(pathlib.join(
environment.webUiRootDir.path,
kPathToConfigurationCode,
));
final String originalInitializationCode = await initializationFile.readAsString();
final List<String> rewrittenCode = <String>[];
bool canvaskitVersionFound = false;
for (final String line in originalInitializationCode.split('\n')) {
if (line.trim().startsWith(kCanvasKitVersionKey)) {
canvaskitVersionFound = true;
rewrittenCode.add(
"const String _canvaskitVersion = '$canvaskitVersion';",
);
} else {
rewrittenCode.add(line);
}
}
if (!canvaskitVersionFound) {
stderr.writeln(
'Failed to update CanvasKit version in $kPathToConfigurationCode.\n'
'Could not to locate the constant that defines the version. Make sure the '
'$kPathToConfigurationCode file contains a line like this:\n'
'\n'
'const String _canvaskitVersion = \'VERSION\';'
);
exit(1);
}
await initializationFile.writeAsString(rewrittenCode.join('\n'));
}