Building CLI Programs in Dart

How to build simple command-line tools using Dart

Kenneth Reilly
ITNEXT

--

Introduction

In this article, we’ll look into the process of building simple command-line tools with Dart. If you’re not already familiar with Dart, it’s an excellent language with modern features that make it suitable for building high-performance software that is easy to maintain and upgrade.

The example project will demonstrate simple features of a typical CLI application, such as argument parsing and basic filesystem operations.

Getting Started

If you don’t already have a Dart environment, head over to the installation page. For a copy of the project source code, check out the GitHub repo here.

This project was created with stagehand, a great Dart package that assists with setting up Dart and Flutter projects. To install stagehand for building your own command-line (and other) applications with Dart:

$ pub global activate stagehand

Stagehand provides several options for project types, one of them being console-full (which is what was used to create this project). To create a basic starting point for a command-line application with stagehand:

$ stagehand console-full your-project-name

Application Entry Point

The main entry point for this program is bin/main.dart:

This is a really simple application so there’s not much here. In a more complex project, this is where configuration and initialization would be performed. In this example, the arguments are simply passed along to Demo.parse(args).

The Demo Class

The next file up for inspection is lib/demo.dart where the application takes the command-line arguments and determines what action to perform, or displays usage information if incorrect arguments are passed in:

Within the Demo class are a few static methods to handle a few simple tasks such as printing the local hostname in a “hello world” example, displaying the app usage information, and determine which operation to perform based on the command-line arguments passed to the application. There are packages such as args available to handle argument parsing, however for this really small project I chose to keep the package dependencies to a minimum (zero).

If a second argument is passed in after the scan command, this argument is passed to a simple filesystem scanner (which we will examine next) to perform a basic directory scan of a given path and display the results.

The Scanner Class

The last file in our project is the Scanner class located in lib/scanner.dart:

In the Scanner class, there is a static scan method which takes a path and begins traversing the directory structure located at that path. This uses a very simplified version of the Factory Method design pattern, since it employs the use of a static method to create an instance of itself internally. There are of course many design patterns that exist, this being an example of just one.

The scanner works by starting with the provided path and traversing it by retrieving a list of FileSystemEntity objects for that path, running a for loop over the items, and then either traversing the item if it’s a Directory or printing the filesize if the item is a File. The item could also be a Link (our simple example doesn’t have a case for this, but it could easily be added in).

That’s it for our basic filesystem Scanner and its operation. This utility could be expanded to perform any number of filesystem tasks (such as file search or filetype count), take additional arguments, or handle other kinds of tasks.

The super-basic filesystem scanner in operation

Conclusion

I hope you enjoyed this article about creating simple command-line tools using Dart, which is a powerful, flexible, and highly expressive language that also happens to have excellent documentation and is useful for many varied applications including HTTP services, image processors, backup tools, and various other utilities that work great within the modern development and deployment ecosystem. For example, my company has a few basic services deployed to Heroku that were developed in Dart (for more information about configuring buildpacks and deploying Dart apps on Heroku, see this article).

Thanks for reading, and good luck with your next Dart project!

Kenneth Reilly (8_bit_hacker) is CTO of LevelUP

--

--