From d2a62fa827a587a270cc20996480e0d2cbd7fa7c Mon Sep 17 00:00:00 2001 From: Jochum van der Ploeg Date: Thu, 28 Jul 2022 16:59:51 +0200 Subject: [PATCH] feat: add `--verbose` flag (#465) Co-authored-by: Felix Angelov --- lib/src/cli/cli.dart | 5 ++ lib/src/cli/dart_cli.dart | 15 ++++- lib/src/cli/flutter_cli.dart | 37 +++++++++---- lib/src/cli/git_cli.dart | 11 +++- lib/src/command_runner.dart | 39 +++++++++++-- lib/src/commands/create/create.dart | 7 ++- .../templates/post_generate_actions.dart | 22 +++++--- lib/src/commands/packages.dart | 2 +- lib/src/commands/test/test.dart | 12 ++-- lib/src/commands/update.dart | 4 +- pubspec.yaml | 4 +- test/e2e_test.dart | 14 ++--- test/src/cli/dart_cli_test.dart | 17 +++++- test/src/cli/flutter_cli_test.dart | 55 +++++++++++++++---- test/src/cli/git_cli_test.dart | 20 ++++++- test/src/command_runner_test.dart | 50 +++++++++++++++-- test/src/commands/create/create_test.dart | 2 +- test/src/commands/test/test_test.dart | 3 +- 18 files changed, 246 insertions(+), 73 deletions(-) diff --git a/lib/src/cli/cli.dart b/lib/src/cli/cli.dart index d8973ee0..1076bc4d 100644 --- a/lib/src/cli/cli.dart +++ b/lib/src/cli/cli.dart @@ -78,7 +78,9 @@ class _Cmd { List args, { bool throwOnError = true, String? workingDirectory, + required Logger logger, }) async { + logger.detail('Running: $cmd with $args'); final runProcess = ProcessOverrides.current?.runProcess ?? Process.run; final result = await runProcess( cmd, @@ -86,6 +88,9 @@ class _Cmd { workingDirectory: workingDirectory, runInShell: true, ); + logger + ..detail('stdout:\n${result.stdout}') + ..detail('stderr:\n${result.stderr}'); if (throwOnError) { _throwIfProcessFailed(result, cmd, args); diff --git a/lib/src/cli/dart_cli.dart b/lib/src/cli/dart_cli.dart index 23057679..75f24fc9 100644 --- a/lib/src/cli/dart_cli.dart +++ b/lib/src/cli/dart_cli.dart @@ -3,9 +3,11 @@ part of 'cli.dart'; /// Dart CLI class Dart { /// Determine whether dart is installed. - static Future installed() async { + static Future installed({ + required Logger logger, + }) async { try { - await _Cmd.run('dart', ['--version']); + await _Cmd.run('dart', ['--version'], logger: logger); return true; } catch (_) { return false; @@ -16,12 +18,18 @@ class Dart { static Future applyFixes({ String cwd = '.', bool recursive = false, + required Logger logger, }) async { if (!recursive) { final pubspec = File(p.join(cwd, 'pubspec.yaml')); if (!pubspec.existsSync()) throw PubspecNotFound(); - await _Cmd.run('dart', ['fix', '--apply'], workingDirectory: cwd); + await _Cmd.run( + 'dart', + ['fix', '--apply'], + workingDirectory: cwd, + logger: logger, + ); return; } @@ -30,6 +38,7 @@ class Dart { 'dart', ['fix', '--apply'], workingDirectory: entity.parent.path, + logger: logger, ), where: _isPubspec, cwd: cwd, diff --git a/lib/src/cli/flutter_cli.dart b/lib/src/cli/flutter_cli.dart index 2dcdcc63..cda7f55e 100644 --- a/lib/src/cli/flutter_cli.dart +++ b/lib/src/cli/flutter_cli.dart @@ -64,9 +64,11 @@ typedef GeneratorBuilder = Future Function(MasonBundle); /// Flutter CLI class Flutter { /// Determine whether flutter is installed. - static Future installed() async { + static Future installed({ + required Logger logger, + }) async { try { - await _Cmd.run('flutter', ['--version']); + await _Cmd.run('flutter', ['--version'], logger: logger); return true; } catch (_) { return false; @@ -77,18 +79,18 @@ class Flutter { static Future packagesGet({ String cwd = '.', bool recursive = false, - Logger? logger, + required Logger logger, }) async { await _runCommand( cmd: (cwd) async { - final installProgress = logger?.progress( + final installProgress = logger.progress( 'Running "flutter packages get" in $cwd', ); try { - await _verifyGitDependencies(cwd); + await _verifyGitDependencies(cwd, logger: logger); } catch (_) { - installProgress?.fail(); + installProgress.fail(); rethrow; } @@ -97,9 +99,10 @@ class Flutter { 'flutter', ['packages', 'get'], workingDirectory: cwd, + logger: logger, ); } finally { - installProgress?.complete(); + installProgress.complete(); } }, cwd: cwd, @@ -111,12 +114,14 @@ class Flutter { static Future pubGet({ String cwd = '.', bool recursive = false, + required Logger logger, }) async { await _runCommand( cmd: (cwd) => _Cmd.run( 'flutter', ['pub', 'get'], workingDirectory: cwd, + logger: logger, ), cwd: cwd, recursive: recursive, @@ -134,7 +139,7 @@ class Flutter { String? excludeFromCoverage, String? randomSeed, List? arguments, - Logger? logger, + required Logger logger, void Function(String)? stdout, void Function(String)? stderr, FlutterTestRunner testRunner = flutterTest, @@ -171,7 +176,7 @@ class Flutter { } if (optimizePerformance) { - final optimizationProgress = logger?.progress('Optimizing tests'); + final optimizationProgress = logger.progress('Optimizing tests'); try { final generator = await buildGenerator(testRunnerBundle); var vars = {'package-root': workingDirectory}; @@ -186,7 +191,7 @@ class Flutter { fileConflictResolution: FileConflictResolution.overwrite, ); } finally { - optimizationProgress?.complete(); + optimizationProgress.complete(); } } @@ -235,7 +240,10 @@ class Flutter { /// /// If any git dependencies are unreachable, /// an [UnreachableGitDependency] is thrown. -Future _verifyGitDependencies(String cwd) async { +Future _verifyGitDependencies( + String cwd, { + required Logger logger, +}) async { final pubspec = Pubspec.parse( await File(p.join(cwd, 'pubspec.yaml')).readAsString(), ); @@ -254,7 +262,12 @@ Future _verifyGitDependencies(String cwd) async { .toList(); await Future.wait( - gitDependencies.map((dependency) => Git.reachable(dependency.url)), + gitDependencies.map( + (dependency) => Git.reachable( + dependency.url, + logger: logger, + ), + ), ); } diff --git a/lib/src/cli/git_cli.dart b/lib/src/cli/git_cli.dart index 8e5b196d..b62a27d7 100644 --- a/lib/src/cli/git_cli.dart +++ b/lib/src/cli/git_cli.dart @@ -22,9 +22,16 @@ Make sure the remote exists and you have the correct access rights.'''; /// Git CLI class Git { /// Determine whether the [remote] is reachable. - static Future reachable(Uri remote) async { + static Future reachable( + Uri remote, { + required Logger logger, + }) async { try { - await _Cmd.run('git', ['ls-remote', '$remote', '--exit-code']); + await _Cmd.run( + 'git', + ['ls-remote', '$remote', '--exit-code'], + logger: logger, + ); } catch (_) { throw UnreachableGitDependency(remote: remote); } diff --git a/lib/src/command_runner.dart b/lib/src/command_runner.dart index fbf88292..975579fe 100644 --- a/lib/src/command_runner.dart +++ b/lib/src/command_runner.dart @@ -43,11 +43,15 @@ class VeryGoodCommandRunner extends CommandRunner { 'true': 'Enable anonymous usage statistics', 'false': 'Disable anonymous usage statistics', }, + ) + ..addFlag( + 'verbose', + help: 'Noisy logging, including all shell commands executed.', ); - addCommand(CreateCommand(analytics: _analytics, logger: logger)); - addCommand(PackagesCommand(logger: logger)); - addCommand(TestCommand(logger: logger)); - addCommand(UpdateCommand(logger: logger, pubUpdater: pubUpdater)); + addCommand(CreateCommand(analytics: _analytics, logger: _logger)); + addCommand(PackagesCommand(logger: _logger)); + addCommand(TestCommand(logger: _logger)); + addCommand(UpdateCommand(logger: _logger, pubUpdater: pubUpdater)); } /// Standard timeout duration for the CLI. @@ -78,6 +82,9 @@ class VeryGoodCommandRunner extends CommandRunner { normalizedResponse == 'y' || normalizedResponse == 'yes'; } final _argResults = parse(args); + if (_argResults['verbose'] == true) { + _logger.level = Level.verbose; + } return await runCommand(_argResults) ?? ExitCode.success.code; } on FormatException catch (e, stackTrace) { _logger @@ -97,6 +104,30 @@ class VeryGoodCommandRunner extends CommandRunner { @override Future runCommand(ArgResults topLevelResults) async { + _logger + ..detail('Argument information:') + ..detail(' Top level options:'); + for (final option in topLevelResults.options) { + if (topLevelResults.wasParsed(option)) { + _logger.detail(' - $option: ${topLevelResults[option]}'); + } + } + if (topLevelResults.command != null) { + final commandResult = topLevelResults.command!; + _logger + ..detail(' Command: ${commandResult.name}') + ..detail(' Command options:'); + for (final option in commandResult.options) { + if (commandResult.wasParsed(option)) { + _logger.detail(' - $option: ${commandResult[option]}'); + } + } + } + + if (_analytics.enabled) { + _logger.detail('Running with analytics enabled.'); + } + int? exitCode = ExitCode.unavailable.code; if (topLevelResults['version'] == true) { _logger.info(packageVersion); diff --git a/lib/src/commands/create/create.dart b/lib/src/commands/create/create.dart index ce08afa4..b51ad061 100644 --- a/lib/src/commands/create/create.dart +++ b/lib/src/commands/create/create.dart @@ -38,10 +38,10 @@ class CreateCommand extends Command { /// {@macro create_command} CreateCommand({ required Analytics analytics, - Logger? logger, + required Logger logger, GeneratorBuilder? generator, }) : _analytics = analytics, - _logger = logger ?? Logger(), + _logger = logger, _generator = generator ?? MasonGenerator.fromBundle { argParser ..addOption( @@ -216,6 +216,7 @@ class CreateCommand extends Command { } void _validateOrgName(String name) { + _logger.detail('Validating org name; $name'); final isValidOrgName = _isValidOrgName(name); if (!isValidOrgName) { usageException( @@ -230,6 +231,7 @@ class CreateCommand extends Command { } void _validateProjectName(String name) { + _logger.detail('Validating project name; $name'); final isValidProjectName = _isValidPackageName(name); if (!isValidProjectName) { usageException( @@ -255,6 +257,7 @@ class CreateCommand extends Command { } void _validateOutputDirectoryArg(List args) { + _logger.detail('Validating output directory args: $args'); if (args.isEmpty) { usageException('No option specified for the output directory.'); } diff --git a/lib/src/commands/create/templates/post_generate_actions.dart b/lib/src/commands/create/templates/post_generate_actions.dart index 375cd5ab..d193aee0 100644 --- a/lib/src/commands/create/templates/post_generate_actions.dart +++ b/lib/src/commands/create/templates/post_generate_actions.dart @@ -7,12 +7,12 @@ Future installDartPackages( Logger logger, Directory outputDir, ) async { - final isFlutterInstalled = await Flutter.installed(); + final isFlutterInstalled = await Flutter.installed(logger: logger); if (isFlutterInstalled) { final installDependenciesProgress = logger.progress( 'Running "flutter pub get" in ${outputDir.path}', ); - await Flutter.pubGet(cwd: outputDir.path); + await Flutter.pubGet(cwd: outputDir.path, logger: logger); installDependenciesProgress.complete(); } } @@ -23,13 +23,13 @@ Future installFlutterPackages( Directory outputDir, { bool recursive = false, }) async { - final isFlutterInstalled = await Flutter.installed(); + final isFlutterInstalled = await Flutter.installed(logger: logger); if (isFlutterInstalled) { - final installDependenciesProgress = logger.progress( - 'Running "flutter packages get" in ${outputDir.path}', + await Flutter.packagesGet( + cwd: outputDir.path, + recursive: recursive, + logger: logger, ); - await Flutter.packagesGet(cwd: outputDir.path, recursive: recursive); - installDependenciesProgress.complete(); } } @@ -39,12 +39,16 @@ Future applyDartFixes( Directory outputDir, { bool recursive = false, }) async { - final isDartInstalled = await Dart.installed(); + final isDartInstalled = await Dart.installed(logger: logger); if (isDartInstalled) { final applyFixesProgress = logger.progress( 'Running "dart fix --apply" in ${outputDir.path}', ); - await Dart.applyFixes(cwd: outputDir.path, recursive: recursive); + await Dart.applyFixes( + cwd: outputDir.path, + recursive: recursive, + logger: logger, + ); applyFixesProgress.complete(); } } diff --git a/lib/src/commands/packages.dart b/lib/src/commands/packages.dart index 79cf9034..db6c46d2 100644 --- a/lib/src/commands/packages.dart +++ b/lib/src/commands/packages.dart @@ -59,7 +59,7 @@ class PackagesGetCommand extends Command { final recursive = _argResults['recursive'] as bool; final target = _argResults.rest.length == 1 ? _argResults.rest[0] : '.'; final targetPath = path.normalize(Directory(target).absolute.path); - final isFlutterInstalled = await Flutter.installed(); + final isFlutterInstalled = await Flutter.installed(logger: _logger); if (isFlutterInstalled) { try { await Flutter.packagesGet( diff --git a/lib/src/commands/test/test.dart b/lib/src/commands/test/test.dart index cdef878e..72df26e2 100644 --- a/lib/src/commands/test/test.dart +++ b/lib/src/commands/test/test.dart @@ -9,7 +9,9 @@ import 'package:universal_io/io.dart'; import 'package:very_good_cli/src/cli/cli.dart'; /// Signature for the [Flutter.installed] method. -typedef FlutterInstalledCommand = Future Function(); +typedef FlutterInstalledCommand = Future Function({ + required Logger logger, +}); /// Signature for the [Flutter.test] method. typedef FlutterTestCommand = Future> Function({ @@ -21,7 +23,7 @@ typedef FlutterTestCommand = Future> Function({ String? excludeFromCoverage, String? randomSeed, List? arguments, - Logger? logger, + required Logger logger, void Function(String)? stdout, void Function(String)? stderr, }); @@ -32,10 +34,10 @@ typedef FlutterTestCommand = Future> Function({ class TestCommand extends Command { /// {@macro test_command} TestCommand({ - Logger? logger, + required Logger logger, FlutterInstalledCommand? flutterInstalled, FlutterTestCommand? flutterTest, - }) : _logger = logger ?? Logger(), + }) : _logger = logger, _flutterInstalled = flutterInstalled ?? Flutter.installed, _flutterTest = flutterTest ?? Flutter.test { argParser @@ -131,7 +133,7 @@ This command should be run from the root of your Flutter project.''', ); final excludeTags = _argResults['exclude-tags'] as String?; final tags = _argResults['tags'] as String?; - final isFlutterInstalled = await _flutterInstalled(); + final isFlutterInstalled = await _flutterInstalled(logger: _logger); final excludeFromCoverage = _argResults['exclude-coverage'] as String?; final randomOrderingSeed = _argResults['test-randomize-ordering-seed'] as String?; diff --git a/lib/src/commands/update.dart b/lib/src/commands/update.dart index d3f9c238..6687d787 100644 --- a/lib/src/commands/update.dart +++ b/lib/src/commands/update.dart @@ -10,9 +10,9 @@ import 'package:very_good_cli/src/version.dart'; class UpdateCommand extends Command { /// {@macro update_command} UpdateCommand({ - Logger? logger, + required Logger logger, PubUpdater? pubUpdater, - }) : _logger = logger ?? Logger(), + }) : _logger = logger, _pubUpdater = pubUpdater ?? PubUpdater(); final Logger _logger; diff --git a/pubspec.yaml b/pubspec.yaml index 056b0182..ee073e63 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -10,8 +10,8 @@ dependencies: args: ^2.1.0 glob: ^2.0.2 lcov_parser: ^0.1.2 - mason: ">=0.1.0-dev.26 <0.1.0-dev.27" - mason_logger: ">=0.1.0-dev.13 <0.1.0-dev.14" + mason: ">=0.1.0-dev.31 <0.1.0-dev.32" + mason_logger: ^0.1.1 meta: ^1.3.0 path: ^1.8.0 pub_updater: ^0.2.1 diff --git a/test/e2e_test.dart b/test/e2e_test.dart index 97c66d78..54b41882 100644 --- a/test/e2e_test.dart +++ b/test/e2e_test.dart @@ -7,11 +7,11 @@ import 'package:universal_io/io.dart'; import 'package:usage/usage.dart'; import 'package:very_good_cli/src/command_runner.dart'; -class MockAnalytics extends Mock implements Analytics {} +class _MockAnalytics extends Mock implements Analytics {} -class MockLogger extends Mock implements Logger {} +class _MockLogger extends Mock implements Logger {} -class MockProgress extends Mock implements Progress {} +class _MockProgress extends Mock implements Progress {} void main() { group( @@ -32,8 +32,8 @@ void main() { tearDownAll(_removeTemporaryFiles); setUp(() { - analytics = MockAnalytics(); - logger = MockLogger(); + analytics = _MockAnalytics(); + logger = _MockLogger(); when(() => analytics.firstRun).thenReturn(false); when(() => analytics.enabled).thenReturn(false); @@ -44,8 +44,8 @@ void main() { () => analytics.waitForLastPing(timeout: any(named: 'timeout')), ).thenAnswer((_) async {}); - logger = MockLogger(); - progress = MockProgress(); + logger = _MockLogger(); + progress = _MockProgress(); when(() => logger.progress(any())).thenReturn(progress); commandRunner = VeryGoodCommandRunner( diff --git a/test/src/cli/dart_cli_test.dart b/test/src/cli/dart_cli_test.dart index 696e76ef..b9da19aa 100644 --- a/test/src/cli/dart_cli_test.dart +++ b/test/src/cli/dart_cli_test.dart @@ -19,12 +19,22 @@ class _MockProcess extends Mock implements _TestProcess {} class _MockProcessResult extends Mock implements ProcessResult {} +class _MockLogger extends Mock implements Logger {} + +class _MockProgress extends Mock implements Progress {} + void main() { group('Dart', () { late ProcessResult processResult; late _TestProcess process; + late Logger logger; + late Progress progress; setUp(() { + logger = _MockLogger(); + progress = _MockProgress(); + when(() => logger.progress(any())).thenReturn(progress); + processResult = _MockProcessResult(); process = _MockProcess(); when(() => processResult.exitCode).thenReturn(ExitCode.success.code); @@ -41,7 +51,7 @@ void main() { group('.installed', () { test('returns true when dart is installed', () { ProcessOverrides.runZoned( - () => expectLater(Dart.installed(), completion(isTrue)), + () => expectLater(Dart.installed(logger: logger), completion(isTrue)), runProcess: process.run, ); }); @@ -49,7 +59,8 @@ void main() { test('returns false when dart is not installed', () { when(() => processResult.exitCode).thenReturn(ExitCode.software.code); ProcessOverrides.runZoned( - () => expectLater(Dart.installed(), completion(isFalse)), + () => + expectLater(Dart.installed(logger: logger), completion(isFalse)), runProcess: process.run, ); }); @@ -58,7 +69,7 @@ void main() { group('.applyFixes', () { test('completes normally', () { ProcessOverrides.runZoned( - () => expectLater(Dart.applyFixes(), completes), + () => expectLater(Dart.applyFixes(logger: logger), completes), runProcess: process.run, ); }); diff --git a/test/src/cli/flutter_cli_test.dart b/test/src/cli/flutter_cli_test.dart index 3ca72a90..eec8f11c 100644 --- a/test/src/cli/flutter_cli_test.dart +++ b/test/src/cli/flutter_cli_test.dart @@ -60,6 +60,8 @@ void main() { group('Flutter', () { late ProcessResult processResult; late _TestProcess process; + late Logger logger; + late Progress progress; setUpAll(() { registerFallbackValue(_FakeGeneratorTarget()); @@ -67,6 +69,10 @@ void main() { }); setUp(() { + logger = _MockLogger(); + progress = _MockProgress(); + when(() => logger.progress(any())).thenReturn(progress); + processResult = _MockProcessResult(); process = _MockProcess(); when(() => processResult.exitCode).thenReturn(ExitCode.success.code); @@ -84,7 +90,7 @@ void main() { test('throws when there is no pubspec.yaml', () { ProcessOverrides.runZoned( () => expectLater( - Flutter.packagesGet(cwd: Directory.systemTemp.path), + Flutter.packagesGet(cwd: Directory.systemTemp.path, logger: logger), throwsA(isA()), ), runProcess: process.run, @@ -107,7 +113,7 @@ void main() { ProcessOverrides.runZoned( () => expectLater( - Flutter.packagesGet(cwd: Directory.systemTemp.path), + Flutter.packagesGet(cwd: Directory.systemTemp.path, logger: logger), throwsException, ), runProcess: process.run, @@ -134,7 +140,7 @@ void main() { ProcessOverrides.runZoned( () => expectLater( - () => Flutter.packagesGet(cwd: directory.path), + () => Flutter.packagesGet(cwd: directory.path, logger: logger), throwsA(isA()), ), runProcess: process.run, @@ -143,7 +149,7 @@ void main() { test('completes when the process succeeds', () { ProcessOverrides.runZoned( - () => expectLater(Flutter.packagesGet(), completes), + () => expectLater(Flutter.packagesGet(logger: logger), completes), runProcess: process.run, ); }); @@ -154,6 +160,7 @@ void main() { Flutter.packagesGet( cwd: Directory.systemTemp.createTempSync().path, recursive: true, + logger: logger, ), throwsA(isA()), ), @@ -170,7 +177,11 @@ void main() { ProcessOverrides.runZoned( () => expectLater( - Flutter.packagesGet(cwd: directory.path, recursive: true), + Flutter.packagesGet( + cwd: directory.path, + recursive: true, + logger: logger, + ), completes, ), runProcess: process.run, @@ -182,7 +193,7 @@ void main() { test('throws when there is no pubspec.yaml', () { ProcessOverrides.runZoned( () => expectLater( - Flutter.pubGet(cwd: Directory.systemTemp.path), + Flutter.pubGet(cwd: Directory.systemTemp.path, logger: logger), throwsA(isA()), ), runProcess: process.run, @@ -204,7 +215,7 @@ void main() { ).thenAnswer((_) async => flutterProcessResult); ProcessOverrides.runZoned( () => expectLater( - Flutter.pubGet(cwd: Directory.systemTemp.path), + Flutter.pubGet(cwd: Directory.systemTemp.path, logger: logger), throwsException, ), runProcess: process.run, @@ -213,14 +224,17 @@ void main() { test('completes when the process succeeds', () { ProcessOverrides.runZoned( - () => expectLater(Flutter.pubGet(), completes), + () => expectLater(Flutter.pubGet(logger: logger), completes), runProcess: process.run, ); }); test('completes when the process succeeds (recursive)', () { ProcessOverrides.runZoned( - () => expectLater(Flutter.pubGet(recursive: true), completes), + () => expectLater( + Flutter.pubGet(recursive: true, logger: logger), + completes, + ), runProcess: process.run, ); }); @@ -228,7 +242,7 @@ void main() { test('throws when process fails', () { when(() => processResult.exitCode).thenReturn(ExitCode.software.code); ProcessOverrides.runZoned( - () => expectLater(Flutter.pubGet(), throwsException), + () => expectLater(Flutter.pubGet(logger: logger), throwsException), runProcess: process.run, ); }); @@ -236,7 +250,10 @@ void main() { test('throws when process fails (recursive)', () { when(() => processResult.exitCode).thenReturn(ExitCode.software.code); ProcessOverrides.runZoned( - () => expectLater(Flutter.pubGet(recursive: true), throwsException), + () => expectLater( + Flutter.pubGet(recursive: true, logger: logger), + throwsException, + ), runProcess: process.run, ); }); @@ -297,7 +314,7 @@ void main() { test('throws when pubspec not found', () async { await expectLater( - () => Flutter.test(cwd: Directory.systemTemp.path), + () => Flutter.test(cwd: Directory.systemTemp.path, logger: logger), throwsA(isA()), ); }); @@ -310,6 +327,7 @@ void main() { cwd: directory.path, stdout: stdoutLogs.add, stderr: stderrLogs.add, + logger: logger, ), completion(equals([ExitCode.success.code])), ); @@ -335,6 +353,7 @@ void main() { stdout: stdoutLogs.add, stderr: stderrLogs.add, testRunner: testRunner(controller.stream), + logger: logger, ), ); @@ -372,6 +391,7 @@ void main() { const ExitTestEvent(exitCode: 0, time: 0), ]), ), + logger: logger, ), completion(equals([ExitCode.success.code])), ); @@ -409,6 +429,7 @@ void main() { const ExitTestEvent(exitCode: 1, time: 0), ]), ), + logger: logger, ), completion(equals([ExitCode.unavailable.code])), ); @@ -460,6 +481,7 @@ void main() { const ExitTestEvent(exitCode: 0, time: 0), ]), ), + logger: logger, ), completion(equals([ExitCode.success.code])), ); @@ -527,6 +549,7 @@ void main() { stdout: stdoutLogs.add, stderr: stderrLogs.add, testRunner: testRunner(controller.stream), + logger: logger, ), completion(equals([ExitCode.unavailable.code])), ); @@ -558,6 +581,7 @@ void main() { const ExitTestEvent(exitCode: 1, time: 0), ]), ), + logger: logger, ), completion(equals([ExitCode.unavailable.code])), ); @@ -588,6 +612,7 @@ void main() { ], ), ), + logger: logger, ), completion(equals([ExitCode.success.code])), ); @@ -613,6 +638,7 @@ void main() { ], ), ), + logger: logger, ), completion(equals([ExitCode.success.code])), ); @@ -646,6 +672,7 @@ void main() { ], ), ), + logger: logger, ), completion(equals([ExitCode.success.code])), ); @@ -689,6 +716,7 @@ void main() { lcovFile.createSync(recursive: true); }, ), + logger: logger, ), completion(equals([ExitCode.success.code])), ); @@ -728,6 +756,7 @@ void main() { ..writeAsStringSync(lcov100); }, ), + logger: logger, ), completion(equals([ExitCode.success.code])), ); @@ -767,6 +796,7 @@ void main() { ..writeAsStringSync(lcov95); }, ), + logger: logger, ), throwsA( isA().having( @@ -816,6 +846,7 @@ void main() { ..writeAsStringSync(lcov95); }, ), + logger: logger, ), completion(equals([ExitCode.success.code])), ); diff --git a/test/src/cli/git_cli_test.dart b/test/src/cli/git_cli_test.dart index d1c14c28..5000567e 100644 --- a/test/src/cli/git_cli_test.dart +++ b/test/src/cli/git_cli_test.dart @@ -19,12 +19,22 @@ class _MockProcess extends Mock implements _TestProcess {} class _MockProcessResult extends Mock implements ProcessResult {} +class _MockLogger extends Mock implements Logger {} + +class _MockProgress extends Mock implements Progress {} + void main() { group('Git', () { late ProcessResult processResult; late _TestProcess process; + late Logger logger; + late Progress progress; setUp(() { + logger = _MockLogger(); + progress = _MockProgress(); + when(() => logger.progress(any())).thenReturn(progress); + processResult = _MockProcessResult(); process = _MockProcess(); when(() => processResult.exitCode).thenReturn(ExitCode.success.code); @@ -43,7 +53,10 @@ void main() { await ProcessOverrides.runZoned( () async { await expectLater( - Git.reachable(Uri.parse('https://github.com/org/repo')), + Git.reachable( + Uri.parse('https://github.com/org/repo'), + logger: logger, + ), completes, ); }, @@ -58,7 +71,10 @@ void main() { await ProcessOverrides.runZoned( () async { await expectLater( - Git.reachable(Uri.parse('https://github.com/org/repo')), + Git.reachable( + Uri.parse('https://github.com/org/repo'), + logger: logger, + ), throwsA(isA()), ); }, diff --git a/test/src/command_runner_test.dart b/test/src/command_runner_test.dart index c0b7ff90..d36c1aa6 100644 --- a/test/src/command_runner_test.dart +++ b/test/src/command_runner_test.dart @@ -22,12 +22,14 @@ const expectedUsage = [ 'Usage: very_good [arguments]\n' '\n' 'Global options:\n' - '-h, --help Print this usage information.\n' - ' --version Print the current version.\n' - ' --analytics Toggle anonymous usage statistics.\n' + '-h, --help Print this usage information.\n' + ' --version Print the current version.\n' + ' --analytics Toggle anonymous usage statistics.\n' '\n' - ' [false] Disable anonymous usage statistics\n' - ' [true] Enable anonymous usage statistics\n' + ' [false] Disable anonymous usage statistics\n' + ' [true] Enable anonymous usage statistics\n' + '\n' + ''' --[no-]verbose Noisy logging, including all shell commands executed.\n''' '\n' 'Available commands:\n' ' create very_good create \n' @@ -225,6 +227,44 @@ void main() { verify(() => logger.info(packageVersion)).called(1); }); }); + + group('--verbose', () { + test('enables verbose logging', () async { + final result = await commandRunner.run(['--verbose']); + expect(result, equals(ExitCode.success.code)); + + verify(() => logger.detail('Argument information:')).called(1); + verify(() => logger.detail(' Top level options:')).called(1); + verify(() => logger.detail(' - verbose: true')).called(1); + verifyNever(() => logger.detail(' Command options:')); + }); + + test('logs that analytics is enabled', () async { + when(() => analytics.enabled).thenReturn(true); + final result = await commandRunner.run(['--verbose']); + expect(result, equals(ExitCode.success.code)); + verify( + () => logger.detail('Running with analytics enabled.'), + ).called(1); + }); + + test('enables verbose logging for sub commands', () async { + final result = await commandRunner.run([ + '--verbose', + 'create', + '-t', + 'dart_pkg', + ]); + expect(result, equals(ExitCode.usage.code)); + + verify(() => logger.detail('Argument information:')).called(1); + verify(() => logger.detail(' Top level options:')).called(1); + verify(() => logger.detail(' - verbose: true')).called(1); + verify(() => logger.detail(' Command: create')).called(1); + verify(() => logger.detail(' Command options:')).called(1); + verify(() => logger.detail(' - template: dart_pkg')).called(1); + }); + }); }); }); } diff --git a/test/src/commands/create/create_test.dart b/test/src/commands/create/create_test.dart index b1c5ca79..e66f09bb 100644 --- a/test/src/commands/create/create_test.dart +++ b/test/src/commands/create/create_test.dart @@ -130,7 +130,7 @@ void main() { ); test('can be instantiated without explicit logger', () { - final command = CreateCommand(analytics: analytics); + final command = CreateCommand(analytics: analytics, logger: logger); expect(command, isNotNull); }); diff --git a/test/src/commands/test/test_test.dart b/test/src/commands/test/test_test.dart index 533ca6c2..f5cda0ad 100644 --- a/test/src/commands/test/test_test.dart +++ b/test/src/commands/test/test_test.dart @@ -75,7 +75,8 @@ void main() { flutterTest = MockFlutterTestCommand(); testCommand = TestCommand( logger: logger, - flutterInstalled: () async => isFlutterInstalled, + flutterInstalled: ({required Logger logger}) async => + isFlutterInstalled, flutterTest: flutterTest.call, )..argResultOverrides = argResults; when(