Home Explore Blog CI



nix

5th chunk of `doc/manual/source/development/cli-guideline.md`
ad8171da3fdba9374ab0ab2e9d0fc5bca6deec5556bf10450000000100000fb5
But users won't stay beginners for long and what was once useful might quickly
become annoying. There is no golden rule that we can give in this guideline
that would make it easier how to draw a line and find best compromise.

What we would encourage is to **build prototypes**, do some **user testing**
and collect **feedback**. Then repeat the cycle few times.

First design the *happy path* and only after your iron it out, continue to work
on **edge cases** (handling and displaying errors, changes of the output by
certain `OPTIONS`, etc…)

## Follow best practices

Needless to say we Nix must be a good citizen and follow best practices in
command line.

In short: **STDOUT is for output, STDERR is for (human) messaging.**

STDOUT and STDERR provide a way for you to output messages to the user while
also allowing them to redirect content to a file. For example:

```shell
$ nix build > build.txt
------------------------------------------------------------------------
  Error! Attribute `bin` missing at (1:94) from string.
------------------------------------------------------------------------

  1| with import <nixpkgs> { }; (pkgs.runCommandCC or pkgs.runCommand) "shell" { buildInputs = [ (surge.bin) ]; } ""
```

Because this warning is on STDERR, it doesn’t end up in the file.

But not everything on STDERR is an error though. For example, you can run `nix
build` and collect logs in a file while still seeing the progress.

```
$ nix build > build.txt
  Evaluated 1234 files in 1.2 seconds
 Downloaded python3.8-poetry 1.2.3 in 5.3 seconds
 Downloaded python3.8-requests 1.2.3 in 5.3 seconds
------------------------------------------------------------------------
      Press `v` to increase logs verbosity
         |> `?` to see other options
------------------------------------------------------------------------
      Learn something new with every build...
         |> See last logs of a build with `nix log --last` command.
------------------------------------------------------------------------
  Evaluated my-project 1.2.3 in 14.43 seconds
Downloading [12 / 200]
         |> firefox 1.2.3 [#########>       ] 10Mb/s | 2min left
   Building [2 / 20]
         |> glibc 1.2.3 -> buildPhase: <last log line>
------------------------------------------------------------------------
```

## Errors (WIP)

**TODO**: Once we have implementation for the *happy path* then we will think
how to present errors.

## Not only for humans

Terse, machine-readable output formats can also be useful but shouldn’t get in
the way of making beautiful CLI output. When needed, commands should offer a
`--json` flag to allow users to easily parse and script the CLI.

When TTY is not detected on STDOUT we should remove all design elements (no
colors, no emojis and using ASCII instead of Unicode symbols). The same should
happen when TTY is not detected on STDERR. We should not display progress /
status section, but only print warnings and errors.

## Dialog with the user

CLIs don't always make it clear when an action has taken place. For every
action a user performs, your CLI should provide an equal and appropriate
reaction, clearly highlighting the what just happened. For example:

```shell
$ nix build
 Downloaded python3.8-poetry 1.2.3 in 5.3 seconds
 Downloaded python3.8-requests 1.2.3 in 5.3 seconds
...
   Success! You have successfully built my-project.
$
```

Above command clearly states that command successfully completed. And in case
of `nix build`, which is a command that might take some time to complete, it is
equally important to also show that a command started.

## Text alignment

Text alignment is the number one design element that will present all of the
Nix commands as a family and not as separate tools glued together.

The format we should follow is:

```shell
$ nix COMMAND
   VERB_1 NOUN and other words
  VERB__1 NOUN and other words
       |> Some details
```

Few rules that we can extract from above example:

- Each line should start at least with one space.

Title: CLI Output and Error Handling, Machine-Readable Formats, and User Interaction
Summary
This section discusses strategies for crafting effective CLI output, including balancing user experience for beginners and advanced users through prototyping and feedback. It emphasizes adhering to best practices, using STDOUT for output and STDERR for human-readable messages, and providing machine-readable output formats like JSON when needed. The guideline also covers adjusting output based on TTY detection, ensuring clear communication of actions, and maintaining consistent text alignment across Nix commands to present a unified user interface.