From e1e59c7c2ebd127ccefc7b7c6ca74d2fa4f2cd45 Mon Sep 17 00:00:00 2001 From: Marvin Willms <54174311+marvin-kolja@users.noreply.github.com> Date: Wed, 31 Jan 2024 03:13:59 +0100 Subject: [PATCH] add!: proper sub commands for bump and log commands (#70) --- lib/src/cli/cider_cli.dart | 3 ++ lib/src/cli/command/bump_command.dart | 51 +++++++++++------------ lib/src/cli/command/bump_sub_command.dart | 37 ++++++++++++++++ lib/src/cli/command/cider_command.dart | 3 ++ lib/src/cli/command/log_command.dart | 27 ++++++++++-- lib/src/cli/command/log_sub_command.dart | 24 +++++++++++ test/functional_test.dart | 30 +++++++++++-- test/subcommands_usage.expect.dart | 10 +++++ 8 files changed, 152 insertions(+), 33 deletions(-) create mode 100644 lib/src/cli/command/bump_sub_command.dart create mode 100644 lib/src/cli/command/log_sub_command.dart create mode 100644 test/subcommands_usage.expect.dart diff --git a/lib/src/cli/cider_cli.dart b/lib/src/cli/cider_cli.dart index 6186936..6dd81e7 100644 --- a/lib/src/cli/cider_cli.dart +++ b/lib/src/cli/cider_cli.dart @@ -33,4 +33,7 @@ class CiderCli extends CommandRunner { @override Future run(Iterable args) => ErrorInterceptor(console).run(() => super.run(args)); + + @override + void printUsage() => console.out.writeln(usage); } diff --git a/lib/src/cli/command/bump_command.dart b/lib/src/cli/command/bump_command.dart index a6e06b6..fc9e196 100644 --- a/lib/src/cli/command/bump_command.dart +++ b/lib/src/cli/command/bump_command.dart @@ -1,29 +1,33 @@ +import 'package:args/command_runner.dart'; import 'package:cider/src/project.dart'; +import 'package:cider/src/cli/command/bump_sub_command.dart'; import 'package:cider/src/cli/command/cider_command.dart'; import 'package:version_manipulation/mutations.dart'; +enum BumpType { + breaking(BumpBreaking(), 'Bump the breaking version'), + major(BumpMajor(), 'Bump the major version'), + minor(BumpMinor(), 'Bump the minor version'), + patch(BumpPatch(), 'Bump the patch version'), + build(BumpBuild(), 'Bump the build version'), + pre(BumpPreRelease(), 'Bump the pre-release version'), + release(Release(), 'Bump the release version'); + + const BumpType(this.mutation, this.description); + + final VersionMutation mutation; + final String description; +} + class BumpCommand extends CiderCommand { BumpCommand(super.printer) { - mutations.keys.forEach(argParser.addCommand); - argParser - ..addFlag('keep-build', help: 'Keep the existing build') - ..addFlag('bump-build', help: 'Also bump the build') - ..addOption('build', - help: 'Sets the build to the given value', defaultsTo: '') - ..addOption('pre', - help: 'Sets the pre-release to the given value', defaultsTo: ''); + for (final type in BumpType.values) { + addSubcommand( + BumpSubCommand(type.name, type.description, type.mutation, printer), + ); + } } - static const mutations = { - 'breaking': BumpBreaking(), - 'build': BumpBuild(), - 'major': BumpMajor(), - 'minor': BumpMinor(), - 'patch': BumpPatch(), - 'pre': BumpPreRelease(), - 'release': Release(), - }; - @override final name = 'bump'; @override @@ -31,14 +35,7 @@ class BumpCommand extends CiderCommand { @override Future exec(Project project) async { - final part = argResults!.command?.name ?? - (throw ArgumentError('Version part must be specified')); - final result = await project.bumpVersion(mutations[part]!, - keepBuild: argResults!['keep-build'], - bumpBuild: argResults!['bump-build'], - build: argResults!['build'], - pre: argResults!['pre']); - printer.out.writeln(result); - return 0; + throw UsageException( + 'Bump command can only be used with subcommands', usage); } } diff --git a/lib/src/cli/command/bump_sub_command.dart b/lib/src/cli/command/bump_sub_command.dart new file mode 100644 index 0000000..6058ef3 --- /dev/null +++ b/lib/src/cli/command/bump_sub_command.dart @@ -0,0 +1,37 @@ +import 'package:cider/src/cli/console.dart'; +import 'package:cider/src/project.dart'; +import 'package:cider/src/cli/command/cider_command.dart'; +import 'package:version_manipulation/mutations.dart'; + +class BumpSubCommand extends CiderCommand { + BumpSubCommand(this.name, this.description, this.mutation, Console printer) + : super(printer) { + argParser + ..addFlag('keep-build', help: 'Keep the existing build') + ..addFlag('bump-build', help: 'Also bump the build') + ..addOption('build', + help: 'Sets the build to the given value', defaultsTo: '') + ..addOption('pre', + help: 'Sets the pre-release to the given value', defaultsTo: ''); + } + + @override + final String name; + + @override + final String description; + + final VersionMutation mutation; + + @override + Future exec(Project project) async { + final result = await project.bumpVersion(mutation, + keepBuild: argResults!['keep-build'], + bumpBuild: argResults!['bump-build'], + build: argResults!['build'], + pre: argResults!['pre']); + printer.out.writeln(result); + + return 0; + } +} diff --git a/lib/src/cli/command/cider_command.dart b/lib/src/cli/command/cider_command.dart index 158ed37..475a856 100644 --- a/lib/src/cli/command/cider_command.dart +++ b/lib/src/cli/command/cider_command.dart @@ -39,6 +39,9 @@ abstract class CiderCommand extends Command { tagTemplate: tagTemplate, keepEmptyUnreleased: keepEmptyUnreleased); } + + @override + printUsage() => printer.out.writeln(usage); } extension _Map on Map { diff --git a/lib/src/cli/command/log_command.dart b/lib/src/cli/command/log_command.dart index 13ed894..f0ace2d 100644 --- a/lib/src/cli/command/log_command.dart +++ b/lib/src/cli/command/log_command.dart @@ -1,8 +1,29 @@ +import 'package:args/command_runner.dart'; import 'package:cider/src/cli/command/cider_command.dart'; +import 'package:cider/src/cli/command/log_sub_command.dart'; import 'package:cider/src/project.dart'; +enum LogType { + fix('Add a new bug fix to the changelog'), + add('Add a new feature to the changelog'), + change('Add a new change to the changelog'), + deprecate('Add a new deprecation to the changelog'), + remove('Add a new removal to the changelog'), + security('Add a new security fix to the changelog'); + + const LogType(this.description); + + final String description; +} + class LogCommand extends CiderCommand { - LogCommand(super.printer); + LogCommand(super.printer) { + for (final type in LogType.values) { + addSubcommand( + LogSubCommand(type.name, type.description, type, printer), + ); + } + } @override final name = 'log'; @@ -12,7 +33,7 @@ class LogCommand extends CiderCommand { @override Future exec(Project project) async { - await project.addUnreleased(argResults!.rest.first, argResults!.rest[1]); - return 0; + throw UsageException( + 'Log command can only be used with subcommands', usage); } } diff --git a/lib/src/cli/command/log_sub_command.dart b/lib/src/cli/command/log_sub_command.dart new file mode 100644 index 0000000..a83a7e9 --- /dev/null +++ b/lib/src/cli/command/log_sub_command.dart @@ -0,0 +1,24 @@ +import 'package:cider/src/cli/command/log_command.dart'; +import 'package:cider/src/cli/console.dart'; +import 'package:cider/src/project.dart'; +import 'package:cider/src/cli/command/cider_command.dart'; + +class LogSubCommand extends CiderCommand { + LogSubCommand(this.name, this.description, this.type, Console printer) + : super(printer); + + @override + final String name; + + @override + final String description; + + final LogType type; + + @override + Future exec(Project project) async { + await project.addUnreleased(type.name, argResults!.rest.first); + + return 0; + } +} diff --git a/test/functional_test.dart b/test/functional_test.dart index 9a374e9..7174222 100644 --- a/test/functional_test.dart +++ b/test/functional_test.dart @@ -7,6 +7,8 @@ import 'package:path/path.dart' as path; import 'package:pubspec_parse/pubspec_parse.dart'; import 'package:test/test.dart'; +import 'subcommands_usage.expect.dart'; + void main() { late Directory temp; final out = BufferChannel(); @@ -232,14 +234,36 @@ I love my dog. expect(err.buffer.toString().trim(), 'The next version must be higher than the current one.'); }); - test('version part must be specified', () async { + test('incorrect usage', () async { final code = await run(['bump']); - expect(code, 65); - expect(err.buffer.toString().trim(), 'Version part must be specified'); + expect(code, 64); + expect(err.buffer.toString().trim().split('\n').first, + 'Usage: cider bump [arguments]'); + }); + test('help usage', () async { + final code = await run(['bump', '--help']); + expect(code, 0); + expect(err.buffer.toString(), isEmpty); + expectSubcommandsUsage(out.buffer.toString(), command: 'bump'); }); }); }); + group('Log', () { + test('incorrect usage', () async { + final code = await run(['log']); + expect(code, 64); + expect(err.buffer.toString().trim().split('\n').first, + 'Usage: cider log [arguments]'); + }); + test('help usage', () async { + final code = await run(['log', '--help']); + expect(code, 0); + expect(err.buffer.toString(), isEmpty); + expectSubcommandsUsage(out.buffer.toString(), command: 'log'); + }); + }); + group('Find Root', () { test('valid root', () async { final code = await cli.run(['version']); diff --git a/test/subcommands_usage.expect.dart b/test/subcommands_usage.expect.dart new file mode 100644 index 0000000..3e0cdd1 --- /dev/null +++ b/test/subcommands_usage.expect.dart @@ -0,0 +1,10 @@ +import 'package:test/test.dart'; + +void expectSubcommandsUsage(String output, {String? command}) { + if (command != null) { + expect(output, contains('Usage: cider $command [arguments]')); + } + expect(output, contains('-h, --help Print this usage information.')); + expect(output, contains('Available subcommands:')); + expect(output, contains('Run "cider help" to see global options.')); +}