Skip to content

Commit 61bdbb4

Browse files
[tool] Use flutter for pub commands when examples use Flutter (#11830)
#11797 changed the repo tooling to use `dart` instead of `flutter` for more commands when the target package isn't a Flutter package, include `pub downgrade` and `pub get` in `analyze`. However, since `pub get` will resolve any example apps, if any of *them* use Flutter, `dart pub get` will fail unless `dart` is coming from the Flutter SDK. Normally this is fine since that's the expected setup, but for the head-head tests in dart-lang that run the repo analysis using the head version of Dart via the `--analysis-sdk` flag, using that version of Dart for pub commands breaks things. This checks the example apps for Flutter dependencies to ensure that `dart pub` won't be used in cases where that can cause failures to resolve in the examples. This should be safe for core-packages, since core-packages should never use Flutter, even in examples.
1 parent c869a5d commit 61bdbb4

4 files changed

Lines changed: 94 additions & 9 deletions

File tree

script/tool/lib/src/analyze_command.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@ class AnalyzeCommand extends PackageLoopingCommand {
323323
processRunner,
324324
platform,
325325
dartSdkPathOverride: _dartBinaryPath,
326+
// 'get' and 'downgrade' resolve examples as well, so check
327+
// those as well when deciding between `flutter` and `dart`.
328+
recursiveFlutterCheck: true,
326329
);
327330
}
328331

script/tool/lib/src/common/pub_utils.dart

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Future<bool> runPubGet(
2626
processRunner,
2727
platform,
2828
streamOutput: streamOutput,
29+
recursiveFlutterCheck: true,
2930
);
3031
}
3132

@@ -41,8 +42,14 @@ Future<bool> runPubCommand(
4142
Platform platform, {
4243
bool streamOutput = true,
4344
String? dartSdkPathOverride,
45+
bool recursiveFlutterCheck = false,
4446
}) async {
45-
final String command = _pubCommand(package, platform, dartSdkPathOverride: dartSdkPathOverride);
47+
final String command = _pubCommand(
48+
package,
49+
platform,
50+
dartSdkPathOverride: dartSdkPathOverride,
51+
recursiveFlutterCheck: recursiveFlutterCheck,
52+
);
4653
final args = <String>['pub', ...commandArgs];
4754
final int exitCode;
4855
if (streamOutput) {
@@ -78,10 +85,24 @@ Future<io.Process> startPubCommand(
7885
], workingDirectory: package.directory);
7986
}
8087

81-
String _pubCommand(RepositoryPackage package, Platform platform, {String? dartSdkPathOverride}) {
88+
String _pubCommand(
89+
RepositoryPackage package,
90+
Platform platform, {
91+
String? dartSdkPathOverride,
92+
bool recursiveFlutterCheck = false,
93+
}) {
8294
// Running `dart pub get` on a Flutter package can fail if a non-Flutter Dart
8395
// is first in the path, so use `flutter pub get` for any Flutter package.
84-
return package.requiresFlutter()
96+
bool useFlutter = package.requiresFlutter();
97+
if (!useFlutter && recursiveFlutterCheck) {
98+
for (final RepositoryPackage example in package.getExamples()) {
99+
if (example.requiresFlutter()) {
100+
useFlutter = true;
101+
break;
102+
}
103+
}
104+
}
105+
return useFlutter
85106
? (platform.isWindows ? 'flutter.bat' : 'flutter')
86107
: (dartSdkPathOverride ?? 'dart');
87108
}

script/tool/test/analyze_command_test.dart

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,21 @@ void main() {
175175
);
176176
});
177177

