Skip to content

Commit 6961977

Browse files
committed
[Windows] Allow overwriting the cache's Dart SDK archive license file (flutter#132669)
flutter/engine#43974 added a license file to the Dart SDK's ZIP archive. As a result, extracting the Dart SDK now needs to overwrite the cache's `LICENSE.dart_sdk_archive.md` file. This is a short-term solution that will be cherry-picked for the next [3.14 beta release](flutter#132267). Addresses flutter#132592. The long-term solution is tracked by flutter#132702
1 parent c5b7ed9 commit 6961977

File tree

2 files changed

+119
-3
lines changed

2 files changed

+119
-3
lines changed

bin/internal/update_dart_sdk.ps1

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ $flutterRoot = (Get-Item $progName).parent.parent.FullName
1818

1919
$cachePath = "$flutterRoot\bin\cache"
2020
$dartSdkPath = "$cachePath\dart-sdk"
21+
$dartSdkLicense = "$cachePath\LICENSE.dart_sdk_archive.md"
2122
$engineStamp = "$cachePath\engine-dart-sdk.stamp"
2223
$engineVersion = (Get-Content "$flutterRoot\bin\internal\engine.version")
2324

@@ -45,11 +46,18 @@ if (-not $dartSdkBaseUrl) {
4546
$dartZipName = "dart-sdk-windows-x64.zip"
4647
$dartSdkUrl = "$dartSdkBaseUrl/flutter_infra_release/flutter/$engineVersion/$dartZipName"
4748

48-
if (Test-Path $dartSdkPath) {
49+
if ((Test-Path $dartSdkPath) -or (Test-Path $dartSdkLicense)) {
4950
# Move old SDK to a new location instead of deleting it in case it is still in use (e.g. by IntelliJ).
5051
$oldDartSdkSuffix = 1
5152
while (Test-Path "$cachePath\$oldDartSdkPrefix$oldDartSdkSuffix") { $oldDartSdkSuffix++ }
52-
Rename-Item $dartSdkPath "$oldDartSdkPrefix$oldDartSdkSuffix"
53+
54+
if (Test-Path $dartSdkPath) {
55+
Rename-Item $dartSdkPath "$oldDartSdkPrefix$oldDartSdkSuffix"
56+
}
57+
58+
if (Test-Path $dartSdkLicense) {
59+
Rename-Item $dartSdkLicense "$oldDartSdkPrefix$oldDartSdkSuffix.LICENSE.md"
60+
}
5361
}
5462
New-Item $dartSdkPath -force -type directory | Out-Null
5563
$dartSdkZip = "$cachePath\$dartZipName"
@@ -94,5 +102,5 @@ If (Get-Command 7z -errorAction SilentlyContinue) {
94102
Remove-Item $dartSdkZip
95103
$engineVersion | Out-File $engineStamp -Encoding ASCII
96104

97-
# Try to delete all old SDKs.
105+
# Try to delete all old SDKs and license files.
98106
Get-ChildItem -Path $cachePath | Where {$_.BaseName.StartsWith($oldDartSdkPrefix)} | Remove-Item -Recurse -ErrorAction SilentlyContinue
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright 2014 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:async';
6+
import 'dart:convert';
7+
8+
import 'package:file/file.dart';
9+
import 'package:flutter_tools/src/base/io.dart';
10+
11+
import '../src/common.dart';
12+
import 'test_utils.dart';
13+
14+
final String flutterRootPath = getFlutterRoot();
15+
final Directory flutterRoot = fileSystem.directory(flutterRootPath);
16+
17+
Future<void> main() async {
18+
// Regression test for https://github.com/flutter/flutter/issues/132592
19+
test('flutter/bin/dart updates the Dart SDK without hanging', () async {
20+
// Run the Dart entrypoint once to ensure the Dart SDK is downloaded.
21+
await runDartBatch();
22+
23+
expect(dartSdkStamp.existsSync(), true);
24+
25+
// Remove the Dart SDK stamp and run the Dart entrypoint again to trigger
26+
// the Dart SDK update.
27+
dartSdkStamp.deleteSync();
28+
final Future<String> runFuture = runDartBatch();
29+
final Timer timer = Timer(const Duration(minutes: 5), () {
30+
// This print is useful for people debugging this test. Normally we would
31+
// avoid printing in a test but this is an exception because it's useful
32+
// ambient information.
33+
// ignore: avoid_print
34+
print(
35+
'The Dart batch entrypoint did not complete after 5 minutes. '
36+
'Historically this is a sign that 7-Zip zip extraction is waiting for '
37+
'the user to confirm they would like to overwrite files. '
38+
"This likely means the test isn't a flake and will fail. "
39+
'See: https://github.com/flutter/flutter/issues/132592'
40+
);
41+
});
42+
43+
final String output = await runFuture;
44+
timer.cancel();
45+
46+
// Check the Dart SDK was re-downloaded and extracted.
47+
// If 7-Zip is installed, unexpected overwrites causes this to hang.
48+
// If 7-Zip is not installed, unexpected overwrites results in error messages.
49+
// See: https://github.com/flutter/flutter/issues/132592
50+
expect(dartSdkStamp.existsSync(), true);
51+
expect(output, contains('Downloading Dart SDK from Flutter engine ...'));
52+
expect(output, contains('Expanding downloaded archive...'));
53+
expect(output, isNot(contains('Use the -Force parameter' /* Luke */)));
54+
},
55+
skip: !platform.isWindows); // [intended] Only Windows uses the batch entrypoint
56+
}
57+
58+
Future<String> runDartBatch() async {
59+
String output = '';
60+
final Process process = await processManager.start(
61+
<String>[
62+
dartBatch.path
63+
],
64+
);
65+
final Future<Object?> stdoutFuture = process.stdout
66+
.transform<String>(utf8.decoder)
67+
.forEach((String str) {
68+
output += str;
69+
});
70+
final Future<Object?> stderrFuture = process.stderr
71+
.transform<String>(utf8.decoder)
72+
.forEach((String str) {
73+
output += str;
74+
});
75+
76+
// Wait for the output to complete
77+
await Future.wait(<Future<Object?>>[stdoutFuture, stderrFuture]);
78+
// Ensure child exited successfully
79+
expect(
80+
await process.exitCode,
81+
0,
82+
reason: 'child process exited with code ${await process.exitCode}, and '
83+
'output:\n$output',
84+
);
85+
86+
// Check the Dart tool prints the expected output.
87+
expect(output, contains('A command-line utility for Dart development.'));
88+
expect(output, contains('Usage: dart <command|dart-file> [arguments]'));
89+
90+
return output;
91+
}
92+
93+
// The executable batch entrypoint for the Dart binary.
94+
File get dartBatch {
95+
return flutterRoot
96+
.childDirectory('bin')
97+
.childFile('dart.bat')
98+
.absolute;
99+
}
100+
101+
// The Dart SDK's stamp file.
102+
File get dartSdkStamp {
103+
return flutterRoot
104+
.childDirectory('bin')
105+
.childDirectory('cache')
106+
.childFile('engine-dart-sdk.stamp')
107+
.absolute;
108+
}

0 commit comments

Comments
 (0)