We have seen how to create a Greeting CLI in another tutorial. Now we will extend our knowledge and create a
full-fledged CLI which will be partially clone of Mac/Unix
Creating CLI required below mentioned features:
- Input command arguments parser
- Traverse files and directory trees
- Filter files/directory based on the arguments
- Logger, better logging information
Taking arguments in
Deno is very easy. Every process has
Deno.args, which returns arguments passed to the program.
[ "param1", "param2" ]
Deno.args returns array of the string passed to the program(examples/minifind.ts).
Our CLI expects params like
help. To get the value of these parameters. We need to parse arguments. Deno has
flags module which help to parse and collect parameters. Let's add
When you run the program with a given example, You will see the output as above. Deno parse helps you to collect all the arguments.
I have used the ES6 de-structuring feature to assign default values.
Deno parse automatically tries to collect and combine params based on patterns. Any argument pass as prefixing
--, considered as arguments with value. If you don't pass value next to it. It will become boolean.
Things to be noted: If you pass an argument with the same param more then once.
parse combine them in
array. In the above example type is passed twice. That is why,
type has value
[ "f", "d" ].
_) here is like a collection of rest params. If arguments do not follow the standard
- prefix. All arguments collected in
_ as an array of data. We are extracting
dir as the directory name from rest
For more info read: https://deno.land/std/flags
Since now we have arguments parsed, let's add some logic to read the directory.
The first thing we can do, We can resolve the
directory where files need to be searched. We can use the resolve method from path module.
--allow-read permission. For the time being, I have given all permission passing flag
-A. you can read more about permissions
Deno.cwd() is used to get current running path. We had to convert
dir as a string. Since
parse can convert it to
string | number based on the input type.
Reading a directory can be done using
Deno.readDir. But we are traversing the entire tree of directories and files. Writing the traverse method can be tricky. You can try by yourself.
Here, I will take the help of
walk function from https://deno.land/std/fs/mod.ts.
walk function is not a stable function. We have to use
--unstable flag while running the example.
Walk function returns an async generator of
entries. Each entries have
path along with other flags like
Nice: The toughest part has been done. Now we can read entire directories along with files in it.
Walk function accepts
WalkOptions as the second argument. We can use this option to add our logic.
The default type would include both
dir ["f","d"] . Users can pass flag -
--type=d to override behavior.
Run- Dirs only:
Run- Files only:
WalkOptions supports regexp to include and exclude patterns. We can use this to filter entries by name.
Run- Get all file name has logger in it:
Now we have working
The last missing piece is to tell your user about your CLI. For that, we have add helping messages for users. I am using
logger-util created by me. You can read more herehttps://deno.land/x/deno_util.
Run with help:
Run with other options:
TaDa! 👏👏 Now you know how to create a CLI.
Now we have working
minifind CLI. However, we had to use
deno run and
filename to run the command, which is not intended/feasible. Deno provides
install command. We can convert any program to an
Let's convert our minifind to
executable. It is very simple.
Once you run above command you will see output like:
If you see that, Just add
export PATH="/Users/xdeepakv/.deno/bin:$PATH" this line to you
.bash_profile(Depending upon your OS type). Once you add
.deno/bin in PATH. Open a new terminal and try below mention command.
Now your minifind is ready to use product. :-)
I hope you like this tutorial. let me know your feedback in the comment. Please support(🙏🙏) by subscribing and clapping on https://deepak-v.medium.com/.
All working examples can be found in my Github: https://github.com/deepakshrma/deno-by-example/tree/master/examples