Skip to content

Commit 66bf00b

Browse files
authored
refactoring chrome_installer (#13122)
* refactoring before implementing the firefox installer. This PR carries utilities to a common place. Renames the lock file with a generic name. * Fixed README file for browser_lock * addressing PR comments: removing unimplemented firefox methods.
1 parent 531a9cf commit 66bf00b

File tree

5 files changed

+114
-87
lines changed

5 files changed

+114
-87
lines changed

lib/web_ui/dev/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ felt test --debug test/golden_tests/engine/canvas_golden_test.dart
4141

4242
## Configuration files
4343

44-
`chrome_lock.yaml` contains the version of Chrome we use to test Flutter for
45-
web. Chrome is not automatically updated whenever a new release is available.
44+
`browser_lock.yaml` contains the version of browsers we use to test Flutter for
45+
web. Versions are not automatically updated whenever a new release is available.
4646
Instead, we update this file manually once in a while.
4747

4848
`goldens_lock.yaml` refers to a revision in the https://github.com/flutter/goldens

lib/web_ui/dev/browser_lock.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
chrome:
2+
# It seems Chrome can't always release from the same build for all operating
3+
# systems, so we specify per-OS build number.
4+
Linux: 695653
5+
Mac: 695656
6+
firefox:
7+
version: 69.0.3

lib/web_ui/dev/chrome_installer.dart

Lines changed: 30 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ import 'package:meta/meta.dart';
1010
import 'package:path/path.dart' as path;
1111
import 'package:yaml/yaml.dart';
1212

13+
import 'common.dart';
1314
import 'environment.dart';
1415

1516
void addChromeVersionOption(ArgParser argParser) {
16-
final io.File lockFile = io.File(path.join(environment.webUiRootDir.path, 'dev', 'chrome_lock.yaml'));
17+
final io.File lockFile = io.File(
18+
path.join(environment.webUiRootDir.path, 'dev', 'browser_lock.yaml'));
1719
final YamlMap lock = loadYaml(lockFile.readAsStringSync());
18-
final int pinnedChromeVersion = _PlatformBinding.instance.getChromeBuild(lock);
20+
final int pinnedChromeVersion = PlatformBinding.instance.getChromeBuild(lock);
1921

2022
argParser
2123
..addOption(
@@ -34,7 +36,7 @@ void addChromeVersionOption(ArgParser argParser) {
3436
///
3537
/// If [requestedVersion] is null, uses the version specified on the
3638
/// command-line. If not specified on the command-line, uses the version
37-
/// specified in the "chrome_lock.yaml" file.
39+
/// specified in the "browser_lock.yaml" file.
3840
///
3941
/// If [requestedVersion] is not null, installs that version. The value
4042
/// may be "latest" (the latest available build of Chrome), "system"
@@ -58,16 +60,18 @@ Future<ChromeInstallation> getOrInstallChrome(
5860
ChromeInstaller installer;
5961
try {
6062
installer = requestedVersion == 'latest'
61-
? await ChromeInstaller.latest()
62-
: ChromeInstaller(version: requestedVersion);
63+
? await ChromeInstaller.latest()
64+
: ChromeInstaller(version: requestedVersion);
6365

6466
if (installer.isInstalled) {
65-
infoLog.writeln('Installation was skipped because Chrome version ${installer.version} is already installed.');
67+
infoLog.writeln(
68+
'Installation was skipped because Chrome version ${installer.version} is already installed.');
6669
} else {
6770
infoLog.writeln('Installing Chrome version: ${installer.version}');
6871
await installer.install();
6972
final ChromeInstallation installation = installer.getInstallation();
70-
infoLog.writeln('Installations complete. To launch it run ${installation.executable}');
73+
infoLog.writeln(
74+
'Installations complete. To launch it run ${installation.executable}');
7175
}
7276
return installer.getInstallation();
7377
} finally {
@@ -76,12 +80,12 @@ Future<ChromeInstallation> getOrInstallChrome(
7680
}
7781

7882
Future<String> _findSystemChromeExecutable() async {
79-
final io.ProcessResult which = await io.Process.run('which', <String>['google-chrome']);
83+
final io.ProcessResult which =
84+
await io.Process.run('which', <String>['google-chrome']);
8085

8186
if (which.exitCode != 0) {
82-
throw ChromeInstallerException(
83-
'Failed to locate system Chrome installation.'
84-
);
87+
throw BrowserInstallerException(
88+
'Failed to locate system Chrome installation.');
8589
}
8690

8791
return which.stdout;
@@ -106,14 +110,12 @@ class ChromeInstaller {
106110
@required String version,
107111
}) {
108112
if (version == 'system') {
109-
throw ChromeInstallerException(
110-
'Cannot install system version of Chrome. System Chrome must be installed manually.'
111-
);
113+
throw BrowserInstallerException(
114+
'Cannot install system version of Chrome. System Chrome must be installed manually.');
112115
}
113116
if (version == 'latest') {
114-
throw ChromeInstallerException(
115-
'Expected a concrete Chromer version, but got $version. Maybe use ChromeInstaller.latest()?'
116-
);
117+
throw BrowserInstallerException(
118+
'Expected a concrete Chromer version, but got $version. Maybe use ChromeInstaller.latest()?');
117119
}
118120
final io.Directory chromeInstallationDir = io.Directory(
119121
path.join(environment.webUiDartToolDir.path, 'chrome'),
@@ -162,7 +164,7 @@ class ChromeInstaller {
162164

163165
return ChromeInstallation(
164166
version: version,
165-
executable: _PlatformBinding.instance.getExecutablePath(versionDir),
167+
executable: PlatformBinding.instance.getChromeExecutablePath(versionDir),
166168
);
167169
}
168170

@@ -172,13 +174,14 @@ class ChromeInstaller {
172174
}
173175

174176
versionDir.createSync(recursive: true);
175-
final String url = _PlatformBinding.instance.getDownloadUrl(version);
177+
final String url = PlatformBinding.instance.getChromeDownloadUrl(version);
176178
final StreamedResponse download = await client.send(Request(
177179
'GET',
178180
Uri.parse(url),
179181
));
180182

181-
final io.File downloadedFile = io.File(path.join(versionDir.path, 'chrome.zip'));
183+
final io.File downloadedFile =
184+
io.File(path.join(versionDir.path, 'chrome.zip'));
182185
await download.stream.pipe(downloadedFile.openWrite());
183186

184187
final io.ProcessResult unzipResult = await io.Process.run('unzip', <String>[
@@ -188,10 +191,9 @@ class ChromeInstaller {
188191
]);
189192

190193
if (unzipResult.exitCode != 0) {
191-
throw ChromeInstallerException(
192-
'Failed to unzip the downloaded Chrome archive ${downloadedFile.path}.\n'
193-
'The unzip process exited with code ${unzipResult.exitCode}.'
194-
);
194+
throw BrowserInstallerException(
195+
'Failed to unzip the downloaded Chrome archive ${downloadedFile.path}.\n'
196+
'The unzip process exited with code ${unzipResult.exitCode}.');
195197
}
196198

197199
downloadedFile.deleteSync();
@@ -202,71 +204,18 @@ class ChromeInstaller {
202204
}
203205
}
204206

205-
class ChromeInstallerException implements Exception {
206-
ChromeInstallerException(this.message);
207-
208-
final String message;
209-
210-
@override
211-
String toString() => message;
212-
}
213-
214207
/// Fetches the latest available Chrome build version.
215208
Future<String> fetchLatestChromeVersion() async {
216209
final Client client = Client();
217210
try {
218-
final Response response = await client.get('https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2FLAST_CHANGE?alt=media');
211+
final Response response = await client.get(
212+
'https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2FLAST_CHANGE?alt=media');
219213
if (response.statusCode != 200) {
220-
throw ChromeInstallerException(
221-
'Failed to fetch latest Chrome version. Server returned status code ${response.statusCode}'
222-
);
214+
throw BrowserInstallerException(
215+
'Failed to fetch latest Chrome version. Server returned status code ${response.statusCode}');
223216
}
224217
return response.body;
225218
} finally {
226219
client.close();
227220
}
228221
}
229-
230-
abstract class _PlatformBinding {
231-
static _PlatformBinding get instance {
232-
if (_instance == null) {
233-
if (io.Platform.isLinux) {
234-
_instance = _LinuxBinding();
235-
} else if (io.Platform.isMacOS) {
236-
_instance = _MacBinding();
237-
} else {
238-
throw '${io.Platform.operatingSystem} is not supported';
239-
}
240-
}
241-
return _instance;
242-
}
243-
static _PlatformBinding _instance;
244-
245-
int getChromeBuild(YamlMap chromeLock);
246-
String getDownloadUrl(String version);
247-
String getExecutablePath(io.Directory versionDir);
248-
}
249-
250-
const String _kBaseDownloadUrl = 'https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o';
251-
252-
class _LinuxBinding implements _PlatformBinding {
253-
@override
254-
int getChromeBuild(YamlMap chromeLock) => chromeLock['Linux'];
255-
256-
@override
257-
String getDownloadUrl(String version) => '$_kBaseDownloadUrl/Linux_x64%2F$version%2Fchrome-linux.zip?alt=media';
258-
259-
@override
260-
String getExecutablePath(io.Directory versionDir) => path.join(versionDir.path, 'chrome-linux', 'chrome');
261-
}
262-
263-
class _MacBinding implements _PlatformBinding {
264-
@override
265-
int getChromeBuild(YamlMap chromeLock) => chromeLock['Mac'];
266-
267-
@override
268-
String getDownloadUrl(String version) => '$_kBaseDownloadUrl/Mac%2F$version%2Fchrome-mac.zip?alt=media';
269-
270-
@override
271-
String getExecutablePath(io.Directory versionDir) => path.join(versionDir.path, 'chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium');
272-
}

lib/web_ui/dev/chrome_lock.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

lib/web_ui/dev/common.dart

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:io' as io;
6+
7+
import 'package:path/path.dart' as path;
8+
import 'package:yaml/yaml.dart';
9+
10+
class BrowserInstallerException implements Exception {
11+
BrowserInstallerException(this.message);
12+
13+
final String message;
14+
15+
@override
16+
String toString() => message;
17+
}
18+
19+
abstract class PlatformBinding {
20+
static PlatformBinding get instance {
21+
if (_instance == null) {
22+
if (io.Platform.isLinux) {
23+
_instance = _LinuxBinding();
24+
} else if (io.Platform.isMacOS) {
25+
_instance = _MacBinding();
26+
} else {
27+
throw '${io.Platform.operatingSystem} is not supported';
28+
}
29+
}
30+
return _instance;
31+
}
32+
33+
static PlatformBinding _instance;
34+
35+
int getChromeBuild(YamlMap chromeLock);
36+
String getChromeDownloadUrl(String version);
37+
String getChromeExecutablePath(io.Directory versionDir);
38+
}
39+
40+
const String _kBaseDownloadUrl =
41+
'https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o';
42+
43+
class _LinuxBinding implements PlatformBinding {
44+
@override
45+
int getChromeBuild(YamlMap browserLock) {
46+
final YamlMap chromeMap = browserLock['chrome'];
47+
return chromeMap['Linux'];
48+
}
49+
50+
@override
51+
String getChromeDownloadUrl(String version) =>
52+
'$_kBaseDownloadUrl/Linux_x64%2F$version%2Fchrome-linux.zip?alt=media';
53+
54+
@override
55+
String getChromeExecutablePath(io.Directory versionDir) =>
56+
path.join(versionDir.path, 'chrome-linux', 'chrome');
57+
}
58+
59+
class _MacBinding implements PlatformBinding {
60+
@override
61+
int getChromeBuild(YamlMap browserLock) => browserLock['Mac'];
62+
63+
@override
64+
String getChromeDownloadUrl(String version) =>
65+
'$_kBaseDownloadUrl/Mac%2F$version%2Fchrome-mac.zip?alt=media';
66+
67+
@override
68+
String getChromeExecutablePath(io.Directory versionDir) => path.join(
69+
versionDir.path,
70+
'chrome-mac',
71+
'Chromium.app',
72+
'Contents',
73+
'MacOS',
74+
'Chromium');
75+
}

0 commit comments

Comments
 (0)