Command Line Interface Challenge

Time: 1 week
Difficulty: Easy
Code Qualtiy Score: 10 points

As a developer, you will have a lot of tasks to do. So, it is important to track them in order to not forget anything. In this challenge, you will implement a simple TODO app. This app will be a CLI (Command Line Interface) app, so you will not need to implement a GUI (Graphical User Interface). Also, you will not need to know anything about databases and SQL, because you will use a simple text file to store the TODOs.

1. Introduction

A cli command is nothing more than a program that you can run from your terminal or shell. Each cli command is an executable file located in your PATH. When you run a command, your shell will search for the executable file in your PATH and if it finds it, it will run it. So, you need to put your executable file in your PATH in order to run it from anywhere. You can check your PATH by using echo $PATH command. It is a list of directories separated by :. You can put your executable file in one of these directories.

Let’s look at how ls command works. When you write ls in your terminal, it will try to find an executable file named ls in your PATH. It will check each directory in your PATH one by one. If it finds it in the first directory, it will run it directly. If it does not find it in the first directory, it will check the second directory and so on. If it does not find it in any of these directories, it will give an error. You can check where ls command is located by using which ls command. It will give you the path of the executable file. Also, terminal will check the file permissions. If the file is not executable, it will give an error.

There are two types of executable files. The first one is a binary ELF file. The second one is a script file. A script file is a text file that contains shebang at the beginning of the file. Shebang is a special comment that starts with #!. It tells the shell which program to use to run the script. For instance, if you write #!/bin/bash at the beginning of your script file, shell will use bash to run your script. If you write #!/usr/bin/env node, terminal will run env command with node as the first argument. And as a second argument, it will give your script file’s path. So, env command will run node with your script file’s path as the first argument. Please use shebang at the beginning of your script file. Otherwise, your script will not run.

Please try to use functional programming approaches such as map, filter, reduce etc. Also, please try to use mutable variables (var and let) as less as possible. Also do not mutate process.env.

In addition these, try to use modern javascript feature such as for (const x of xs).

Using Git

In order to track your changes, you will need to use a version control system. In this challenge, you will use git as your version control system. There are some rules that you need to follow. If you don’t follow them.

First of all, cour commits should describe what you did but it should not consists of only changes. For instance README file updated or x file changed messages are not good commit messages. Instead, you can use Added a new section about x for README file updated or Added a new function to do y for x file changed. Therefore, it should give an idea about what you did. It is not needed to list all crud operations that you did because they are already listed in the commit itself.

Also please be consistent between your commit messages. For instance, if you use imperative mood for your commit messages, you should use it for all of your commit messages. If you use past tense, you should use it for all of your commit messages. Also syntacticly they should be consistent. For instance, you can start with a big letter and you can put a dot at the end of the message. But you should be consistent between your commit messages.

It is very important to keep git history clean. You should not commit files that are not related to your project. For instance, you should not commit your node_modules folder, IDE files, temporary files etc. You should only commit files that are related to your project. Also, git stores your history. So, you should not grow your git repository size by committing unnecessary files. PLease be careful about binary files. Git is not good at storing binary files. So, you should not commit binary files (If you really need them, then you can). But please be careful about them.

Another thing is using .gitignore file to ignore files that you don’t want to track. For instance, you don’t need to track node_modules folder. You can ignore it by adding node_modules to .gitignore file. However, instead of writing it manually, you can use gitignore.io to generate .gitignore file for your project.

Using VSCode

You can use VSCode as your IDE. It is a good IDE for Javascript and Node.js development. Vscode has a lot of plugins that you can use. For instance, you can use Prettier plugin to format your code. You can use ESLint plugin to check your code quality. You can use GitLens plugin to see git history. However, please note that, it has a great feature that you can use. You can use .vscode folder in order to store your project specific settings.

2. Requirements

There are some rules that you need to follow. If you don’t follow them, you will get 0 points.

  1. No external libraries and no project scaffolding tools.
  2. You need to use git as version control system.
  3. You need to use a single file to store the TODOs. Each line will be a TODO and each of them should be a JSON string.

Each TODO will have an associated assigned user (assignee). This will be stored as plain string. For instance a TODO will look like this:

{
  "id": 1,
  "title": "A sample task description",
  "assignee": "John Doe",
  "done": false
}

Assignee will be read from an environment variable. You will use process.env to read environment variables. You will use TODO_USERNAME as the environment variable name. If this variable is not set, you will use Unknown as the assignee.

3. Features

For your TODO app you need to implement the following features. You will get 0 points if one of them is not implemented.

  1. Add a task: mytodo add "A sample task description"
  2. List all tasks: mytodo list also mytodo
  3. Mark a task as done: mytodo done 1
  4. Mark a task as undone: mytodo undone 1
  5. List all done tasks: mytodo list --done
  6. List all undone tasks: mytodo list --undone
  7. Delete a task: mytodo delete 1
  8. Update a task: mytodo update 1 "A new task description"

4. Score

You will get a score for code quality.

  1. [5 pts] Easy to read code (Good comments, small functions, no over abstraction etc.).
  2. [1 pts] Naming conventions (please use camelCase for variables and functions)
  3. [1 pts] Good usage of git commits and messages.
  4. [2 pts] Prettier code formatting.
  5. [1 pts] Good usage of package.json.

5. Objectives

It is expected to learn these topics (or getting familiar with):

  • Basic Javascript knowledge
  • Basic Node.js knowledge
  • File system operations
  • Standard input and output operations
  • Developing a simple CLI app (Getting cli arguments and environment variables)
  • Using git as version control system
  • A shell (bash, zsh etc.)
  • An IDE (vim, emacs, vscode etc.)
  • JSON format
  • Basics of package.json (use bin field)