Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

CLI principles

Luke Andrews edited this page May 6, 2020 · 3 revisions

Speed

The CLI should execute quickly, getting things done and returning to the prompt as soon as possible. In dealing with other languages and external services we may incur unavoidable latency, but the core execution and boot of the CLI should remain instantaneous.

  • Try to avoid loading large amounts of files. Technical design principals differ in the CLI from web development. Not every class, error or constant needs their own file. You can define multiple classes in a single file if they are all used locally. This will help keep our speed up.
  • Whenever you are doing a process that you know will take a long time, let the user know.
  • almost never use require. autoload all of your classes.

No dependencies

Because ruby objects are loaded into memory, the fewer runtime dependencies we require the better. We have only two dependencies: cli-kit and cli-ui. They are vendored in the codebase to avoid using bundler or sourcing gems, which can add latency.

Don’t require escalated privileges

If possible don’t sudo or require passwords for any task. Most open-source tools avoid using escalated privileges. If they do, it’s usually left to the user to execute as a part of a specific action (sudo make install, for example). Adhering to this principle enforces trust, as developers are hesitant to use a tool that could do anything on their machine.

Don’t call home without user’s permission

Similar to the previous point, developers are resistant to use developer tools that make network requests without their consent. We have implemented opt-in anonymized usage reporting so we can track the CLI’s most-used features and improve its stability and reliability.

Don’t delete stuff

Any operation executed by the tool should be non-destructive. Leave it up to the user to remove things created by the tool if they wish.

Separation of concerns

Commands should deal with the user interface, options and arguments, serializing them as necessary, and calling Tasks and Service Classes to perform complex logic.

Separation of CLI and project functionality

When interacting with your project, the CLI should call functionality in libraries on your project. For instance most of the actions on a rails project call rails generator commands. This is so that you can update what those generators do but keep the interface consistent. Also, your users can have a specific version of your dependency and the CLI can operate across different versions, maintaining compatibility.

Clone this wiki locally