Недавно я создал порт на языке Go для инструмента cli jo.
Команда jo - это инструмент для простого создания JSON. Он может быть вложенным и использоваться для тела запроса команды curl. На самом деле я помню день, когда он был опубликован, и удивился, почему никому не пришла в голову эта идея раньше. Я заглянул в код и отправил несколько небольших запросов на включение, но почему-то не использовал их несколько лет. Я хотел бы выразить уважение к оригинальному инструменту jo и идее автора, за то, что он стал доступным для различных операционных систем.
Недавно заинтересовался портированием полезных cli-инструментов на язык Go. Я думаю, что в наши дни язык - лучший выбор для создания инструментов cli. Популярность по-прежнему быстро растет, поэтому мы можем ожидать, что многие разработчики установят с нуля и внесут свой вклад в сообщество OSS (честно говоря, я люблю Rust за его безопасность памяти и особенности. Но трудно ожидать такого большого количества разработчиков. Я выбираю Rust или Haskell, если язык подходит для достижения того, что я хочу).
$ gojo foo=bar qux=quux {"foo":"bar","qux":"quux"} $ gojo -p foo=bar qux=quux { "foo": "bar", "qux": "quux" } $ gojo -a foo bar baz ["foo","bar","baz"] $ seq 10 | gojo -a [1,2,3,4,5,6,7,8,9,10] $ gojo -p foo=$(gojo bar=$(gojo baz=100)) { "foo": { "bar": { "baz": 100 } } } $ gojo -p res[foo][][id]=10 res[foo][][id]=20 res[cnt]=2 { "res": { "foo": [ { "id": 10 }, { "id": 20 } ], "cnt": 2 } }
Я реализовал gojo, используя тестовые примеры jo в качестве справки. Особенно мне понравилось реализовывать глубоко вложенные ключи с помощью рекурсий. Другой язык ведет к другой красивой структуре кода, поэтому всегда интересно реализовать хорошо известный инструмент на другом языке.
В исходном инструменте jo есть много опций, позволяющих изменить поведение при угадывании типов. Я еще не реализовал многие из них, потому что до сих пор не понимаю, что для этого инструмента требуется так много опций. Мне не понравился синтаксис чтения содержимого файлов; jo [email protected]
, потому что это может противоречить философии UNIX. Но я наконец реализовал синтаксис в последней версии, потому что gojo [email protected]
, безусловно, легче набирать, чем gojo foo="$(<sample.txt)"
, и на самом деле трудно написать правильную соответствующую команду, когда целевой файл является двоичным файлом.
Я использую язык Go более четырех лет и создал множество небольших cli-инструментов. Я сделал много ошибок в своем опыте работы с языком Go. Непроверяемый код, инструмент cli только с основным пакетом, меньшая тестируемость из-за отсутствия макетов клиента api и т. Д.
Когда я создаю инструмент cli с помощью Go, я с самого начала создаю повторно используемый пакет в верхнем каталоге репозитория. Этот пакет не должен зависеть от флагов командной строки (т. Е. os.Args
) и потоков вывода / ввода (т. Е. os.Stdout
, os.Stderr
и os.Stdin
). При тщательном создании пакет может быть импортирован и достаточно настраиваемым для вывода в любые файлы или использования в качестве ответа HTTP-сервера. Затем я создаю каталог cli, который анализирует флаги командной строки и вводит потоки. Я определяю одну экспортируемую функцию cli.Run
, которая возвращает код выхода. Пакет cli может зависеть от os.Args
и потоков, но он по-прежнему должен быть тестируемым (тестовые флаги, потоки и код выхода), и я никогда не вызываю os.Exit
в этом пакете. Код основного пакета func main() { os.Exit(cli.Run()) }
и все.
В любом случае, создание cli-инструмента с помощью Go - это так весело. Рассмотрите возможность повторного использования, даже когда вы создаете инструмент cli. Перенос чего-либо на другой язык - хорошее упражнение на каникулах программистов. Развлекайся.