Skip to content

Commit 3b2c441

Browse files
[tools] Add mockito support to update-dependency (flutter#4260)
Regenerates mocks when updating `mockito` using the tooling. Fixes flutter#124196
1 parent 0f56eae commit 3b2c441

File tree

2 files changed

+159
-1
lines changed

2 files changed

+159
-1
lines changed

script/tool/lib/src/update_dependency_command.dart

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,13 @@ ${response.httpResponse.body}
170170
if (!await _regeneratePigeonFiles(package)) {
171171
return PackageResult.fail(<String>['Failed to update pigeon files']);
172172
}
173+
} else if (dependency == 'mockito') {
174+
if (!await _regenerateMocks(package)) {
175+
return PackageResult.fail(<String>['Failed to update mocks']);
176+
}
173177
}
174178
// TODO(stuartmorgan): Add additional handling of known packages that
175-
// do file generation (mockito, etc.).
179+
// do file generation.
176180

177181
return PackageResult.success();
178182
}
@@ -258,6 +262,43 @@ ${response.httpResponse.body}
258262
}
259263
return true;
260264
}
265+
266+
/// Re-runs Mockito mock generation for [package] if necessary.
267+
Future<bool> _regenerateMocks(RepositoryPackage package) async {
268+
final Pubspec pubspec = package.parsePubspec();
269+
if (!pubspec.devDependencies.keys.contains('build_runner')) {
270+
print(
271+
'${indentation}No build_runner dependency; skipping mock regeneration.');
272+
return true;
273+
}
274+
275+
print('${indentation}Running pub get...');
276+
final io.ProcessResult getResult = await processRunner
277+
.run('dart', <String>['pub', 'get'], workingDir: package.directory);
278+
if (getResult.exitCode != 0) {
279+
printError('dart pub get failed (${getResult.exitCode}):\n'
280+
'${getResult.stdout}\n${getResult.stderr}\n');
281+
return false;
282+
}
283+
284+
print('${indentation}Updating mocks...');
285+
final io.ProcessResult buildRunnerResult = await processRunner.run(
286+
'dart',
287+
<String>[
288+
'run',
289+
'build_runner',
290+
'build',
291+
'--delete-conflicting-outputs'
292+
],
293+
workingDir: package.directory);
294+
if (buildRunnerResult.exitCode != 0) {
295+
printError(
296+
'"dart run build_runner build" failed (${buildRunnerResult.exitCode}):\n'
297+
'${buildRunnerResult.stdout}\n${buildRunnerResult.stderr}\n');
298+
return false;
299+
}
300+
return true;
301+
}
261302
}
262303

263304
class _PubDependencyInfo {

script/tool/test/update_dependency_command_test.dart

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,5 +466,122 @@ dev_dependencies:
466466
]),
467467
);
468468
});
469+
470+
test('regenerates mocks when updating mockito if necessary', () async {
471+
final RepositoryPackage package =
472+
createFakePackage('a_package', packagesDir);
473+
addDependency(package, 'mockito', version: '1.0.0');
474+
addDevDependency(package, 'build_runner');
475+
476+
await runCapturingPrint(runner, <String>[
477+
'update-dependency',
478+
'--pub-package',
479+
'mockito',
480+
'--version',
481+
'1.5.0',
482+
]);
483+
484+
expect(
485+
processRunner.recordedCalls,
486+
orderedEquals(<ProcessCall>[
487+
ProcessCall(
488+
'dart',
489+
const <String>['pub', 'get'],
490+
package.path,
491+
),
492+
ProcessCall(
493+
'dart',
494+
const <String>[
495+
'run',
496+
'build_runner',
497+
'build',
498+
'--delete-conflicting-outputs'
499+
],
500+
package.path,
501+
),
502+
]),
503+
);
504+
});
505+
506+
test('skips regenerating mocks when there is no build_runner dependency',
507+
() async {
508+
final RepositoryPackage package =
509+
createFakePackage('a_package', packagesDir);
510+
addDependency(package, 'mockito', version: '1.0.0');
511+
512+
await runCapturingPrint(runner, <String>[
513+
'update-dependency',
514+
'--pub-package',
515+
'mockito',
516+
'--version',
517+
'1.5.0',
518+
]);
519+
520+
expect(processRunner.recordedCalls.isEmpty, true);
521+
});
522+
523+
test('updating mockito fails if pub get fails', () async {
524+
final RepositoryPackage package =
525+
createFakePackage('a_package', packagesDir);
526+
addDependency(package, 'mockito', version: '1.0.0');
527+
addDevDependency(package, 'build_runner');
528+
529+
processRunner.mockProcessesForExecutable['dart'] = <FakeProcessInfo>[
530+
FakeProcessInfo(MockProcess(exitCode: 1), <String>['pub', 'get'])
531+
];
532+
533+
Error? commandError;
534+
final List<String> output = await runCapturingPrint(runner, <String>[
535+
'update-dependency',
536+
'--pub-package',
537+
'mockito',
538+
'--version',
539+
'1.5.0',
540+
], errorHandler: (Error e) {
541+
commandError = e;
542+
});
543+
544+
expect(commandError, isA<ToolExit>());
545+
expect(
546+
output,
547+
containsAllInOrder(<Matcher>[
548+
contains('dart pub get failed'),
549+
contains('Failed to update mocks'),
550+
]),
551+
);
552+
});
553+
554+
test('updating mockito fails if running build_runner fails', () async {
555+
final RepositoryPackage package =
556+
createFakePackage('a_package', packagesDir);
557+
addDependency(package, 'mockito', version: '1.0.0');
558+
addDevDependency(package, 'build_runner');
559+
560+
processRunner.mockProcessesForExecutable['dart'] = <FakeProcessInfo>[
561+
FakeProcessInfo(MockProcess(), <String>['pub', 'get']),
562+
FakeProcessInfo(
563+
MockProcess(exitCode: 1), <String>['run', 'build_runner']),
564+
];
565+
566+
Error? commandError;
567+
final List<String> output = await runCapturingPrint(runner, <String>[
568+
'update-dependency',
569+
'--pub-package',
570+
'mockito',
571+
'--version',
572+
'1.5.0',
573+
], errorHandler: (Error e) {
574+
commandError = e;
575+
});
576+
577+
expect(commandError, isA<ToolExit>());
578+
expect(
579+
output,
580+
containsAllInOrder(<Matcher>[
581+
contains('"dart run build_runner build" failed'),
582+
contains('Failed to update mocks'),
583+
]),
584+
);
585+
});
469586
});
470587
}

0 commit comments

Comments
 (0)