Skip to content

Commit

Permalink
feat: add --verbose flag (#465)
Browse files Browse the repository at this point in the history
Co-authored-by: Felix Angelov <felangelov@gmail.com>
  • Loading branch information
wolfenrain and felangel committed Jul 28, 2022
1 parent ca66c60 commit d2a62fa
Show file tree
Hide file tree
Showing 18 changed files with 246 additions and 73 deletions.
5 changes: 5 additions & 0 deletions lib/src/cli/cli.dart
Expand Up @@ -78,14 +78,19 @@ class _Cmd {
List<String> 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,
args,
workingDirectory: workingDirectory,
runInShell: true,
);
logger
..detail('stdout:\n${result.stdout}')
..detail('stderr:\n${result.stderr}');

if (throwOnError) {
_throwIfProcessFailed(result, cmd, args);
Expand Down
15 changes: 12 additions & 3 deletions lib/src/cli/dart_cli.dart
Expand Up @@ -3,9 +3,11 @@ part of 'cli.dart';
/// Dart CLI
class Dart {
/// Determine whether dart is installed.
static Future<bool> installed() async {
static Future<bool> installed({
required Logger logger,
}) async {
try {
await _Cmd.run('dart', ['--version']);
await _Cmd.run('dart', ['--version'], logger: logger);
return true;
} catch (_) {
return false;
Expand All @@ -16,12 +18,18 @@ class Dart {
static Future<void> 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;
}

Expand All @@ -30,6 +38,7 @@ class Dart {
'dart',
['fix', '--apply'],
workingDirectory: entity.parent.path,
logger: logger,
),
where: _isPubspec,
cwd: cwd,
Expand Down
37 changes: 25 additions & 12 deletions lib/src/cli/flutter_cli.dart
Expand Up @@ -64,9 +64,11 @@ typedef GeneratorBuilder = Future<MasonGenerator> Function(MasonBundle);
/// Flutter CLI
class Flutter {
/// Determine whether flutter is installed.
static Future<bool> installed() async {
static Future<bool> installed({
required Logger logger,
}) async {
try {
await _Cmd.run('flutter', ['--version']);
await _Cmd.run('flutter', ['--version'], logger: logger);
return true;
} catch (_) {
return false;
Expand All @@ -77,18 +79,18 @@ class Flutter {
static Future<void> 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;
}

Expand All @@ -97,9 +99,10 @@ class Flutter {
'flutter',
['packages', 'get'],
workingDirectory: cwd,
logger: logger,
);
} finally {
installProgress?.complete();
installProgress.complete();
}
},
cwd: cwd,
Expand All @@ -111,12 +114,14 @@ class Flutter {
static Future<void> 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,
Expand All @@ -134,7 +139,7 @@ class Flutter {
String? excludeFromCoverage,
String? randomSeed,
List<String>? arguments,
Logger? logger,
required Logger logger,
void Function(String)? stdout,
void Function(String)? stderr,
FlutterTestRunner testRunner = flutterTest,
Expand Down Expand Up @@ -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 = <String, dynamic>{'package-root': workingDirectory};
Expand All @@ -186,7 +191,7 @@ class Flutter {
fileConflictResolution: FileConflictResolution.overwrite,
);
} finally {
optimizationProgress?.complete();
optimizationProgress.complete();
}
}

Expand Down Expand Up @@ -235,7 +240,10 @@ class Flutter {
///
/// If any git dependencies are unreachable,
/// an [UnreachableGitDependency] is thrown.
Future<void> _verifyGitDependencies(String cwd) async {
Future<void> _verifyGitDependencies(
String cwd, {
required Logger logger,
}) async {
final pubspec = Pubspec.parse(
await File(p.join(cwd, 'pubspec.yaml')).readAsString(),
);
Expand All @@ -254,7 +262,12 @@ Future<void> _verifyGitDependencies(String cwd) async {
.toList();

await Future.wait(
gitDependencies.map((dependency) => Git.reachable(dependency.url)),
gitDependencies.map(
(dependency) => Git.reachable(
dependency.url,
logger: logger,
),
),
);
}

Expand Down
11 changes: 9 additions & 2 deletions lib/src/cli/git_cli.dart
Expand Up @@ -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<void> reachable(Uri remote) async {
static Future<void> 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);
}
Expand Down
39 changes: 35 additions & 4 deletions lib/src/command_runner.dart
Expand Up @@ -43,11 +43,15 @@ class VeryGoodCommandRunner extends CommandRunner<int> {
'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.
Expand Down Expand Up @@ -78,6 +82,9 @@ class VeryGoodCommandRunner extends CommandRunner<int> {
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
Expand All @@ -97,6 +104,30 @@ class VeryGoodCommandRunner extends CommandRunner<int> {

@override
Future<int?> 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);
Expand Down
7 changes: 5 additions & 2 deletions lib/src/commands/create/create.dart
Expand Up @@ -38,10 +38,10 @@ class CreateCommand extends Command<int> {
/// {@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(
Expand Down Expand Up @@ -216,6 +216,7 @@ class CreateCommand extends Command<int> {
}

void _validateOrgName(String name) {
_logger.detail('Validating org name; $name');
final isValidOrgName = _isValidOrgName(name);
if (!isValidOrgName) {
usageException(
Expand All @@ -230,6 +231,7 @@ class CreateCommand extends Command<int> {
}

void _validateProjectName(String name) {
_logger.detail('Validating project name; $name');
final isValidProjectName = _isValidPackageName(name);
if (!isValidProjectName) {
usageException(
Expand All @@ -255,6 +257,7 @@ class CreateCommand extends Command<int> {
}

void _validateOutputDirectoryArg(List<String> args) {
_logger.detail('Validating output directory args: $args');
if (args.isEmpty) {
usageException('No option specified for the output directory.');
}
Expand Down
22 changes: 13 additions & 9 deletions lib/src/commands/create/templates/post_generate_actions.dart
Expand Up @@ -7,12 +7,12 @@ Future<void> 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();
}
}
Expand All @@ -23,13 +23,13 @@ Future<void> 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();
}
}

Expand All @@ -39,12 +39,16 @@ Future<void> 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();
}
}
2 changes: 1 addition & 1 deletion lib/src/commands/packages.dart
Expand Up @@ -59,7 +59,7 @@ class PackagesGetCommand extends Command<int> {
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(
Expand Down
12 changes: 7 additions & 5 deletions lib/src/commands/test/test.dart
Expand Up @@ -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<bool> Function();
typedef FlutterInstalledCommand = Future<bool> Function({
required Logger logger,
});

/// Signature for the [Flutter.test] method.
typedef FlutterTestCommand = Future<List<int>> Function({
Expand All @@ -21,7 +23,7 @@ typedef FlutterTestCommand = Future<List<int>> Function({
String? excludeFromCoverage,
String? randomSeed,
List<String>? arguments,
Logger? logger,
required Logger logger,
void Function(String)? stdout,
void Function(String)? stderr,
});
Expand All @@ -32,10 +34,10 @@ typedef FlutterTestCommand = Future<List<int>> Function({
class TestCommand extends Command<int> {
/// {@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
Expand Down Expand Up @@ -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?;
Expand Down

0 comments on commit d2a62fa

Please sign in to comment.