178+
test('runs flutter pub get for non-Flutter packages with Flutter examples', () async {
179+
final RepositoryPackage mainPackage = createFakePackage('a', packagesDir, examples: []);
180+
createFakePackage('example', mainPackage.directory, examples: [], isFlutter: true);
181+
182+
await runCapturingPrint(runner, <String>['analyze']);
183+
184+
expect(
185+
processRunner.recordedCalls,
186+
orderedEquals(<ProcessCall>[
187+
ProcessCall('flutter', const <String>['pub', 'get'], mainPackage.path),
188+
ProcessCall('dart', const <String>['analyze', '--fatal-infos'], mainPackage.path),
189+
]),
190+
);
191+
});
192+
178193
test('passes lib/ directory with --lib-only', () async {
179194
final RepositoryPackage package = createFakePackage('a_package', packagesDir);
180195

@@ -254,16 +269,47 @@ void main() {
254269
});
255270

256271
test('downgrades first when requested', () async {
257-
final RepositoryPackage plugin = createFakePlugin('a', packagesDir);
272+
final RepositoryPackage package = createFakePackage('a', packagesDir);
258273

259274
await runCapturingPrint(runner, <String>['analyze', '--downgrade']);
260275

261276
expect(
262277
processRunner.recordedCalls,
263278
orderedEquals(<ProcessCall>[
264-
ProcessCall('flutter', const <String>['pub', 'downgrade'], plugin.path),
265-
ProcessCall('flutter', const <String>['pub', 'get'], plugin.path),
266-
ProcessCall('dart', const <String>['analyze', '--fatal-infos'], plugin.path),
279+
ProcessCall('dart', const <String>['pub', 'downgrade'], package.path),
280+
ProcessCall('dart', const <String>['pub', 'get'], package.path),
281+
ProcessCall('dart', const <String>['analyze', '--fatal-infos'], package.path),
282+
]),
283+
);
284+
});
285+
286+
test('downgrades using flutter for Flutter packages', () async {
287+
final RepositoryPackage package = createFakePackage('a', packagesDir, isFlutter: true);
288+
289+
await runCapturingPrint(runner, <String>['analyze', '--downgrade']);
290+
291+
expect(
292+
processRunner.recordedCalls,
293+
orderedEquals(<ProcessCall>[
294+
ProcessCall('flutter', const <String>['pub', 'downgrade'], package.path),
295+
ProcessCall('flutter', const <String>['pub', 'get'], package.path),
296+
ProcessCall('dart', const <String>['analyze', '--fatal-infos'], package.path),
297+
]),
298+
);
299+
});
300+
301+
test('downgrades using flutter for non-Flutter packages with Flutter examples', () async {
302+
final RepositoryPackage package = createFakePackage('a', packagesDir, examples: []);
303+
createFakePackage('example', package.directory, examples: [], isFlutter: true);
304+
305+
await runCapturingPrint(runner, <String>['analyze', '--downgrade']);
306+
307+
expect(
308+
processRunner.recordedCalls,
309+
orderedEquals(<ProcessCall>[
310+
ProcessCall('flutter', const <String>['pub', 'downgrade'], package.path),
311+
ProcessCall('flutter', const <String>['pub', 'get'], package.path),
312+
ProcessCall('dart', const <String>['analyze', '--fatal-infos'], package.path),
267313
]),
268314
);
269315
});

script/tool/test/common/pub_utils_test.dart

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ void main() {
1717
(:packagesDir, :processRunner, gitProcessRunner: _, gitDir: _) = configureBaseCommandMocks();
1818
});
1919

20-
test('runs with Dart for a non-Flutter package by default', () async {
20+
test('runs with Dart for a non-Flutter package', () async {
2121
final RepositoryPackage package = createFakePackage('a_package', packagesDir);
2222
final platform = MockPlatform();
2323

@@ -31,7 +31,7 @@ void main() {
3131
);
3232
});
3333

34-
test('runs with Flutter for a Flutter package by default', () async {
34+
test('runs with Flutter for a Flutter package', () async {
3535
final RepositoryPackage package = createFakePackage('a_package', packagesDir, isFlutter: true);
3636
final platform = MockPlatform();
3737

@@ -45,6 +45,21 @@ void main() {
4545
);
4646
});
4747

48+
test('runs with Flutter for a non-Flutter package with a Flutter example', () async {
49+
final RepositoryPackage package = createFakePackage('a_package', packagesDir, examples: []);
50+
createFakePackage('example', package.directory, examples: [], isFlutter: true);
51+
final platform = MockPlatform();
52+
53+
await runPubGet(package, processRunner, platform);
54+
55+
expect(
56+
processRunner.recordedCalls,
57+
orderedEquals(<ProcessCall>[
58+
ProcessCall('flutter', const <String>['pub', 'get'], package.path),
59+
]),
60+
);
61+
});
62+
4863
test('uses the correct Flutter command on Windows', () async {
4964
final RepositoryPackage package = createFakePackage('a_package', packagesDir, isFlutter: true);
5065
final platform = MockPlatform(isWindows: true);

0 commit comments

Comments
 (0)