You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I propose that we refactor our admin tools into something that looks as follows:
/// Exception thrown when the invocation of an [AdminAction] fails.@sealedclassAdminActionFailedExceptionimplementsException {
finalString message;
AdminActionFailedException(this.message);
@overrideStringtoString() => message;
}
@sealedclassAdminAction {
/// Name of the action is an identifier to be specified when the action is triggered.finalString name;
/// Map from option name to description of the option.finalMap<String,String> options;
/// A one-liner summary of what this action does.finalString summary;
/// A multi-line explanation of what this action does, written in markdown. /// /// This **must** explain what the action does? What the implications are? /// What other actions could be useful to use in conjunction. /// What are reasonable expectations around cache-time outs, etc. /// /// Do write detailed documentation and include examples.finalString description;
/// Function to be called to invoke the action. /// /// This function is passed an [arguments] Map where keys match the keys in [options]. /// Returns a JSON response, a failed invocation should throw [AdminActionFailedException], or /// a [ResponseException]. /// Any other exception will be considered an internal error.finalFuture<Map<String, dynamic>>Function(Map<String,String> arguments) invoke;
AdminAction({
requiredthis.name,
requiredthis.summary,
requiredthis.description,
this.options =const<String,String>{},
requiredthis.invoke
}} {
// Check that name works as a command-line argumentif (!RegExp(r'^[a-z][a-z0-9-]{0,128}$').hasMatch(name)) {
throwArgumentError.value(name, 'name');
}
// Check that the keys for options works as command-line optionsif (options.keys.any((k) =>!RegExp(r'^[a-z][a-z0-9-]{0,128}$').hasMatch(k))) {
throwArgumentError.value(options, 'options');
}
}
}
final _adminHelpAction =AdminAction(
name:'help',
summary:'Display help message',
description:'''Display help messages for a given action.**Example** `help --action=help` will show the help message for this action.''',
options: {
'action':'Action for which the help message should be displayed',
},
invoke: (arguments) async {
final actionName = arguments['action'] ??'';
final action = _registeredAdminActions.firstWhere((a) => a.name == actionName, orElse: () =>null);
if (action ==null) {
throwAdminActionFailedException('unknown action: "$actionName"');
}
return {
'name': action.name,
'summary': action.summary,
'description': action.description,
'options': action.options,
};
},
);
final _adminListAction =AdminAction(
name:'list',
summary:'List available actions',
description:'''Display a list of available admin actions.**Example** `list` will show a list of actions.''',
invoke: (arguments) async {
return {
'actions': {
for (final action in _registeredAdminActions)
action.name: action.summary,
},
};
},
);
final _registeredAdminActions = [
_adminHelpAction,
_adminListAction,
];
On the CLI client side, we'll have to print the output JSON as pretty-printed YAML -- this will only be nice if we can make format YAML in the output using wrapAsCustomStyledYamlNode as proposed in dart-lang/yaml_edit#26
The text was updated successfully, but these errors were encountered:
I propose that we refactor our admin tools into something that looks as follows:
On the CLI client side, we'll have to print the output JSON as pretty-printed YAML -- this will only be nice if we can make format YAML in the output using
wrapAsCustomStyledYamlNode
as proposed in dart-lang/yaml_edit#26The text was updated successfully, but these errors were encountered: