From 62c9ef14157b26a652f3bf5b034e994eced3937c Mon Sep 17 00:00:00 2001 From: Renan Araujo Date: Fri, 6 Jan 2023 12:36:07 +0000 Subject: [PATCH] feat: create dart package new usage --- .../commands/create/commands/commands.dart | 1 + .../create/commands/create_subcommand.dart | 19 ++ .../create/commands/dart_package.dart | 35 +++ lib/src/commands/create/create.dart | 10 + .../commands/create/commands/legacy_test.dart | 3 +- .../create/create_subcommand_test.dart | 235 ++++++++++++++++++ test/src/commands/create/create_test.dart | 3 +- 7 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 lib/src/commands/create/commands/dart_package.dart diff --git a/lib/src/commands/create/commands/commands.dart b/lib/src/commands/create/commands/commands.dart index 608f7b6b8..8a550abb9 100644 --- a/lib/src/commands/create/commands/commands.dart +++ b/lib/src/commands/create/commands/commands.dart @@ -1,3 +1,4 @@ export 'create_subcommand.dart'; +export 'dart_package.dart'; export 'flutter_app.dart'; export 'legacy.dart'; diff --git a/lib/src/commands/create/commands/create_subcommand.dart b/lib/src/commands/create/commands/create_subcommand.dart index aee9e6872..d0865a52d 100644 --- a/lib/src/commands/create/commands/create_subcommand.dart +++ b/lib/src/commands/create/commands/create_subcommand.dart @@ -97,6 +97,14 @@ abstract class CreateSubCommand extends Command { aliases: ['org'], ); } + + if (this is Publishable) { + argParser.addFlag( + 'publishable', + negatable: false, + help: 'Whether the generated project is intended to be published.', + ); + } } final Analytics _analytics; @@ -236,6 +244,7 @@ abstract class CreateSubCommand extends Command { 'project_name': projectName, 'description': projectDescription, if (this is OrgName) 'org_name': (this as OrgName).orgName, + if (this is Publishable) 'publishable': (this as Publishable).publishable, }; } } @@ -298,3 +307,13 @@ mixin MultiTemplates on CreateSubCommand { ); } } + +/// Mixin for [CreateSubCommand] subclasses that receives the publishable +/// flag. +/// +/// Takes care of parsing it from [argResults] and pass it +/// to the brick generator. +mixin Publishable on CreateSubCommand { + /// Gets the publishable flag. + bool get publishable => argResults['publishable'] as bool? ?? false; +} diff --git a/lib/src/commands/create/commands/dart_package.dart b/lib/src/commands/create/commands/dart_package.dart new file mode 100644 index 000000000..e46a25cea --- /dev/null +++ b/lib/src/commands/create/commands/dart_package.dart @@ -0,0 +1,35 @@ +import 'package:mason_logger/mason_logger.dart'; +import 'package:usage/usage.dart'; +import 'package:very_good_cli/src/commands/create/create_subcommand.dart'; +import 'package:very_good_cli/src/commands/create/templates/templates.dart'; + +/// {@template very_good_create_dart_package_command} +/// A [CreateSubCommand] for creating Dart packages. +/// {@endtemplate} +class CreateDartPackage extends CreateSubCommand with Publishable { + /// {@macro very_good_create_dart_package_command} + CreateDartPackage({ + required Analytics analytics, + required Logger logger, + required MasonGeneratorFromBundle? generatorFromBundle, + required MasonGeneratorFromBrick? generatorFromBrick, + }) : super( + analytics: analytics, + logger: logger, + generatorFromBundle: generatorFromBundle, + generatorFromBrick: generatorFromBrick, + ); + + @override + String get name => 'dart_package'; + + @override + List get aliases => ['dart_pkg']; + + @override + String get description => + 'Creates a new very good Dart package in the specified directory.'; + + @override + Template get template => DartPkgTemplate(); +} diff --git a/lib/src/commands/create/create.dart b/lib/src/commands/create/create.dart index c3990bb6e..ee7425359 100644 --- a/lib/src/commands/create/create.dart +++ b/lib/src/commands/create/create.dart @@ -38,6 +38,16 @@ class CreateCommand extends Command { generatorFromBrick: generatorFromBrick, ), ); + + // very_good create dart_pkg + addSubcommand( + CreateDartPackage( + analytics: analytics, + logger: logger, + generatorFromBundle: generatorFromBundle, + generatorFromBrick: generatorFromBrick, + ), + ); } @override diff --git a/test/src/commands/create/commands/legacy_test.dart b/test/src/commands/create/commands/legacy_test.dart index 9ac2cabd0..cd3f7779e 100644 --- a/test/src/commands/create/commands/legacy_test.dart +++ b/test/src/commands/create/commands/legacy_test.dart @@ -23,7 +23,8 @@ Usage: very_good create [arguments] -h, --help Print this usage information. Available subcommands: - flutter_app Creates a new very good Flutter app in the specified directory. + dart_package Creates a new very good Dart package in the specified directory. + flutter_app Creates a new very good Flutter app in the specified directory. Run "very_good help" to see global options.''' ]; diff --git a/test/src/commands/create/create_subcommand_test.dart b/test/src/commands/create/create_subcommand_test.dart index 273489bbc..faa180537 100644 --- a/test/src/commands/create/create_subcommand_test.dart +++ b/test/src/commands/create/create_subcommand_test.dart @@ -71,6 +71,23 @@ class _TestCreateSubCommandWithOrgName extends _TestCreateSubCommand ); } +class _TestCreateSubCommandWithPublishable extends _TestCreateSubCommand + with Publishable { + _TestCreateSubCommandWithPublishable({ + required Template template, + required Analytics analytics, + required Logger logger, + required MasonGeneratorFromBundle? generatorFromBundle, + required MasonGeneratorFromBrick? generatorFromBrick, + }) : super( + template: template, + analytics: analytics, + logger: logger, + generatorFromBundle: generatorFromBundle, + generatorFromBrick: generatorFromBrick, + ); +} + class _TestCreateSubCommandMultiTemplate extends CreateSubCommand with MultiTemplates { _TestCreateSubCommandMultiTemplate({ @@ -1082,4 +1099,222 @@ Run "runner help" to see global options.'''; }); }); }); + + group('Publishable', () { + const expectedUsage = ''' +Usage: very_good create create_subcommand [arguments] +-h, --help Print this usage information. +-o, --output-directory The desired output directory when creating a new project. + --description The description for this new project. + (defaults to "A Very Good Project created by Very Good CLI.") + --publishable Whether the generated project is intended to be published. + +Run "runner help" to see global options.'''; + + late Template template; + late MockBundle bundle; + + setUp(() { + bundle = MockBundle(); + when(() => bundle.name).thenReturn('test'); + when(() => bundle.description).thenReturn('Test bundle'); + when(() => bundle.version).thenReturn(''); + template = MockTemplate(); + when(() => template.name).thenReturn('test'); + when(() => template.bundle).thenReturn(bundle); + when(() => template.onGenerateComplete(any(), any())).thenAnswer( + (_) async {}, + ); + when( + () => analytics.sendEvent(any(), any(), label: any(named: 'label')), + ).thenAnswer((_) async {}); + }); + + group('can be instantiated', () { + test('with default options', () { + final command = _TestCreateSubCommandWithPublishable( + template: template, + analytics: analytics, + logger: logger, + generatorFromBundle: null, + generatorFromBrick: null, + ); + + expect( + command.argParser.options['publishable'], + isA