Разница между раздражающим инструментом CLI и отличным инструментом часто может быть достигнута несколькими простыми изменениями.

За эти годы я построил множество инструментов командной строки, в том числе pipx, у которого почти полмиллиона загрузок. Здесь я пытаюсь зафиксировать важные вещи в инструменте CLI, которые делают его приятным в использовании. Я пришел к принятию этих условностей и ожиданий. Без лишних слов, вот контрольный список.

Использовать библиотеку синтаксического анализа аргументов

Не пытайтесь вручную анализировать аргументы командной строки. Используйте библиотеку. Библиотеки также будут автоматически генерировать текст справки.

Правильно установите код выхода

В системах POSIX стандартный код выхода - 0 для успеха и от 1 до 255 для любого другого. Люди, вызывающие ваш инструмент, захотят написать сценарий его успеха или неудачи. Код выхода можно получить с помощью $?. Обычно я просто устанавливаю 1, но в зависимости от требований вы можете придавать особое значение другим значениям кода ошибки.

Показать текст справки с --help

Это обычное ожидание пользователей. Инструмент должен автоматически создавать текст справки.

Показать версию с --version

Это обычное соглашение. Не используйте -v, так как его можно спутать с verbose.

Разрешить необязательную многословность (и использовать регистратор)

Будь то флаг --verbose или более подробные уровни ведения журнала со все большей и большей детализацией, позволяющие пользователям получать более подробную информацию о том, что происходит. Вы НЕ должны добиваться этого, выполняя if (verbose) { print(verboseMessage) }. Вместо этого используйте регистратор и установите желаемый уровень ведения журнала. Таким образом, вы можете выполнять журналирование вызовов везде и один раз установить уровень ведения журнала. Если уровень ведения журнала показывает только ошибки, вызовы журнала не выполняются. В противном случае они что-нибудь напечатают (в stderr, конечно).

Используйте stderr и stdout намеренно. У них разные цели.

stdout предназначен для машинного анализа и показывает только выходные данные, предназначенные для вызова инструмента CLI. stderr предназначен для диагностических сообщений и регистрации. Таким образом, вы можете распечатать столько диагностической информации, сколько захотите, а вывод, который может анализировать машина, например json, по-прежнему может быть проанализирован из stdout. Потоки отличаются друг от друга и имеют разные цели. "Читать далее".

Не показывайте конечным пользователям трассировку стека. Всегда.

CLI - это абстракция поверх любого языка, на котором он написан. Единственное, что должно беспокоить пользователя, - это API, предоставляемый CLI: текст справки. Ошибки должны быть ориентированы на текст справки. Трассировка стека, показывающая ошибку, сбивает пользователя с толку. Вместо этого используйте команду try / catch и отобразите сообщение об ошибке, требующее принятия мер.

Сделайте сообщения об ошибках максимально полезными

Создавайте сообщение, думая о пользователе. Вместо того, чтобы говорить «обнаружен недопустимый символ в позиции 0», что заставляет пользователя больше работать над расшифровкой, что это означает, скажите что-нибудь вроде «Не удалось проанализировать ввод из file.txt. Подтвердите, что это действительный JSON, затем повторите попытку ». Также часто бывает полезно следить за основным сообщением об ошибке, в данном случае «Не удалось выполнить синтаксический анализ…».

Экономно используйте цвет

У пользователей могут быть разные потребности в контрасте. У некоторых пользователей фон белый, у некоторых темный, поэтому установка цвета может размыть текст. Кроме того, некоторые пользователи могут быть слабовидящими и нуждаются в специальных настройках. Использование слишком большого количества цветов в конечном итоге приводит к обратным результатам, так как инструмент выглядит слишком резким или любительским. Единственное правило, которое обычно приемлемо, - это ошибки, отмеченные красным цветом, предупреждения - желтым, и выводимые в цвете по умолчанию.

Сигнал «конец опций» с помощью -

Это немного угловой случай, но мне он понадобился несколько раз. Разделитель -- используется для обозначения чего-либо после того, как этот аргумент должен использоваться буквально, а не как флаг. Например, в

grep -- -c file.txt

означает, что в файле ищется текст -c. Без разделителя это было бы ошибкой, поскольку -c интерпретировался бы как флаг, а не аргумент. "Читать далее".

Будь как можно тише

Вы заметили, как мало вывода обычно выдается для встроенных команд, таких как ls или rm? Они переходят прямо к делу. Они не говорят «ищу файлы в каталоге ... найдено 5 файлов ... вот файлы ...». Если пользователи хотят это увидеть, они могут использовать подробные флаги.

Первоначально опубликовано на https://grassfedcode.com 25 октября 2020 г.