Args Riverpod
DISCLAIMER: this package is not part of the official Riverpod packages.
args package extention with Riverpod capabilities.
args_riverpod introduce following classes:
ProviderCommandRunner: provides aCommandRunnerwith a rootProviderContainer(instanciated along with runner).ProviderCommand: provides aCommandwith access to the rootProviderContainer.
Usage is the same as args package with following differences:
- Branch commands can override
processArgsfunction to handle the arguments they declare - Leaf commands can override
processArgsfunction to handle the arguments they declare and must overrideexecutefunction (which replacerunfunction) - Provider Command Runner provides a
setGlobalArgsProcessorthat enable to register a listener to handle global arguments.
Note:
runhas been replaced byexecutedue toargspackage implementation constraints.
Root Provider Container
When creating the ProviderCommandRunner, you can pass the root ProviderContainer overrides and observers.
ProviderCommandRunner("cli", "A super CLI.", overrides: [], observers: []);
Global Options Processing
ProviderCommandRunner instanciates a Riverpod ProviderContainer that is supplied to all commands/sub-commands & args processors.
This container is available as ref in processArgs and execute functions.
In order to declare a global options processor, call setGlobalArgProcessor on the ProviderCommandRunner.
void main(List<String> arguments) {
ProviderCommandRunner("cli", "A super CLI.")
..setGlobalArgProcessor(GlobalOptionParser())
..addCommand(BranchCommand())
..argParser.addOption('host', help: 'Server host URL')
..argParser.addOption('token', help: 'Server access token')
..run(arguments);
}
class GlobalOptionParser extends ProviderArgsProcessor {
@override
Future<void> processArgs() async {
print('GlobalOptionParser.processArgs called');
ref.read(hostArgProvider.notifier).state = argResults?['host'];
ref.read(tokenArgProvider.notifier).state = argResults?['token'];
}
}
Branch Command Options Processing
A command with subcommands is known as a "branch command" and cannot be executed itself.
It should call addSubcommand (often from the constructor) to register subcommands.
A branch command can override processArgs to process its related arguments.
class BranchCommand extends ProviderCommand {
@override
final name = "branch";
@override
final description = "branch command";
BranchCommand() {
argParser.addOption('input', help: 'input file path');
addSubcommand(LeafCommand());
}
@override
void processArgs() {
print('BranchCommand.processArgs called');
ref.read(inputArgProvider.notifier).state = argResults?['input'];
}
}
Leaf Command Options Processing
A command is known as a "leaf command" if it has no subcommands and is meant to be run.
Leaf commands must override execute and can override processArgs.
class LeafCommand extends ProviderCommand {
@override
final name = "leaf";
@override
final description = "leaf command";
LeafCommand() {
argParser.addOption('output', help: 'output file path');
}
@override
void processArgs() {
print('LeafCommand.processArgs called');
ref.read(ouputArgProvider.notifier).state = argResults?['output'];
}
@override
void execute() {
print('LeafCommand.execute called');
ref.read(fooServiceProvider).doSomething();
}
}
Complete Usage Example
Full usage example is available here.
You can run it as follow:
git clone git@gitlab.com:noan-public/dart-and-flutter/args_riverpod.git && cd args_riverpod
dart "$PWD/args_riverpod/example/args_riverpod_example.dart" --host server.com --token my_token branch --input path/in-file.txt leaf --output path/out-file.txt
Libraries
- args_riverpod
- Support for doing something awesome.