Executable Command Line in Dart!

Bhavan Patel
DKatalis
6 min readOct 30, 2021

--

Making Executable command line app in Dart? Surprised? Yes, we can! Let’s begin.

There might be tons of questions going on in mind. Why? How?!
Let's take it easy and build step by step.

Why we need executable Command Line App?

The answer is time! We know while developing kick-ass boost in coding will definitely save our time! And time is money! 💴

Apart from time, we will have some tools that will take care of rocket science stuff in the background that we don’t need to worry about!

How we can make executable command line app in dart?

To answer this, we will create one very simple cool command line that will help you out in real Flutter or Dart programming.

Let’s get started! These are what you are going to read next:

  • Things needed to make cli app
  • What are we going to make?
  • Step by Step making cli app

What stuff you really need to make cli app in dart?

We will require one rocket 🚀 and one human, that's it!

LOL. No!

We require only a system with Dart/Flutter installed! You can go ahead and get it here!

If not:

flutter doctor

The output should be something similar. The Main we need is No Issues Found!

flutter doctor

What are we going to make?

We are going to create a cool code helper in Flutter, which will take some arguments and generate template files for us. Like this:

cool bloc Authentication
cool screen Login --stateful
cool screen Profile --stateless

cool will be our cli and bloc | screen will be our primary arguments which will decide what to make, Authentication / Login / Profile are just name of that bloc or screen. Last argument will be for screen is stateful or stateless.

Finally, let’s start!

First, we need to create one directory, let's say, executable and create a basic structure.

mkdir executable
cd executable
dart create cool console-full

The output will be:

This dart create command will create a Dart project named cool with argument of console-full. console-full will basically create bin/cool.dart and set up your project with basic stuff needed to be executable.

Now, let’s change pubspec.yml and make the project executable.

Also, let’s change a little bit on default generated bin/cool.dart with the following.

Now make save all your work will publish it to local machine pub dart!

cd cool
dart pub global activate --source path .

The output will be similar to this:

Done! We made it publish on our local machine! Let’s try out is it working or not!

Go to another terminal window, Just hit cool !

Oh yes! It really is working! Now, let’s move to actual implementation!

First, we need to add needed packages, one called args, that will help us out with parsing raw command-line arguments into a set of options and values.
The second one is called recase, which will help us out with changing the case of the input text to the desired case convention.

dart pub add args
dart pub add recase

Now, let’s create lib directory and helper sub-directory and some empty .dart files listed like the structure below.

Next, let’s add content to all files with the given code snippets.

At bin/cool.dart replace the code with one written below

This will create parser at the first step and add two parsers, one is for screen which is screenParser another one is for bloc which is blocParser.

Now both the parsers will have their own command that needs to be added with the parser and arguments that need to be added with specific command parser.

Here, stateful & stateless arguments belong to screen command only so we need to add to screenParser only.

Once adding arguments and command to parser is done, we need to see the result, so we can pass it to the next function which will create files.

Now, let's add lib/generator.dart with the code below:

Here, let's go into details. The generate function is taking arguments as a parsed result and default generator which is the default structure where files will be created. Based on the command, whether it’s screen or bloc, it will create files.

Let's understand screen creation. The _file Model will be created based on the filename and refactor the case using reCase. Based on the file model, it will create the file using dart.io File at lib/screens and based on the third parameter --stateful or --stateless it will get the template from the template helper and create screen with refactoring filename case in Pascal case.

It’s quite similar to what we did for the bloc, but the difference is there is no third argument and it will generate state, event, bloc and exporter file. Exporter file only exports all three state, event and bloc.

Now, let’s add the missing stuffs in lib/structure.dart and lib/file.dart

Next, we are adding missing helper files, which will be PathUtils to replace existing and get path name. Template will be responsible for supporting static pre-defined templates that will be used in generator.

Once done, add the following in lib/helper/path_utils.dart and lib/helper/template.dart

We’re almost done! We have everything that we need! Now it's time to test!

Let's publish again as we have made a lot of changes! Haha!

dart pub global activate --source path .

Yeh yeh! we done! let’s test!

Go to another tab in the terminal and try out some commands!

cool screen LoginScreen
cool screen Profile_screen
cool screen settingScreen --stateless
cool screen registerScreen --stateful
cool bloc Authentication
cool bloc customer_Level

The result should be like the one below:

Generated Files will be stays like this:

Here, we can give names in any case but files will be generated as perfect!

What you can make if you take this forward?

You are now a Rocket 🚀 scientist hahaha! Now you can take it to another level, it all depends on you! Where do you want to go? Mars? Moon? Galaxy!

  • Create a cli that can bootstrap your project! Like ignite-cli. Helpful for creating a whole project based on the arguments!!
  • Also can be taken as creating custom file/code analysis cli taking a file or directory as an argument and do some analysis and give a result!
  • Ahh! Parser cli Get involve APIs will give A type data and it will generate B type data on execute! xml > json convertor!
  • And many more…

Hope you have learned something new today. Do appreciate with some claps. 👏👏. If you like what you’re reading, come join our team and meet the like-minded team behind this. Join us !

Connect with me on Medium or LinkedIn or for any help!

#staysafe

More Details on Me (Bhavan Patel)

--

--

Bhavan Patel
DKatalis
Writer for

Software Engineer at DKATALIS (Digital Katalis)