Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/src/better_command_runner/better_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ import 'package:args/command_runner.dart';
import 'package:cli_tools/better_command_runner.dart';

abstract class BetterCommand extends Command {
final PassMessage? _logInfo;
final MessageOutput? _passOutput;
final ArgParser _argParser;

BetterCommand({PassMessage? logInfo, int? wrapTextColumn})
: _logInfo = logInfo,
BetterCommand({MessageOutput? passOutput, int? wrapTextColumn})
: _passOutput = passOutput,
_argParser = ArgParser(usageLineLength: wrapTextColumn);

@override
ArgParser get argParser => _argParser;

@override
void printUsage() {
_logInfo?.call(usage);
_passOutput?.logUsage(usage);
}
}
60 changes: 40 additions & 20 deletions lib/src/better_command_runner/better_command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,32 @@ import 'package:args/command_runner.dart';
/// A function type for executing code before running a command.
typedef OnBeforeRunCommand = Future<void> Function(BetterCommandRunner runner);

/// A function type for passing log messages.
typedef PassMessage = void Function(String message);
/// A proxy for user-provided functions for passing specific log messages.
///
/// It is valid to not provide a function in order to not pass that output.
final class MessageOutput {
final void Function(UsageException exception)? _logUsageException;

final void Function(String usage)? _logUsage;

MessageOutput({
void Function(UsageException exception)? logUsageException,
void Function(String usage)? logUsage,
}) : _logUsageException = logUsageException,
_logUsage = logUsage;

/// Logs a usage exception.
/// If the function has not been provided then nothing will happen.
void logUsageException(UsageException exception) {
_logUsageException?.call(exception);
}

/// Logs a usage message.
/// If the function has not been provided then nothing will happen.
void logUsage(String usage) {
_logUsage?.call(usage);
}
}

/// A function type for setting the log level.
/// The [logLevel] is the log level to set.
Expand All @@ -34,8 +58,7 @@ class BetterCommandRunner extends CommandRunner {
/// The specified command was not found or couldn't be located.
static const int exitCodeCommandNotFound = 127;

final PassMessage? _logError;
final PassMessage? _logInfo;
final MessageOutput? _messageOutput;
final SetLogLevel? _setLogLevel;
final OnBeforeRunCommand? _onBeforeRunCommand;
OnAnalyticsEvent? _onAnalyticsEvent;
Expand All @@ -44,27 +67,24 @@ class BetterCommandRunner extends CommandRunner {

/// Creates a new instance of [BetterCommandRunner].
///
/// The [executableName] is the name of the executable for the command line interface.
/// The [description] is a description of the command line interface.
/// The [logError] function is used to pass error log messages.
/// The [logInfo] function is used to pass informational log messages.
/// The [setLogLevel] function is used to set the log level.
/// The [onBeforeRunCommand] function is executed before running a command.
/// The [onAnalyticsEvent] function is used to track events.
/// The [wrapTextColumn] is the column width for wrapping text in the command line interface.
/// - [executableName] is the name of the executable for the command line interface.
/// - [description] is a description of the command line interface.
/// - [messageOutput] is an optional [MessageOutput] object used to pass specific log messages.
/// - [setLogLevel] function is used to set the log level.
/// - [onBeforeRunCommand] function is executed before running a command.
/// - [onAnalyticsEvent] function is used to track events.
/// - [wrapTextColumn] is the column width for wrapping text in the command line interface.
BetterCommandRunner(
super.executableName,
super.description, {
PassMessage? logError,
PassMessage? logInfo,
MessageOutput? messageOutput,
SetLogLevel? setLogLevel,
OnBeforeRunCommand? onBeforeRunCommand,
OnAnalyticsEvent? onAnalyticsEvent,
int? wrapTextColumn,
}) : _logError = logError,
_logInfo = logInfo,
_onBeforeRunCommand = onBeforeRunCommand,
}) : _messageOutput = messageOutput,
_setLogLevel = setLogLevel,
_onBeforeRunCommand = onBeforeRunCommand,
_onAnalyticsEvent = onAnalyticsEvent,
_argParser = ArgParser(usageLineLength: wrapTextColumn) {
argParser.addFlag(
Expand Down Expand Up @@ -114,15 +134,15 @@ class BetterCommandRunner extends CommandRunner {
try {
return super.parse(args);
} on UsageException catch (e) {
_messageOutput?.logUsageException(e);
_onAnalyticsEvent?.call(BetterCommandRunnerAnalyticsEvents.invalid);
_logError?.call(e.toString());
rethrow;
}
}

@override
void printUsage() {
_logInfo?.call(usage);
_messageOutput?.logUsage(usage);
}

@override
Expand Down Expand Up @@ -170,7 +190,7 @@ class BetterCommandRunner extends CommandRunner {
try {
await super.runCommand(topLevelResults);
} on UsageException catch (e) {
_logError?.call(e.toString());
_messageOutput?.logUsageException(e);
_onAnalyticsEvent?.call(BetterCommandRunnerAnalyticsEvents.invalid);
rethrow;
}
Expand Down
6 changes: 4 additions & 2 deletions test/better_command_runner/logging_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ void main() {
var runner = BetterCommandRunner(
'test',
'this is a test cli',
logError: (message) => errors.add(message),
logInfo: (message) => infos.add(message),
messageOutput: MessageOutput(
logUsageException: (e) => errors.add(e.toString()),
logUsage: (u) => infos.add(u),
),
)..addCommand(MockCommand());
tearDown(() {
errors.clear();
Expand Down
6 changes: 4 additions & 2 deletions test/better_command_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:test/test.dart';
class MockCommand extends BetterCommand {
static String commandName = 'mock-command';

MockCommand({super.logInfo}) {
MockCommand({super.passOutput}) {
argParser.addOption(
'name',
defaultsTo: 'serverpod',
Expand All @@ -26,7 +26,9 @@ void main() {
group('Given a better command registered in the better command runner', () {
var infos = <String>[];
var betterCommand = MockCommand(
logInfo: (String message) => infos.add(message),
passOutput: MessageOutput(
logUsage: (u) => infos.add(u),
),
);
var runner = BetterCommandRunner('test', 'test project')
..addCommand(betterCommand);
Expand Down