-
Notifications
You must be signed in to change notification settings - Fork 201
CLI principles
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.
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.
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.
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.
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.
Commands should deal with the user interface, options and arguments, serializing them as necessary, and calling Tasks and Service Classes to perform complex logic.
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.