diff --git a/script/tool/lib/src/update_dependency_command.dart b/script/tool/lib/src/update_dependency_command.dart index 30060bc228..d3914ca73b 100644 --- a/script/tool/lib/src/update_dependency_command.dart +++ b/script/tool/lib/src/update_dependency_command.dart @@ -170,9 +170,13 @@ ${response.httpResponse.body} if (!await _regeneratePigeonFiles(package)) { return PackageResult.fail(['Failed to update pigeon files']); } + } else if (dependency == 'mockito') { + if (!await _regenerateMocks(package)) { + return PackageResult.fail(['Failed to update mocks']); + } } // TODO(stuartmorgan): Add additional handling of known packages that - // do file generation (mockito, etc.). + // do file generation. return PackageResult.success(); } @@ -258,6 +262,43 @@ ${response.httpResponse.body} } return true; } + + /// Re-runs Mockito mock generation for [package] if necessary. + Future _regenerateMocks(RepositoryPackage package) async { + final Pubspec pubspec = package.parsePubspec(); + if (!pubspec.devDependencies.keys.contains('build_runner')) { + print( + '${indentation}No build_runner dependency; skipping mock regeneration.'); + return true; + } + + print('${indentation}Running pub get...'); + final io.ProcessResult getResult = await processRunner + .run('dart', ['pub', 'get'], workingDir: package.directory); + if (getResult.exitCode != 0) { + printError('dart pub get failed (${getResult.exitCode}):\n' + '${getResult.stdout}\n${getResult.stderr}\n'); + return false; + } + + print('${indentation}Updating mocks...'); + final io.ProcessResult buildRunnerResult = await processRunner.run( + 'dart', + [ + 'run', + 'build_runner', + 'build', + '--delete-conflicting-outputs' + ], + workingDir: package.directory); + if (buildRunnerResult.exitCode != 0) { + printError( + '"dart run build_runner build" failed (${buildRunnerResult.exitCode}):\n' + '${buildRunnerResult.stdout}\n${buildRunnerResult.stderr}\n'); + return false; + } + return true; + } } class _PubDependencyInfo { diff --git a/script/tool/test/update_dependency_command_test.dart b/script/tool/test/update_dependency_command_test.dart index e0687b2bfd..c19c110e24 100644 --- a/script/tool/test/update_dependency_command_test.dart +++ b/script/tool/test/update_dependency_command_test.dart @@ -466,5 +466,122 @@ dev_dependencies: ]), ); }); + + test('regenerates mocks when updating mockito if necessary', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + addDependency(package, 'mockito', version: '1.0.0'); + addDevDependency(package, 'build_runner'); + + await runCapturingPrint(runner, [ + 'update-dependency', + '--pub-package', + 'mockito', + '--version', + '1.5.0', + ]); + + expect( + processRunner.recordedCalls, + orderedEquals([ + ProcessCall( + 'dart', + const ['pub', 'get'], + package.path, + ), + ProcessCall( + 'dart', + const [ + 'run', + 'build_runner', + 'build', + '--delete-conflicting-outputs' + ], + package.path, + ), + ]), + ); + }); + + test('skips regenerating mocks when there is no build_runner dependency', + () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + addDependency(package, 'mockito', version: '1.0.0'); + + await runCapturingPrint(runner, [ + 'update-dependency', + '--pub-package', + 'mockito', + '--version', + '1.5.0', + ]); + + expect(processRunner.recordedCalls.isEmpty, true); + }); + + test('updating mockito fails if pub get fails', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + addDependency(package, 'mockito', version: '1.0.0'); + addDevDependency(package, 'build_runner'); + + processRunner.mockProcessesForExecutable['dart'] = [ + FakeProcessInfo(MockProcess(exitCode: 1), ['pub', 'get']) + ]; + + Error? commandError; + final List output = await runCapturingPrint(runner, [ + 'update-dependency', + '--pub-package', + 'mockito', + '--version', + '1.5.0', + ], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('dart pub get failed'), + contains('Failed to update mocks'), + ]), + ); + }); + + test('updating mockito fails if running build_runner fails', () async { + final RepositoryPackage package = + createFakePackage('a_package', packagesDir); + addDependency(package, 'mockito', version: '1.0.0'); + addDevDependency(package, 'build_runner'); + + processRunner.mockProcessesForExecutable['dart'] = [ + FakeProcessInfo(MockProcess(), ['pub', 'get']), + FakeProcessInfo( + MockProcess(exitCode: 1), ['run', 'build_runner']), + ]; + + Error? commandError; + final List output = await runCapturingPrint(runner, [ + 'update-dependency', + '--pub-package', + 'mockito', + '--version', + '1.5.0', + ], errorHandler: (Error e) { + commandError = e; + }); + + expect(commandError, isA()); + expect( + output, + containsAllInOrder([ + contains('"dart run build_runner build" failed'), + contains('Failed to update mocks'), + ]), + ); + }); }); }