Contents
Outline
When you develop the app with Flutter
, sometimes you need to do something with command(CLI - Command Line Interface). For example, you can update the version
of pubspec.yaml
file directly, but you can also make it update with the following command.
dart run bull:pub_version --version 2.5.7
In this blog post, I will introduce how to create command(CLI) tool with Dart
.
Create package project
You need to create a Dart
package project to create a command tool with Dart
and publish it to pub.dev
. If you don’t need to publish it to pub.dev
, you can create a command tool in the existing project, so you can skip this part.
Then, execute the following command to create a Dart
package.
# dart create --template=package [PACKAGE_NAME]
dart create --template=package cli_example
After creating the project, you can see the following folders and files.
cli_example
├── CHANGELOG.md
├── README.md
├── analysis_options.yaml
├── example
│ └── cli_example_example.dart
├── lib
│ ├── cli_example.dart
│ └── src
│ └── cli_example_base.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── cli_example_test.dart
Install args package
The args
package helps you create commands(CLI) with Dart
.
Execute the following command to install the args
package.
dart pub add args
If you are using Flutter
project, execute the following command to install the args
package.
flutter pub add args
Implement command
In order to create a command(CLI) with Dart
, you need to use the Command
class of the args
package. Open the lib/src/cli_example_base.dart
file and modify it as follows.
import 'package:args/command_runner.dart';
class Echo extends Command {
@override
final name = 'echo';
@override
final description = 'Echo option';
Echo() {
argParser.addOption('message', help: 'A message to echo');
}
@override
void run() {
String? message = argResults?['message'];
// ignore: avoid_print
print('Message: $message');
}
}
When you inherit the Command
class, you need to override three members. name
is the name of the command, and description
is the description of the command. And the run()
function is the part that implements the command.
In the Command
class, you can use the argParse
and argResults
variables by default. In the constructor(Echo()
), the option, which is needed for the command, is added in the constructor by using addOption
of the argParser
.
And in the run()
function which is the implementation part of the command, the value set in the option of the command is assigned through argResults?['message']
, and the content is printed using print
.
When implementing the command in real, you will add various options to the argParser
, and implement various functions according to the options in the run()
function.
Add command
The contents implemented in the lib
folder can be only loaded and used in the Dart
file. In other words, the Echo
we’ve created cannot be used as a command yet, and can only be used in *.dart
files.
In order to use the Echo
command we created as a command not the *.dart
file, we need to create a bin
folder and create a file that runs the Echo
command.
Then, create the bin/cli_example.dart
file and modify it as follows.
import 'package:args/command_runner.dart';
import 'package:cli_example/cli_example.dart';
void main(List<String> arguments) {
CommandRunner(
"cli_example",
"Dart CLI example",
)
..addCommand(Echo())
..run(arguments);
}
When the user executes the command, the main
function is executed and the arguments
contains the options and values entered by the user.
In this file, we use the args
package to register(addCommand
) the Echo
command we created and execute(run
) it with the value (arguments
) entered by the user.
This file can be executed with the following command.
dart run cli_example echo --message="test"
And then, you can get the following result.
Message: test
We’ve created the command with the Command
class of the args
package, you can use the following command.
dart run cli_example -h
And then, you can see the description
and help
message that we’ve written above.
Dart CLI example
Usage: cli_example <command> [arguments]
Global options:
-h, --help Print this usage information.
Available commands:
echo Echo option
Run "cli_example help <command>" for more information about a command.
Of course, you can also print the help
message for the Echo
command as follows.
dart run cli_example echo -h
And then, you can see the following result.
Echo option
Usage: cli_example echo [arguments]
-h, --help Print this usage information.
--message A message to echo
Create example
In order to publish the command package we created to pub.dev
, we need to create an example that uses the Echo
command. Open the example/cli_example_example.dart
file and modify it as follows.
import 'package:args/command_runner.dart';
import 'package:cli_example/cli_example.dart';
void main() async {
final cmd = CommandRunner(
"cli_example",
"Dart CLI example",
)..addCommand(Echo());
await cmd.run(['echo', '--message', 'test message']);
}
Actually, we don’t need to create an example because we’re creating a command tool. On the contrary, this file can confuse users, so I recommend removing it.
Write test code
In order to check if the command you created works well when we execute the command, you need to write the test code. Create the test/cli_example_test.dart
file and modify it as follows.
import 'package:args/command_runner.dart';
import 'package:cli_example/cli_example.dart';
import 'package:run_with_print/run_with_print.dart';
import 'package:test/test.dart';
void main() {
final runner = CommandRunner('test', 'test')..addCommand(Echo());
test('Echo test message', () async {
await runWithPrint((logs) async {
await runner.run(['echo', '--message', 'test message']);
expect(logs, ['Message: test message']);
});
});
}
The Echo
command uses the print
function to print the result. To check this, you can install the run_with_print
package by running the following command.
dart pub add --dev run_with_print
After installing, you can check the output with print
through the runWithPrint
function of the run_with_print
package. For more information about the run_with_print
package, please refer to the following link.
Now, execute the following command to run the test code.
dart test test/cli_example_test.dart
Then, you can see the following result.
00:00 +1: All tests passed!
Test command
Now, let’s check if the command we created works well. First, upload the code that implements the command to GitHub
. And then, run the following command to activate the command.
dart pub global activate --source git https://github.com/dev-yakuza/cli_example
And then, you can run the command as follows.
dart pub global run cli_example echo --message="test messsage"
Then, you can see the following result.
Message: test messsage
Build
The command can be built as a standalone executable. Run the following command to build the command as a standalone executable.
dart compile exe bin/cli_example.dart
Then, you can see the cli_example.exe
file created in the bin
folder. You can run the command file as follows.
./bin/cli_example.exe echo --message="test message"
The command file has the exe
extension, but this command file supports not only Windows
but also macOS
and Linux
.
Publish pub.dev
You can publish the command package you created to pub.dev
and use it. For more information on publishing packages to pub.dev
, please refer to the following link.
Official document references
The following is the official document that helps you create commands with Dart
.
Get started: Command-line and server apps
: https://dart.dev/tutorials/server/get-startedWrite command-line apps
: https://dart.dev/tutorials/server/cmdlineargs package
: https://pub.dev/documentation/args/latest/index.html
Completed
Done! We’ve seen how to create a command tool using Dart
. When developing an app with Flutter
or developing a project with Dart
, sometimes you need to create a specific command. In this case, please refer to this post to create a command tool.
Was my blog helpful? Please leave a comment at the bottom. it will be a great help to me!
App promotion
Deku
.Deku
created the applications with Flutter.If you have interested, please try to download them for free.